xref: /llvm-project/llvm/lib/DWARFLinker/Parallel/SyntheticTypeNameBuilder.h (revision 2357e899cb11e05312c54b689ebd0355487be6bc)
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:
SyntheticTypeNameBuilder(TypePool & TypePoolRef)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