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