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 /// Analyze \p InputUnitEntryPair's ODR attributes and put names
76 /// of the referenced type dies to the built name.
77 Error addReferencedODRDies(UnitEntryPairTy InputUnitEntryPair,
78 bool AssignNameToTypeDescriptor,
79 ArrayRef<dwarf::Attribute> ODRAttrs);
80
81 /// Add names of parent dies to the built name.
82 Error addParentName(UnitEntryPairTy &InputUnitEntryPair);
83
84 /// \returns synthetic name of the specified \p DieEntry.
85 /// The name is constructed from the dwarf::DW_AT_decl_file
86 /// and dwarf::DW_AT_decl_line attributes.
87 void addDieNameFromDeclFileAndDeclLine(UnitEntryPairTy &InputUnitEntryPair,
88 bool &HasDeclFileName);
89
90 /// Add type prefix to the built name.
91 void addTypePrefix(CompileUnit &CU, const DWARFDebugInfoEntry *DieEntry);
92
93 /// Add type name to the built name.
94 Error addTypeName(UnitEntryPairTy InputUnitEntryPair, bool AddParentNames);
95
96 /// Analyze \p InputUnitEntryPair for the type name and possibly assign
97 /// built type name to the DIE's type info.
98 /// NOTE: while analyzing types we may create different kind of names
99 /// for the same type depending on whether the type is part of another type.
100 /// f.e. DW_TAG_formal_parameter would receive "{02}01" name when
101 /// examined alone. Or "{0}int" name when it is a part of a function name:
102 /// {a}void foo({0}int). The \p AssignNameToTypeDescriptor tells whether
103 /// the type name is part of another type name and then should not be assigned
104 /// to DIE type descriptor.
105 Error addDIETypeName(UnitEntryPairTy InputUnitEntryPair,
106 std::optional<std::pair<size_t, size_t>> ChildIndex,
107 bool AssignNameToTypeDescriptor);
108
109 /// Add ordered name to the built name.
110 void addOrderedName(std::pair<size_t, size_t> ChildIdx);
111
112 /// Add value name to the built name.
113 void addValueName(UnitEntryPairTy InputUnitEntryPair, dwarf::Attribute Attr);
114
115 /// Buffer keeping bult name.
116 SmallString<1000> SyntheticName;
117
118 /// Recursion counter
119 size_t RecursionDepth = 0;
120
121 /// Type pool
122 TypePool &TypePoolRef;
123};
124
125/// This class helps to assign indexes for DIE children.
126/// Indexes are used to create type name for children which
127/// should be presented in the original order(function parameters,
128/// array dimensions, enumeration members, class/structure members).
129class OrderedChildrenIndexAssigner {
130public:
131 OrderedChildrenIndexAssigner(CompileUnit &CU,
132 const DWARFDebugInfoEntry *DieEntry);
133
134 /// Returns index of the specified child and width of hexadecimal
135 /// representation.
136 std::optional<std::pair<size_t, size_t>>
137 getChildIndex(CompileUnit &CU, const DWARFDebugInfoEntry *ChildDieEntry);
138
139protected:
140 using OrderedChildrenIndexesArrayTy = std::array<size_t, 8>;
141
142 std::optional<size_t> tagToArrayIndex(CompileUnit &CU,
143 const DWARFDebugInfoEntry *DieEntry);
144
145 bool NeedCountChildren = false;
146 OrderedChildrenIndexesArrayTy OrderedChildIdxs = {0};
147 OrderedChildrenIndexesArrayTy ChildIndexesWidth = {0};
148};
149
150} // end of namespace parallel
151} // end of namespace dwarf_linker
152} // end of namespace llvm
153
154#endif // LLVM_LIB_DWARFLINKER_PARALLEL_SYNTHETICTYPENAMEBUILDER_H
155