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