1 | //===-- LVType.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 LVType class, which is used to describe a debug |
10 | // information type. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVTYPE_H |
15 | #define LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVTYPE_H |
16 | |
17 | #include "llvm/DebugInfo/LogicalView/Core/LVElement.h" |
18 | |
19 | namespace llvm { |
20 | namespace logicalview { |
21 | |
22 | enum class LVTypeKind { |
23 | IsBase, |
24 | IsConst, |
25 | IsEnumerator, |
26 | IsImport, |
27 | IsImportDeclaration, |
28 | IsImportModule, |
29 | IsPointer, |
30 | IsPointerMember, |
31 | IsReference, |
32 | IsRestrict, |
33 | IsRvalueReference, |
34 | IsSubrange, |
35 | IsTemplateParam, |
36 | IsTemplateTemplateParam, |
37 | IsTemplateTypeParam, |
38 | IsTemplateValueParam, |
39 | IsTypedef, |
40 | IsUnaligned, |
41 | IsUnspecified, |
42 | IsVolatile, |
43 | IsModifier, // CodeView - LF_MODIFIER |
44 | LastEntry |
45 | }; |
46 | using LVTypeKindSelection = std::set<LVTypeKind>; |
47 | using LVTypeDispatch = std::map<LVTypeKind, LVTypeGetFunction>; |
48 | using LVTypeRequest = std::vector<LVTypeGetFunction>; |
49 | |
50 | // Class to represent a DWARF Type. |
51 | class LVType : public LVElement { |
52 | enum class Property { IsSubrangeCount, LastEntry }; |
53 | |
54 | // Typed bitvector with kinds and properties for this type. |
55 | LVProperties<LVTypeKind> Kinds; |
56 | LVProperties<Property> Properties; |
57 | static LVTypeDispatch Dispatch; |
58 | |
59 | // Find the current type in the given 'Targets'. |
60 | LVType *findIn(const LVTypes *Targets) const; |
61 | |
62 | public: |
63 | LVType() : LVElement(LVSubclassID::LV_TYPE) { setIsType(); } |
64 | LVType(const LVType &) = delete; |
65 | LVType &operator=(const LVType &) = delete; |
66 | virtual ~LVType() = default; |
67 | |
68 | static bool classof(const LVElement *Element) { |
69 | return Element->getSubclassID() == LVSubclassID::LV_TYPE; |
70 | } |
71 | |
72 | KIND(LVTypeKind, IsBase); |
73 | KIND(LVTypeKind, IsConst); |
74 | KIND(LVTypeKind, IsEnumerator); |
75 | KIND(LVTypeKind, IsImport); |
76 | KIND_1(LVTypeKind, IsImportDeclaration, IsImport); |
77 | KIND_1(LVTypeKind, IsImportModule, IsImport); |
78 | KIND(LVTypeKind, IsPointer); |
79 | KIND(LVTypeKind, IsPointerMember); |
80 | KIND(LVTypeKind, IsReference); |
81 | KIND(LVTypeKind, IsRestrict); |
82 | KIND(LVTypeKind, IsRvalueReference); |
83 | KIND(LVTypeKind, IsSubrange); |
84 | KIND(LVTypeKind, IsTemplateParam); |
85 | KIND_1(LVTypeKind, IsTemplateTemplateParam, IsTemplateParam); |
86 | KIND_1(LVTypeKind, IsTemplateTypeParam, IsTemplateParam); |
87 | KIND_1(LVTypeKind, IsTemplateValueParam, IsTemplateParam); |
88 | KIND(LVTypeKind, IsTypedef); |
89 | KIND(LVTypeKind, IsUnaligned); |
90 | KIND(LVTypeKind, IsUnspecified); |
91 | KIND(LVTypeKind, IsVolatile); |
92 | KIND(LVTypeKind, IsModifier); |
93 | |
94 | PROPERTY(Property, IsSubrangeCount); |
95 | |
96 | const char *kind() const override; |
97 | |
98 | // Follow a chain of references given by DW_AT_abstract_origin and/or |
99 | // DW_AT_specification and update the type name. |
100 | StringRef resolveReferencesChain(); |
101 | |
102 | bool isBase() const override { return getIsBase(); } |
103 | bool isTemplateParam() const override { return getIsTemplateParam(); } |
104 | |
105 | // Encode the specific template argument. |
106 | virtual void encodeTemplateArgument(std::string &Name) const {} |
107 | |
108 | // Return the underlying type for a type definition. |
109 | virtual LVElement *getUnderlyingType() { return nullptr; } |
110 | virtual void setUnderlyingType(LVElement *Element) {} |
111 | |
112 | void resolveName() override; |
113 | void resolveReferences() override; |
114 | |
115 | static LVTypeDispatch &getDispatch() { return Dispatch; } |
116 | |
117 | static bool parametersMatch(const LVTypes *References, |
118 | const LVTypes *Targets); |
119 | |
120 | static void getParameters(const LVTypes *Types, LVTypes *TypesParam, |
121 | LVScopes *ScopesParam); |
122 | |
123 | // Iterate through the 'References' set and check that all its elements |
124 | // are present in the 'Targets' set. For a missing element, mark its |
125 | // parents as missing. |
126 | static void markMissingParents(const LVTypes *References, |
127 | const LVTypes *Targets); |
128 | |
129 | // Returns true if current type is logically equal to the given 'Type'. |
130 | virtual bool equals(const LVType *Type) const; |
131 | |
132 | // Returns true if the given 'References' are logically equal to the |
133 | // given 'Targets'. |
134 | static bool equals(const LVTypes *References, const LVTypes *Targets); |
135 | |
136 | // Report the current type as missing or added during comparison. |
137 | void report(LVComparePass Pass) override; |
138 | |
139 | void print(raw_ostream &OS, bool Full = true) const override; |
140 | void (raw_ostream &OS, bool Full = true) const override; |
141 | |
142 | #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) |
143 | void dump() const override { print(OS&: dbgs()); } |
144 | #endif |
145 | }; |
146 | |
147 | // Class to represent DW_TAG_typedef_type. |
148 | class LVTypeDefinition final : public LVType { |
149 | public: |
150 | LVTypeDefinition() : LVType() { |
151 | setIsTypedef(); |
152 | setIncludeInPrint(); |
153 | } |
154 | LVTypeDefinition(const LVTypeDefinition &) = delete; |
155 | LVTypeDefinition &operator=(const LVTypeDefinition &) = delete; |
156 | ~LVTypeDefinition() = default; |
157 | |
158 | // Return the underlying type for a type definition. |
159 | LVElement *getUnderlyingType() override; |
160 | void setUnderlyingType(LVElement *Element) override { setType(Element); } |
161 | |
162 | void () override; |
163 | |
164 | // Returns true if current type is logically equal to the given 'Type'. |
165 | bool equals(const LVType *Type) const override; |
166 | |
167 | void (raw_ostream &OS, bool Full = true) const override; |
168 | }; |
169 | |
170 | // Class to represent a DW_TAG_enumerator. |
171 | class LVTypeEnumerator final : public LVType { |
172 | // Index in the String pool representing any initial value. |
173 | size_t ValueIndex = 0; |
174 | |
175 | public: |
176 | LVTypeEnumerator() : LVType() { |
177 | setIsEnumerator(); |
178 | setIncludeInPrint(); |
179 | } |
180 | LVTypeEnumerator(const LVTypeEnumerator &) = delete; |
181 | LVTypeEnumerator &operator=(const LVTypeEnumerator &) = delete; |
182 | ~LVTypeEnumerator() = default; |
183 | |
184 | // Process the values for a DW_TAG_enumerator. |
185 | StringRef getValue() const override { |
186 | return getStringPool().getString(Index: ValueIndex); |
187 | } |
188 | void setValue(StringRef Value) override { |
189 | ValueIndex = getStringPool().getIndex(Key: Value); |
190 | } |
191 | size_t getValueIndex() const override { return ValueIndex; } |
192 | |
193 | // Returns true if current type is logically equal to the given 'Type'. |
194 | bool equals(const LVType *Type) const override; |
195 | |
196 | void (raw_ostream &OS, bool Full = true) const override; |
197 | }; |
198 | |
199 | // Class to represent DW_TAG_imported_module / DW_TAG_imported_declaration. |
200 | class LVTypeImport final : public LVType { |
201 | public: |
202 | LVTypeImport() : LVType() { setIncludeInPrint(); } |
203 | LVTypeImport(const LVTypeImport &) = delete; |
204 | LVTypeImport &operator=(const LVTypeImport &) = delete; |
205 | ~LVTypeImport() = default; |
206 | |
207 | // Returns true if current type is logically equal to the given 'Type'. |
208 | bool equals(const LVType *Type) const override; |
209 | |
210 | void (raw_ostream &OS, bool Full = true) const override; |
211 | }; |
212 | |
213 | // Class to represent a DWARF Template parameter holder (type or param). |
214 | class LVTypeParam final : public LVType { |
215 | // Index in the String pool representing any initial value. |
216 | size_t ValueIndex = 0; |
217 | |
218 | public: |
219 | LVTypeParam(); |
220 | LVTypeParam(const LVTypeParam &) = delete; |
221 | LVTypeParam &operator=(const LVTypeParam &) = delete; |
222 | ~LVTypeParam() = default; |
223 | |
224 | // Template parameter value. |
225 | StringRef getValue() const override { |
226 | return getStringPool().getString(Index: ValueIndex); |
227 | } |
228 | void setValue(StringRef Value) override { |
229 | ValueIndex = getStringPool().getIndex(Key: Value); |
230 | } |
231 | size_t getValueIndex() const override { return ValueIndex; } |
232 | |
233 | // Encode the specific template argument. |
234 | void encodeTemplateArgument(std::string &Name) const override; |
235 | |
236 | // Returns true if current type is logically equal to the given 'Type'. |
237 | bool equals(const LVType *Type) const override; |
238 | |
239 | void (raw_ostream &OS, bool Full = true) const override; |
240 | }; |
241 | |
242 | // Class to represent a DW_TAG_subrange_type. |
243 | class LVTypeSubrange final : public LVType { |
244 | // Values describing the subrange bounds. |
245 | int64_t LowerBound = 0; // DW_AT_lower_bound or DW_AT_count value. |
246 | int64_t UpperBound = 0; // DW_AT_upper_bound value. |
247 | |
248 | public: |
249 | LVTypeSubrange() : LVType() { |
250 | setIsSubrange(); |
251 | setIncludeInPrint(); |
252 | } |
253 | LVTypeSubrange(const LVTypeSubrange &) = delete; |
254 | LVTypeSubrange &operator=(const LVTypeSubrange &) = delete; |
255 | ~LVTypeSubrange() = default; |
256 | |
257 | int64_t getCount() const override { |
258 | return getIsSubrangeCount() ? LowerBound : 0; |
259 | } |
260 | void setCount(int64_t Value) override { |
261 | LowerBound = Value; |
262 | setIsSubrangeCount(); |
263 | } |
264 | |
265 | int64_t getLowerBound() const override { return LowerBound; } |
266 | void setLowerBound(int64_t Value) override { LowerBound = Value; } |
267 | |
268 | int64_t getUpperBound() const override { return UpperBound; } |
269 | void setUpperBound(int64_t Value) override { UpperBound = Value; } |
270 | |
271 | std::pair<unsigned, unsigned> getBounds() const override { |
272 | return {LowerBound, UpperBound}; |
273 | } |
274 | void setBounds(unsigned Lower, unsigned Upper) override { |
275 | LowerBound = Lower; |
276 | UpperBound = Upper; |
277 | } |
278 | |
279 | void () override; |
280 | |
281 | // Returns true if current type is logically equal to the given 'Type'. |
282 | bool equals(const LVType *Type) const override; |
283 | |
284 | void (raw_ostream &OS, bool Full = true) const override; |
285 | }; |
286 | |
287 | } // end namespace logicalview |
288 | } // end namespace llvm |
289 | |
290 | #endif // LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVTYPE_H |
291 | |