1 | //===-- LVSymbol.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 | // This file defines the LVSymbol class, which is used to describe a debug |
10 | // information symbol. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVSYMBOL_H |
15 | #define LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVSYMBOL_H |
16 | |
17 | #include "llvm/DebugInfo/LogicalView/Core/LVElement.h" |
18 | |
19 | namespace llvm { |
20 | namespace logicalview { |
21 | |
22 | enum class LVSymbolKind { |
23 | IsCallSiteParameter, |
24 | IsConstant, |
25 | IsInheritance, |
26 | IsMember, |
27 | IsParameter, |
28 | IsUnspecified, |
29 | IsVariable, |
30 | LastEntry |
31 | }; |
32 | using LVSymbolKindSet = std::set<LVSymbolKind>; |
33 | using LVSymbolDispatch = std::map<LVSymbolKind, LVSymbolGetFunction>; |
34 | using LVSymbolRequest = std::vector<LVSymbolGetFunction>; |
35 | |
36 | class LVSymbol final : public LVElement { |
37 | enum class Property { HasLocation, FillGaps, LastEntry }; |
38 | |
39 | // Typed bitvector with kinds and properties for this symbol. |
40 | LVProperties<LVSymbolKind> Kinds; |
41 | LVProperties<Property> Properties; |
42 | static LVSymbolDispatch Dispatch; |
43 | |
44 | // CodeView symbol Linkage name. |
45 | size_t LinkageNameIndex = 0; |
46 | |
47 | // Reference to DW_AT_specification, DW_AT_abstract_origin attribute. |
48 | LVSymbol *Reference = nullptr; |
49 | std::unique_ptr<LVLocations> Locations; |
50 | LVLocation *CurrentLocation = nullptr; |
51 | |
52 | // Bitfields length. |
53 | uint32_t BitSize = 0; |
54 | |
55 | // Index in the String pool representing any initial value. |
56 | size_t ValueIndex = 0; |
57 | |
58 | // Coverage factor in units (bytes). |
59 | unsigned CoverageFactor = 0; |
60 | float CoveragePercentage = 0; |
61 | |
62 | // Add a location gap into the location list. |
63 | LVLocations::iterator addLocationGap(LVLocations::iterator Pos, |
64 | LVAddress LowPC, LVAddress HighPC); |
65 | |
66 | // Find the current symbol in the given 'Targets'. |
67 | LVSymbol *findIn(const LVSymbols *Targets) const; |
68 | |
69 | public: |
70 | LVSymbol() : LVElement(LVSubclassID::LV_SYMBOL) { |
71 | setIsSymbol(); |
72 | setIncludeInPrint(); |
73 | } |
74 | LVSymbol(const LVSymbol &) = delete; |
75 | LVSymbol &operator=(const LVSymbol &) = delete; |
76 | ~LVSymbol() = default; |
77 | |
78 | static bool classof(const LVElement *Element) { |
79 | return Element->getSubclassID() == LVSubclassID::LV_SYMBOL; |
80 | } |
81 | |
82 | KIND(LVSymbolKind, IsCallSiteParameter); |
83 | KIND(LVSymbolKind, IsConstant); |
84 | KIND(LVSymbolKind, IsInheritance); |
85 | KIND(LVSymbolKind, IsMember); |
86 | KIND(LVSymbolKind, IsParameter); |
87 | KIND(LVSymbolKind, IsUnspecified); |
88 | KIND(LVSymbolKind, IsVariable); |
89 | |
90 | PROPERTY(Property, HasLocation); |
91 | PROPERTY(Property, FillGaps); |
92 | |
93 | const char *kind() const override; |
94 | |
95 | // Access DW_AT_specification, DW_AT_abstract_origin reference. |
96 | LVSymbol *getReference() const { return Reference; } |
97 | void setReference(LVSymbol *Symbol) override { |
98 | Reference = Symbol; |
99 | setHasReference(); |
100 | } |
101 | void setReference(LVElement *Element) override { |
102 | assert((!Element || isa<LVSymbol>(Element)) && "Invalid element" ); |
103 | setReference(static_cast<LVSymbol *>(Element)); |
104 | } |
105 | |
106 | void setLinkageName(StringRef LinkageName) override { |
107 | LinkageNameIndex = getStringPool().getIndex(Key: LinkageName); |
108 | } |
109 | StringRef getLinkageName() const override { |
110 | return getStringPool().getString(Index: LinkageNameIndex); |
111 | } |
112 | size_t getLinkageNameIndex() const override { return LinkageNameIndex; } |
113 | |
114 | uint32_t getBitSize() const override { return BitSize; } |
115 | void setBitSize(uint32_t Size) override { BitSize = Size; } |
116 | |
117 | // Process the values for a DW_AT_const_value. |
118 | StringRef getValue() const override { |
119 | return getStringPool().getString(Index: ValueIndex); |
120 | } |
121 | void setValue(StringRef Value) override { |
122 | ValueIndex = getStringPool().getIndex(Key: Value); |
123 | } |
124 | size_t getValueIndex() const override { return ValueIndex; } |
125 | |
126 | // Add a Location Entry. |
127 | void addLocationConstant(dwarf::Attribute Attr, LVUnsigned Constant, |
128 | uint64_t LocDescOffset); |
129 | void addLocationOperands(LVSmall Opcode, ArrayRef<uint64_t> Operands); |
130 | void addLocation(dwarf::Attribute Attr, LVAddress LowPC, LVAddress HighPC, |
131 | LVUnsigned SectionOffset, uint64_t LocDescOffset, |
132 | bool CallSiteLocation = false); |
133 | |
134 | // Fill gaps in the location list. |
135 | void fillLocationGaps(); |
136 | |
137 | // Get all the locations associated with symbols. |
138 | void getLocations(LVLocations &LocationList, LVValidLocation ValidLocation, |
139 | bool RecordInvalid = false); |
140 | void getLocations(LVLocations &LocationList) const; |
141 | |
142 | // Calculate coverage factor. |
143 | void calculateCoverage(); |
144 | |
145 | unsigned getCoverageFactor() const { return CoverageFactor; } |
146 | void setCoverageFactor(unsigned Value) { CoverageFactor = Value; } |
147 | float getCoveragePercentage() const { return CoveragePercentage; } |
148 | void setCoveragePercentage(float Value) { CoveragePercentage = Value; } |
149 | |
150 | // Print location in raw format. |
151 | void printLocations(raw_ostream &OS, bool Full = true) const; |
152 | |
153 | // Follow a chain of references given by DW_AT_abstract_origin and/or |
154 | // DW_AT_specification and update the symbol name. |
155 | StringRef resolveReferencesChain(); |
156 | |
157 | void resolveName() override; |
158 | void resolveReferences() override; |
159 | |
160 | static LVSymbolDispatch &getDispatch() { return Dispatch; } |
161 | |
162 | static bool parametersMatch(const LVSymbols *References, |
163 | const LVSymbols *Targets); |
164 | |
165 | static void getParameters(const LVSymbols *Symbols, LVSymbols *Parameters); |
166 | |
167 | // Iterate through the 'References' set and check that all its elements |
168 | // are present in the 'Targets' set. For a missing element, mark its |
169 | // parents as missing. |
170 | static void markMissingParents(const LVSymbols *References, |
171 | const LVSymbols *Targets); |
172 | |
173 | // Returns true if current type is logically equal to the given 'Symbol'. |
174 | bool equals(const LVSymbol *Symbol) const; |
175 | |
176 | // Returns true if the given 'References' are logically equal to the |
177 | // given 'Targets'. |
178 | static bool equals(const LVSymbols *References, const LVSymbols *Targets); |
179 | |
180 | // Report the current symbol as missing or added during comparison. |
181 | void report(LVComparePass Pass) override; |
182 | |
183 | void print(raw_ostream &OS, bool Full = true) const override; |
184 | void (raw_ostream &OS, bool Full = true) const override; |
185 | |
186 | #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) |
187 | void dump() const override { print(OS&: dbgs()); } |
188 | #endif |
189 | }; |
190 | |
191 | } // end namespace logicalview |
192 | } // end namespace llvm |
193 | |
194 | #endif // LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVSYMBOL_H |
195 | |