1 //===-- LVElement.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 LVElement class, which is used to describe a debug
10 // information element.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVELEMENT_H
15 #define LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVELEMENT_H
16 
17 #include "llvm/DebugInfo/LogicalView/Core/LVObject.h"
18 #include "llvm/Support/Casting.h"
19 #include <map>
20 #include <set>
21 #include <vector>
22 
23 namespace llvm {
24 namespace logicalview {
25 
26 // RTTI Subclasses ID.
27 enum class LVSubclassID : unsigned char {
28   LV_ELEMENT,
29   LV_LINE_FIRST,
30   LV_LINE,
31   LV_LINE_DEBUG,
32   LV_LINE_ASSEMBLER,
33   LV_LINE_LAST,
34   lV_SCOPE_FIRST,
35   LV_SCOPE,
36   LV_SCOPE_AGGREGATE,
37   LV_SCOPE_ALIAS,
38   LV_SCOPE_ARRAY,
39   LV_SCOPE_COMPILE_UNIT,
40   LV_SCOPE_ENUMERATION,
41   LV_SCOPE_FORMAL_PACK,
42   LV_SCOPE_FUNCTION,
43   LV_SCOPE_FUNCTION_INLINED,
44   LV_SCOPE_FUNCTION_TYPE,
45   LV_SCOPE_NAMESPACE,
46   LV_SCOPE_ROOT,
47   LV_SCOPE_TEMPLATE_PACK,
48   LV_SCOPE_LAST,
49   LV_SYMBOL_FIRST,
50   LV_SYMBOL,
51   LV_SYMBOL_LAST,
52   LV_TYPE_FIRST,
53   LV_TYPE,
54   LV_TYPE_DEFINITION,
55   LV_TYPE_ENUMERATOR,
56   LV_TYPE_IMPORT,
57   LV_TYPE_PARAM,
58   LV_TYPE_SUBRANGE,
59   LV_TYPE_LAST
60 };
61 
62 enum class LVElementKind { Discarded, Global, Optimized, LastEntry };
63 using LVElementKindSet = std::set<LVElementKind>;
64 using LVElementDispatch = std::map<LVElementKind, LVElementGetFunction>;
65 using LVElementRequest = std::vector<LVElementGetFunction>;
66 
67 class LVElement : public LVObject {
68   enum class Property {
69     IsLine,   // A logical line.
70     IsScope,  // A logical scope.
71     IsSymbol, // A logical symbol.
72     IsType,   // A logical type.
73     IsEnumClass,
74     IsExternal,
75     HasType,
76     HasAugmentedName,
77     IsTypedefReduced,
78     IsArrayResolved,
79     IsMemberPointerResolved,
80     IsTemplateResolved,
81     IsInlined,
82     IsInlinedAbstract,
83     InvalidFilename,
84     HasReference,
85     HasReferenceAbstract,
86     HasReferenceExtension,
87     HasReferenceSpecification,
88     QualifiedResolved,
89     IncludeInPrint,
90     IsStatic,
91     TransformName,
92     IsScoped,        // CodeView local type.
93     IsNested,        // CodeView nested type.
94     IsScopedAlready, // CodeView nested type inserted in correct scope.
95     IsArtificial,
96     IsReferencedType,
97     IsSystem,
98     OffsetFromTypeIndex,
99     IsAnonymous,
100     LastEntry
101   };
102   // Typed bitvector with properties for this element.
103   LVProperties<Property> Properties;
104   static LVElementDispatch Dispatch;
105 
106   /// RTTI.
107   const LVSubclassID SubclassID;
108 
109   // Indexes in the String Pool.
110   size_t NameIndex = 0;
111   size_t QualifiedNameIndex = 0;
112   size_t FilenameIndex = 0;
113 
114   uint16_t AccessibilityCode : 2; // DW_AT_accessibility.
115   uint16_t InlineCode : 2;        // DW_AT_inline.
116   uint16_t VirtualityCode : 2;    // DW_AT_virtuality.
117 
118   // The given Specification points to an element that is connected via the
119   // DW_AT_specification, DW_AT_abstract_origin or DW_AT_extension attribute.
120   void setFileLine(LVElement *Specification);
121 
122   // Get the qualified name that include its parents name.
123   void resolveQualifiedName();
124 
125 protected:
126   // Type of this element.
127   LVElement *ElementType = nullptr;
128 
129   // Print the FileName Index.
130   void printFileIndex(raw_ostream &OS, bool Full = true) const override;
131 
132 public:
LVElement(LVSubclassID ID)133   LVElement(LVSubclassID ID)
134       : LVObject(), SubclassID(ID), AccessibilityCode(0), InlineCode(0),
135         VirtualityCode(0) {}
136   LVElement(const LVElement &) = delete;
137   LVElement &operator=(const LVElement &) = delete;
138   virtual ~LVElement() = default;
139 
getSubclassID()140   LVSubclassID getSubclassID() const { return SubclassID; }
141 
142   PROPERTY(Property, IsLine);
143   PROPERTY(Property, IsScope);
144   PROPERTY(Property, IsSymbol);
145   PROPERTY(Property, IsType);
146   PROPERTY(Property, IsEnumClass);
147   PROPERTY(Property, IsExternal);
148   PROPERTY(Property, HasType);
149   PROPERTY(Property, HasAugmentedName);
150   PROPERTY(Property, IsTypedefReduced);
151   PROPERTY(Property, IsArrayResolved);
152   PROPERTY(Property, IsMemberPointerResolved);
153   PROPERTY(Property, IsTemplateResolved);
154   PROPERTY(Property, IsInlined);
155   PROPERTY(Property, IsInlinedAbstract);
156   PROPERTY(Property, InvalidFilename);
157   PROPERTY(Property, HasReference);
158   PROPERTY(Property, HasReferenceAbstract);
159   PROPERTY(Property, HasReferenceExtension);
160   PROPERTY(Property, HasReferenceSpecification);
161   PROPERTY(Property, QualifiedResolved);
162   PROPERTY(Property, IncludeInPrint);
163   PROPERTY(Property, IsStatic);
164   PROPERTY(Property, TransformName);
165   PROPERTY(Property, IsScoped);
166   PROPERTY(Property, IsNested);
167   PROPERTY(Property, IsScopedAlready);
168   PROPERTY(Property, IsArtificial);
169   PROPERTY(Property, IsReferencedType);
170   PROPERTY(Property, IsSystem);
171   PROPERTY(Property, OffsetFromTypeIndex);
172   PROPERTY(Property, IsAnonymous);
173 
isNamed()174   bool isNamed() const override { return NameIndex != 0; }
isTyped()175   bool isTyped() const override { return ElementType != nullptr; }
isFiled()176   bool isFiled() const override { return FilenameIndex != 0; }
177 
178   // The Element class type can point to a Type or Scope.
getIsKindType()179   bool getIsKindType() const { return ElementType && ElementType->getIsType(); }
getIsKindScope()180   bool getIsKindScope() const {
181     return ElementType && ElementType->getIsScope();
182   }
183 
getName()184   StringRef getName() const override {
185     return getStringPool().getString(NameIndex);
186   }
187   void setName(StringRef ElementName) override;
188 
189   // Get pathname associated with the Element.
getPathname()190   StringRef getPathname() const {
191     return getStringPool().getString(getFilenameIndex());
192   }
193 
194   // Set filename associated with the Element.
195   void setFilename(StringRef Filename);
196 
197   // Set the Element qualified name.
setQualifiedName(StringRef Name)198   void setQualifiedName(StringRef Name) {
199     QualifiedNameIndex = getStringPool().getIndex(Name);
200   }
getQualifiedName()201   StringRef getQualifiedName() const {
202     return getStringPool().getString(QualifiedNameIndex);
203   }
204 
getNameIndex()205   size_t getNameIndex() const { return NameIndex; }
getQualifiedNameIndex()206   size_t getQualifiedNameIndex() const { return QualifiedNameIndex; }
207 
208   // Element type name.
209   StringRef getTypeName() const;
210 
getProducer()211   virtual StringRef getProducer() const { return StringRef(); }
setProducer(StringRef ProducerName)212   virtual void setProducer(StringRef ProducerName) {}
213 
isCompileUnit()214   virtual bool isCompileUnit() const { return false; }
isRoot()215   virtual bool isRoot() const { return false; }
216 
setReference(LVElement * Element)217   virtual void setReference(LVElement *Element) {}
setReference(LVScope * Scope)218   virtual void setReference(LVScope *Scope) {}
setReference(LVSymbol * Symbol)219   virtual void setReference(LVSymbol *Symbol) {}
setReference(LVType * Type)220   virtual void setReference(LVType *Type) {}
221 
setLinkageName(StringRef LinkageName)222   virtual void setLinkageName(StringRef LinkageName) {}
getLinkageName()223   virtual StringRef getLinkageName() const { return StringRef(); }
getLinkageNameIndex()224   virtual size_t getLinkageNameIndex() const { return 0; }
225 
getCallLineNumber()226   virtual uint32_t getCallLineNumber() const { return 0; }
setCallLineNumber(uint32_t Number)227   virtual void setCallLineNumber(uint32_t Number) {}
getCallFilenameIndex()228   virtual size_t getCallFilenameIndex() const { return 0; }
setCallFilenameIndex(size_t Index)229   virtual void setCallFilenameIndex(size_t Index) {}
getFilenameIndex()230   size_t getFilenameIndex() const { return FilenameIndex; }
setFilenameIndex(size_t Index)231   void setFilenameIndex(size_t Index) { FilenameIndex = Index; }
232 
233   // Set the File location for the Element.
234   void setFile(LVElement *Reference = nullptr);
235 
isBase()236   virtual bool isBase() const { return false; }
isTemplateParam()237   virtual bool isTemplateParam() const { return false; }
238 
getBitSize()239   virtual uint32_t getBitSize() const { return 0; }
setBitSize(uint32_t Size)240   virtual void setBitSize(uint32_t Size) {}
241 
getCount()242   virtual int64_t getCount() const { return 0; }
setCount(int64_t Value)243   virtual void setCount(int64_t Value) {}
getLowerBound()244   virtual int64_t getLowerBound() const { return 0; }
setLowerBound(int64_t Value)245   virtual void setLowerBound(int64_t Value) {}
getUpperBound()246   virtual int64_t getUpperBound() const { return 0; }
setUpperBound(int64_t Value)247   virtual void setUpperBound(int64_t Value) {}
getBounds()248   virtual std::pair<unsigned, unsigned> getBounds() const { return {}; }
setBounds(unsigned Lower,unsigned Upper)249   virtual void setBounds(unsigned Lower, unsigned Upper) {}
250 
251   // Access DW_AT_GNU_discriminator attribute.
getDiscriminator()252   virtual uint32_t getDiscriminator() const { return 0; }
setDiscriminator(uint32_t Value)253   virtual void setDiscriminator(uint32_t Value) {}
254 
255   // Process the values for a DW_TAG_enumerator.
getValue()256   virtual std::string getValue() const { return {}; }
setValue(StringRef Value)257   virtual void setValue(StringRef Value) {}
getValueIndex()258   virtual size_t getValueIndex() const { return 0; }
259 
260   // DWARF Accessibility Codes.
getAccessibilityCode()261   uint32_t getAccessibilityCode() const { return AccessibilityCode; }
setAccessibilityCode(uint32_t Access)262   void setAccessibilityCode(uint32_t Access) { AccessibilityCode = Access; }
263   StringRef
264   accessibilityString(uint32_t Access = dwarf::DW_ACCESS_private) const;
265 
266   // DWARF Inline Codes.
getInlineCode()267   uint32_t getInlineCode() const { return InlineCode; }
setInlineCode(uint32_t Code)268   void setInlineCode(uint32_t Code) { InlineCode = Code; }
269   StringRef inlineCodeString(uint32_t Code) const;
270 
271   // DWARF Virtuality Codes.
getVirtualityCode()272   uint32_t getVirtualityCode() const { return VirtualityCode; }
setVirtualityCode(uint32_t Virtuality)273   void setVirtualityCode(uint32_t Virtuality) { VirtualityCode = Virtuality; }
274   StringRef
275   virtualityString(uint32_t Virtuality = dwarf::DW_VIRTUALITY_none) const;
276 
277   // DWARF Extern Codes.
278   StringRef externalString() const;
279 
getType()280   LVElement *getType() const { return ElementType; }
281   LVType *getTypeAsType() const;
282   LVScope *getTypeAsScope() const;
283 
284   void setType(LVElement *Element = nullptr) {
285     ElementType = Element;
286     if (Element) {
287       setHasType();
288       Element->setIsReferencedType();
289     }
290   }
291 
292   // Set the type for the element, handling template parameters.
293   void setGenericType(LVElement *Element);
294 
getTypeQualifiedName()295   StringRef getTypeQualifiedName() const {
296     return ElementType ? ElementType->getQualifiedName() : "";
297   }
298 
299   StringRef typeAsString() const;
300   std::string typeOffsetAsString() const;
301   std::string discriminatorAsString() const;
302 
303   LVScope *traverseParents(LVScopeGetFunction GetFunction) const;
304 
305   LVScope *getFunctionParent() const;
306   virtual LVScope *getCompileUnitParent() const;
307 
308   // Print any referenced element.
309   void printReference(raw_ostream &OS, bool Full, LVElement *Parent) const;
310 
311   // Print the linkage name (Symbols and functions).
312   void printLinkageName(raw_ostream &OS, bool Full, LVElement *Parent,
313                         LVScope *Scope) const;
314   void printLinkageName(raw_ostream &OS, bool Full, LVElement *Parent) const;
315 
316   // Generate the full name for the Element.
317   void resolveFullname(LVElement *BaseType, StringRef Name = emptyString());
318 
319   // Generate a name for unnamed elements.
320   void generateName(std::string &Prefix) const;
321   void generateName();
322 
removeElement(LVElement * Element)323   virtual bool removeElement(LVElement *Element) { return false; }
324   virtual void updateLevel(LVScope *Parent, bool Moved = false);
325 
326   // During the parsing of the debug information, the logical elements are
327   // created with information extracted from its description entries (DIE).
328   // But they are not complete for the logical view concept. A second pass
329   // is executed in order to collect their additional information.
330   // The following functions 'resolve' some of their properties, such as
331   // name, references, parents, extra information based on the element kind.
332   virtual void resolve();
resolveExtra()333   virtual void resolveExtra() {}
334   virtual void resolveName();
resolveReferences()335   virtual void resolveReferences() {}
336   void resolveParents();
337 
338   bool referenceMatch(const LVElement *Element) const;
339 
340   // Returns true if current element is logically equal to the given 'Element'.
341   bool equals(const LVElement *Element) const;
342 
343   // Report the current element as missing or added during comparison.
report(LVComparePass Pass)344   virtual void report(LVComparePass Pass) {}
345 
getDispatch()346   static LVElementDispatch &getDispatch() { return Dispatch; }
347 };
348 
349 } // end namespace logicalview
350 } // end namespace llvm
351 
352 #endif // LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVELEMENT_H
353