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