aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/DWARFLinkerParallel/SyntheticTypeNameBuilder.h
blob: c9dce4e94fb0dc30a34d99976d11fa8dd5f9aba9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
//===- SyntheticTypeNameBuilder.h -------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===/

#ifndef LLVM_LIB_DWARFLINKERNEXT_SYNTHETICTYPENAMEBUILDER_H
#define LLVM_LIB_DWARFLINKERNEXT_SYNTHETICTYPENAMEBUILDER_H

#include "DWARFLinkerCompileUnit.h"
#include "DWARFLinkerGlobalData.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"

namespace llvm {
class DWARFDebugInfoEntry;

namespace dwarflinker_parallel {
struct LinkContext;
class TypeTableUnit;
class CompileUnit;

/// The helper class to build type name based on DIE properties.
/// It builds synthetic name based on explicit attributes: DW_AT_name,
/// DW_AT_linkage_name or based on implicit attributes(DW_AT_decl*).
/// Names for specific DIEs(like subprograms, template classes...) include
/// additional attributes: subprogram parameters, template parameters,
/// array ranges. Examples of built name:
///
/// class A {  }                    : {8}A
///
/// namspace llvm { class A {  } }  : {1}llvm{8}A
///
/// template <int> structure B { }  : {F}B<{0}int>
///
/// void foo ( int p1, float p3 )   : {a}void foo({0}int, {0}int)
///
/// int *ptr;                       : {c}ptr {0}int
///
/// int var;                        : {d}var
///
/// These names is used to refer DIEs describing types.
class SyntheticTypeNameBuilder {
public:
  SyntheticTypeNameBuilder(TypePool &TypePoolRef) : TypePoolRef(TypePoolRef) {}

  /// Create synthetic name for the specified DIE \p InputUnitEntryPair
  /// and assign created name to the DIE type info. \p ChildIndex is used
  /// to create name for ordered DIEs(function arguments f.e.).
  Error assignName(UnitEntryPairTy InputUnitEntryPair,
                   std::optional<std::pair<size_t, size_t>> ChildIndex);

protected:
  /// Add array type dimension.
  void addArrayDimension(UnitEntryPairTy InputUnitEntryPair);

  /// Add signature( entry type plus type of parameters plus type of template
  /// parameters(if \p addTemplateParameters is true).
  Error addSignature(UnitEntryPairTy InputUnitEntryPair,
                     bool addTemplateParameters);

  /// Add specified \p FunctionParameters to the built name.
  Error addParamNames(
      CompileUnit &CU,
      SmallVector<const DWARFDebugInfoEntry *, 20> &FunctionParameters);

  /// Add specified \p TemplateParameters to the built name.
  Error addTemplateParamNames(
      CompileUnit &CU,
      SmallVector<const DWARFDebugInfoEntry *, 10> &TemplateParameters);

  /// Add ordered name to the built name.
  void addOrderedName(CompileUnit &CU, const DWARFDebugInfoEntry *DieEntry);

  /// Analyze \p InputUnitEntryPair's ODR attributes and put names
  /// of the referenced type dies to the built name.
  Error addReferencedODRDies(UnitEntryPairTy InputUnitEntryPair,
                             bool AssignNameToTypeDescriptor,
                             ArrayRef<dwarf::Attribute> ODRAttrs);

  /// Add names of parent dies to the built name.
  Error addParentName(UnitEntryPairTy &InputUnitEntryPair);

  /// \returns synthetic name of the specified \p DieEntry.
  /// The name is constructed from the dwarf::DW_AT_decl_file
  /// and dwarf::DW_AT_decl_line attributes.
  void addDieNameFromDeclFileAndDeclLine(UnitEntryPairTy &InputUnitEntryPair,
                                         bool &HasDeclFileName);

  /// Add type prefix to the built name.
  void addTypePrefix(const DWARFDebugInfoEntry *DieEntry);

  /// Add type name to the built name.
  Error addTypeName(UnitEntryPairTy InputUnitEntryPair, bool AddParentNames);

  /// Analyze \p InputUnitEntryPair for the type name and possibly assign
  /// built type name to the DIE's type info.
  /// NOTE: while analyzing types we may create different kind of names
  /// for the same type depending on whether the type is part of another type.
  /// f.e. DW_TAG_formal_parameter would receive "{02}01" name when
  /// examined alone. Or "{0}int" name when it is a part of a function name:
  /// {a}void foo({0}int). The \p AssignNameToTypeDescriptor tells whether
  /// the type name is part of another type name and then should not be assigned
  /// to DIE type descriptor.
  Error addDIETypeName(UnitEntryPairTy InputUnitEntryPair,
                       std::optional<std::pair<size_t, size_t>> ChildIndex,
                       bool AssignNameToTypeDescriptor);

  /// Add ordered name to the built name.
  void addOrderedName(std::pair<size_t, size_t> ChildIdx);

  /// Add value name to the built name.
  void addValueName(UnitEntryPairTy InputUnitEntryPair, dwarf::Attribute Attr);

  /// Buffer keeping bult name.
  SmallString<1000> SyntheticName;

  /// Recursion counter
  size_t RecursionDepth = 0;

  /// Type pool
  TypePool &TypePoolRef;
};

/// This class helps to assign indexes for DIE children.
/// Indexes are used to create type name for children which
/// should be presented in the original order(function parameters,
/// array dimensions, enumeration members, class/structure members).
class OrderedChildrenIndexAssigner {
public:
  OrderedChildrenIndexAssigner(CompileUnit &CU,
                               const DWARFDebugInfoEntry *DieEntry);

  /// Returns index of the specified child and width of hexadecimal
  /// representation.
  std::optional<std::pair<size_t, size_t>>
  getChildIndex(CompileUnit &CU, const DWARFDebugInfoEntry *ChildDieEntry);

protected:
  using OrderedChildrenIndexesArrayTy = std::array<size_t, 8>;

  std::optional<size_t> tagToArrayIndex(CompileUnit &CU,
                                        const DWARFDebugInfoEntry *DieEntry);

  bool NeedCountChildren = false;
  OrderedChildrenIndexesArrayTy OrderedChildIdxs = {0};
  OrderedChildrenIndexesArrayTy ChildIndexesWidth = {0};
};

} // end namespace dwarflinker_parallel
} // end namespace llvm

#endif // LLVM_LIB_DWARFLINKERNEXT_SYNTHETICTYPENAMEBUILDER_H