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
17namespace llvm {
18class DWARFDebugInfoEntry;
19
20namespace dwarf_linker {
21namespace parallel {
22struct LinkContext;
23class TypeTableUnit;
24class 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.
46class SyntheticTypeNameBuilder {
47public:
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
56protected:
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).
132class OrderedChildrenIndexAssigner {
133public:
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
142protected:
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