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 printExtra(raw_ostream &OS, bool Full = true) const override;
141 
142 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
143   void dump() const override { print(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 resolveExtra() 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 printExtra(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   std::string getValue() const override {
186     return std::string(getStringPool().getString(ValueIndex));
187   }
188   void setValue(StringRef Value) override {
189     ValueIndex = getStringPool().getIndex(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 printExtra(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 printExtra(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   std::string getValue() const override {
226     return std::string(getStringPool().getString(ValueIndex));
227   }
228   void setValue(StringRef Value) override {
229     ValueIndex = getStringPool().getIndex(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 printExtra(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 resolveExtra() 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 printExtra(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