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