1 | //===- SyntheticTypeNameBuilder.h -------------------------------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===/ |
8 | |
9 | #ifndef LLVM_LIB_DWARFLINKER_PARALLEL_SYNTHETICTYPENAMEBUILDER_H |
10 | #define LLVM_LIB_DWARFLINKER_PARALLEL_SYNTHETICTYPENAMEBUILDER_H |
11 | |
12 | #include "DWARFLinkerCompileUnit.h" |
13 | #include "DWARFLinkerGlobalData.h" |
14 | #include "llvm/ADT/SmallString.h" |
15 | #include "llvm/ADT/SmallVector.h" |
16 | |
17 | namespace llvm { |
18 | class DWARFDebugInfoEntry; |
19 | |
20 | namespace dwarf_linker { |
21 | namespace parallel { |
22 | struct LinkContext; |
23 | class TypeTableUnit; |
24 | class CompileUnit; |
25 | |
26 | /// The helper class to build type name based on DIE properties. |
27 | /// It builds synthetic name based on explicit attributes: DW_AT_name, |
28 | /// DW_AT_linkage_name or based on implicit attributes(DW_AT_decl*). |
29 | /// Names for specific DIEs(like subprograms, template classes...) include |
30 | /// additional attributes: subprogram parameters, template parameters, |
31 | /// array ranges. Examples of built name: |
32 | /// |
33 | /// class A { } : {8}A |
34 | /// |
35 | /// namspace llvm { class A { } } : {1}llvm{8}A |
36 | /// |
37 | /// template <int> structure B { } : {F}B<{0}int> |
38 | /// |
39 | /// void foo ( int p1, float p3 ) : {a}void foo({0}int, {0}int) |
40 | /// |
41 | /// int *ptr; : {c}ptr {0}int |
42 | /// |
43 | /// int var; : {d}var |
44 | /// |
45 | /// These names is used to refer DIEs describing types. |
46 | class SyntheticTypeNameBuilder { |
47 | public: |
48 | SyntheticTypeNameBuilder(TypePool &TypePoolRef) : TypePoolRef(TypePoolRef) {} |
49 | |
50 | /// Create synthetic name for the specified DIE \p InputUnitEntryPair |
51 | /// and assign created name to the DIE type info. \p ChildIndex is used |
52 | /// to create name for ordered DIEs(function arguments f.e.). |
53 | Error assignName(UnitEntryPairTy InputUnitEntryPair, |
54 | std::optional<std::pair<size_t, size_t>> ChildIndex); |
55 | |
56 | protected: |
57 | /// Add array type dimension. |
58 | void addArrayDimension(UnitEntryPairTy InputUnitEntryPair); |
59 | |
60 | /// Add signature( entry type plus type of parameters plus type of template |
61 | /// parameters(if \p addTemplateParameters is true). |
62 | Error addSignature(UnitEntryPairTy InputUnitEntryPair, |
63 | bool addTemplateParameters); |
64 | |
65 | /// Add specified \p FunctionParameters to the built name. |
66 | Error addParamNames( |
67 | CompileUnit &CU, |
68 | SmallVector<const DWARFDebugInfoEntry *, 20> &FunctionParameters); |
69 | |
70 | /// Add specified \p TemplateParameters to the built name. |
71 | Error addTemplateParamNames( |
72 | CompileUnit &CU, |
73 | SmallVector<const DWARFDebugInfoEntry *, 10> &TemplateParameters); |
74 | |
75 | /// Add ordered name to the built name. |
76 | void addOrderedName(CompileUnit &CU, const DWARFDebugInfoEntry *DieEntry); |
77 | |
78 | /// Analyze \p InputUnitEntryPair's ODR attributes and put names |
79 | /// of the referenced type dies to the built name. |
80 | Error addReferencedODRDies(UnitEntryPairTy InputUnitEntryPair, |
81 | bool AssignNameToTypeDescriptor, |
82 | ArrayRef<dwarf::Attribute> ODRAttrs); |
83 | |
84 | /// Add names of parent dies to the built name. |
85 | Error addParentName(UnitEntryPairTy &InputUnitEntryPair); |
86 | |
87 | /// \returns synthetic name of the specified \p DieEntry. |
88 | /// The name is constructed from the dwarf::DW_AT_decl_file |
89 | /// and dwarf::DW_AT_decl_line attributes. |
90 | void addDieNameFromDeclFileAndDeclLine(UnitEntryPairTy &InputUnitEntryPair, |
91 | bool &HasDeclFileName); |
92 | |
93 | /// Add type prefix to the built name. |
94 | void addTypePrefix(const DWARFDebugInfoEntry *DieEntry); |
95 | |
96 | /// Add type name to the built name. |
97 | Error addTypeName(UnitEntryPairTy InputUnitEntryPair, bool AddParentNames); |
98 | |
99 | /// Analyze \p InputUnitEntryPair for the type name and possibly assign |
100 | /// built type name to the DIE's type info. |
101 | /// NOTE: while analyzing types we may create different kind of names |
102 | /// for the same type depending on whether the type is part of another type. |
103 | /// f.e. DW_TAG_formal_parameter would receive "{02}01" name when |
104 | /// examined alone. Or "{0}int" name when it is a part of a function name: |
105 | /// {a}void foo({0}int). The \p AssignNameToTypeDescriptor tells whether |
106 | /// the type name is part of another type name and then should not be assigned |
107 | /// to DIE type descriptor. |
108 | Error addDIETypeName(UnitEntryPairTy InputUnitEntryPair, |
109 | std::optional<std::pair<size_t, size_t>> ChildIndex, |
110 | bool AssignNameToTypeDescriptor); |
111 | |
112 | /// Add ordered name to the built name. |
113 | void addOrderedName(std::pair<size_t, size_t> ChildIdx); |
114 | |
115 | /// Add value name to the built name. |
116 | void addValueName(UnitEntryPairTy InputUnitEntryPair, dwarf::Attribute Attr); |
117 | |
118 | /// Buffer keeping bult name. |
119 | SmallString<1000> SyntheticName; |
120 | |
121 | /// Recursion counter |
122 | size_t RecursionDepth = 0; |
123 | |
124 | /// Type pool |
125 | TypePool &TypePoolRef; |
126 | }; |
127 | |
128 | /// This class helps to assign indexes for DIE children. |
129 | /// Indexes are used to create type name for children which |
130 | /// should be presented in the original order(function parameters, |
131 | /// array dimensions, enumeration members, class/structure members). |
132 | class OrderedChildrenIndexAssigner { |
133 | public: |
134 | OrderedChildrenIndexAssigner(CompileUnit &CU, |
135 | const DWARFDebugInfoEntry *DieEntry); |
136 | |
137 | /// Returns index of the specified child and width of hexadecimal |
138 | /// representation. |
139 | std::optional<std::pair<size_t, size_t>> |
140 | getChildIndex(CompileUnit &CU, const DWARFDebugInfoEntry *ChildDieEntry); |
141 | |
142 | protected: |
143 | using OrderedChildrenIndexesArrayTy = std::array<size_t, 8>; |
144 | |
145 | std::optional<size_t> tagToArrayIndex(CompileUnit &CU, |
146 | const DWARFDebugInfoEntry *DieEntry); |
147 | |
148 | bool NeedCountChildren = false; |
149 | OrderedChildrenIndexesArrayTy OrderedChildIdxs = {0}; |
150 | OrderedChildrenIndexesArrayTy ChildIndexesWidth = {0}; |
151 | }; |
152 | |
153 | } // end of namespace parallel |
154 | } // end of namespace dwarf_linker |
155 | } // end of namespace llvm |
156 | |
157 | #endif // LLVM_LIB_DWARFLINKER_PARALLEL_SYNTHETICTYPENAMEBUILDER_H |
158 | |