| 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 | |