Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:42

0001 //===-- LVObject.h ----------------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file defines the LVObject class, which is used to describe a debug
0010 // information object.
0011 //
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVOBJECT_H
0015 #define LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVOBJECT_H
0016 
0017 #include "llvm/BinaryFormat/Dwarf.h"
0018 #include "llvm/DebugInfo/CodeView/CodeView.h"
0019 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
0020 #include "llvm/DebugInfo/LogicalView/Core/LVSupport.h"
0021 #include <limits>
0022 #include <list>
0023 #include <string>
0024 
0025 namespace llvm {
0026 namespace dwarf {
0027 // Support for CodeView ModifierOptions::Unaligned.
0028 constexpr Tag DW_TAG_unaligned = Tag(dwarf::DW_TAG_hi_user + 1);
0029 } // namespace dwarf
0030 } // namespace llvm
0031 
0032 namespace llvm {
0033 namespace logicalview {
0034 
0035 using LVSectionIndex = uint64_t;
0036 using LVAddress = uint64_t;
0037 using LVHalf = uint16_t;
0038 using LVLevel = uint32_t;
0039 using LVOffset = uint64_t;
0040 using LVSigned = int64_t;
0041 using LVUnsigned = uint64_t;
0042 using LVSmall = uint8_t;
0043 
0044 class LVElement;
0045 class LVLine;
0046 class LVLocation;
0047 class LVLocationSymbol;
0048 class LVObject;
0049 class LVOperation;
0050 class LVScope;
0051 class LVSymbol;
0052 class LVType;
0053 
0054 class LVOptions;
0055 class LVPatterns;
0056 
0057 StringRef typeNone();
0058 StringRef typeVoid();
0059 StringRef typeInt();
0060 StringRef typeUnknown();
0061 StringRef emptyString();
0062 
0063 using LVElementSetFunction = void (LVElement::*)();
0064 using LVElementGetFunction = bool (LVElement::*)() const;
0065 using LVLineSetFunction = void (LVLine::*)();
0066 using LVLineGetFunction = bool (LVLine::*)() const;
0067 using LVObjectSetFunction = void (LVObject::*)();
0068 using LVObjectGetFunction = bool (LVObject::*)() const;
0069 using LVScopeSetFunction = void (LVScope::*)();
0070 using LVScopeGetFunction = bool (LVScope::*)() const;
0071 using LVSymbolSetFunction = void (LVSymbol::*)();
0072 using LVSymbolGetFunction = bool (LVSymbol::*)() const;
0073 using LVTypeSetFunction = void (LVType::*)();
0074 using LVTypeGetFunction = bool (LVType::*)() const;
0075 
0076 using LVElements = SmallVector<LVElement *, 8>;
0077 using LVLines = SmallVector<LVLine *, 8>;
0078 using LVLocations = SmallVector<LVLocation *, 8>;
0079 using LVOperations = SmallVector<LVOperation *, 8>;
0080 using LVScopes = SmallVector<LVScope *, 8>;
0081 using LVSymbols = SmallVector<LVSymbol *, 8>;
0082 using LVTypes = SmallVector<LVType *, 8>;
0083 
0084 using LVOffsets = SmallVector<LVOffset, 8>;
0085 
0086 const LVAddress MaxAddress = std::numeric_limits<uint64_t>::max();
0087 
0088 enum class LVBinaryType { NONE, ELF, COFF };
0089 enum class LVComparePass { Missing, Added };
0090 
0091 // Validate functions.
0092 using LVValidLocation = bool (LVLocation::*)();
0093 
0094 // Keep counters of objects.
0095 struct LVCounter {
0096   unsigned Lines = 0;
0097   unsigned Scopes = 0;
0098   unsigned Symbols = 0;
0099   unsigned Types = 0;
0100   void reset() {
0101     Lines = 0;
0102     Scopes = 0;
0103     Symbols = 0;
0104     Types = 0;
0105   }
0106 };
0107 
0108 class LVObject {
0109   enum class Property {
0110     IsLocation,          // Location.
0111     IsGlobalReference,   // This object is being referenced from another CU.
0112     IsGeneratedName,     // The Object name was generated.
0113     IsResolved,          // Object has been resolved.
0114     IsResolvedName,      // Object name has been resolved.
0115     IsDiscarded,         // Object has been stripped by the linker.
0116     IsOptimized,         // Object has been optimized by the compiler.
0117     IsAdded,             // Object has been 'added'.
0118     IsMatched,           // Object has been matched to a given pattern.
0119     IsMissing,           // Object is 'missing'.
0120     IsMissingLink,       // Object is indirectly 'missing'.
0121     IsInCompare,         // In 'compare' mode.
0122     IsFileFromReference, // File ID from specification.
0123     IsLineFromReference, // Line No from specification.
0124     HasMoved,            // The object was moved from 'target' to 'reference'.
0125     HasPattern,          // The object has a pattern.
0126     IsFinalized,         // CodeView object is finalized.
0127     IsReferenced,        // CodeView object being referenced.
0128     HasCodeViewLocation, // CodeView object with debug location.
0129     LastEntry
0130   };
0131   // Typed bitvector with properties for this object.
0132   LVProperties<Property> Properties;
0133 
0134   LVOffset Offset = 0;
0135   uint32_t LineNumber = 0;
0136   LVLevel ScopeLevel = 0;
0137   union {
0138     dwarf::Tag Tag;
0139     dwarf::Attribute Attr;
0140     LVSmall Opcode;
0141   } TagAttrOpcode = {dwarf::DW_TAG_null};
0142 
0143   // The parent of this object (nullptr if the root scope). For locations,
0144   // the parent is a symbol object; otherwise it is a scope object.
0145   union {
0146     LVElement *Element;
0147     LVScope *Scope;
0148     LVSymbol *Symbol;
0149   } Parent = {nullptr};
0150 
0151   // We do not support any object duplication, as they are created by parsing
0152   // the debug information. There is only the case where we need a very basic
0153   // object, to manipulate its offset, line number and scope level. Allow the
0154   // copy constructor to create that object; it is used to print a reference
0155   // to another object and in the case of templates, to print its encoded args.
0156   LVObject(const LVObject &Object) {
0157 #ifndef NDEBUG
0158     incID();
0159 #endif
0160     Properties = Object.Properties;
0161     Offset = Object.Offset;
0162     LineNumber = Object.LineNumber;
0163     ScopeLevel = Object.ScopeLevel;
0164     TagAttrOpcode = Object.TagAttrOpcode;
0165     Parent = Object.Parent;
0166   }
0167 
0168 #ifndef NDEBUG
0169   // This is an internal ID used for debugging logical elements. It is used
0170   // for cases where an unique offset within the binary input file is not
0171   // available.
0172   static uint64_t GID;
0173   uint64_t ID = 0;
0174 
0175   void incID() {
0176     ++GID;
0177     ID = GID;
0178   }
0179 #endif
0180 
0181 protected:
0182   // Get a string representation for the given number and discriminator.
0183   std::string lineAsString(uint32_t LineNumber, LVHalf Discriminator,
0184                            bool ShowZero) const;
0185 
0186   // Get a string representation for the given number.
0187   std::string referenceAsString(uint32_t LineNumber, bool Spaces) const;
0188 
0189   // Print the Filename or Pathname.
0190   // Empty implementation for those objects that do not have any user
0191   // source file references, such as debug locations.
0192   virtual void printFileIndex(raw_ostream &OS, bool Full = true) const {}
0193 
0194 public:
0195   LVObject() {
0196 #ifndef NDEBUG
0197     incID();
0198 #endif
0199   };
0200   LVObject &operator=(const LVObject &) = delete;
0201   virtual ~LVObject() = default;
0202 
0203   PROPERTY(Property, IsLocation);
0204   PROPERTY(Property, IsGlobalReference);
0205   PROPERTY(Property, IsGeneratedName);
0206   PROPERTY(Property, IsResolved);
0207   PROPERTY(Property, IsResolvedName);
0208   PROPERTY(Property, IsDiscarded);
0209   PROPERTY(Property, IsOptimized);
0210   PROPERTY(Property, IsAdded);
0211   PROPERTY(Property, IsMatched);
0212   PROPERTY(Property, IsMissing);
0213   PROPERTY(Property, IsMissingLink);
0214   PROPERTY(Property, IsInCompare);
0215   PROPERTY(Property, IsFileFromReference);
0216   PROPERTY(Property, IsLineFromReference);
0217   PROPERTY(Property, HasMoved);
0218   PROPERTY(Property, HasPattern);
0219   PROPERTY(Property, IsFinalized);
0220   PROPERTY(Property, IsReferenced);
0221   PROPERTY(Property, HasCodeViewLocation);
0222 
0223   // True if the scope has been named or typed or with line number.
0224   virtual bool isNamed() const { return false; }
0225   virtual bool isTyped() const { return false; }
0226   virtual bool isFiled() const { return false; }
0227   bool isLined() const { return LineNumber != 0; }
0228 
0229   // DWARF tag, attribute or expression opcode.
0230   dwarf::Tag getTag() const { return TagAttrOpcode.Tag; }
0231   void setTag(dwarf::Tag Tag) { TagAttrOpcode.Tag = Tag; }
0232   dwarf::Attribute getAttr() const { return TagAttrOpcode.Attr; }
0233   void setAttr(dwarf::Attribute Attr) { TagAttrOpcode.Attr = Attr; }
0234   LVSmall getOpcode() const { return TagAttrOpcode.Opcode; }
0235   void setOpcode(LVSmall Opcode) { TagAttrOpcode.Opcode = Opcode; }
0236 
0237   // DIE offset.
0238   LVOffset getOffset() const { return Offset; }
0239   void setOffset(LVOffset DieOffset) { Offset = DieOffset; }
0240 
0241   // Level where this object is located.
0242   LVLevel getLevel() const { return ScopeLevel; }
0243   void setLevel(LVLevel Level) { ScopeLevel = Level; }
0244 
0245   virtual StringRef getName() const { return StringRef(); }
0246   virtual void setName(StringRef ObjectName) {}
0247 
0248   LVElement *getParent() const {
0249     assert((!Parent.Element || static_cast<LVElement *>(Parent.Element)) &&
0250            "Invalid element");
0251     return Parent.Element;
0252   }
0253   LVScope *getParentScope() const {
0254     assert((!Parent.Scope || static_cast<LVScope *>(Parent.Scope)) &&
0255            "Invalid scope");
0256     return Parent.Scope;
0257   }
0258   LVSymbol *getParentSymbol() const {
0259     assert((!Parent.Symbol || static_cast<LVSymbol *>(Parent.Symbol)) &&
0260            "Invalid symbol");
0261     return Parent.Symbol;
0262   }
0263   void setParent(LVScope *Scope);
0264   void setParent(LVSymbol *Symbol);
0265   void resetParent() { Parent = {nullptr}; }
0266 
0267   virtual LVAddress getLowerAddress() const { return 0; }
0268   virtual void setLowerAddress(LVAddress Address) {}
0269   virtual LVAddress getUpperAddress() const { return 0; }
0270   virtual void setUpperAddress(LVAddress Address) {}
0271 
0272   uint32_t getLineNumber() const { return LineNumber; }
0273   void setLineNumber(uint32_t Number) { LineNumber = Number; }
0274 
0275   virtual const char *kind() const { return nullptr; }
0276 
0277   std::string indentAsString() const;
0278   std::string indentAsString(LVLevel Level) const;
0279 
0280   // String used as padding for printing objects with no line number.
0281   virtual std::string noLineAsString(bool ShowZero) const;
0282 
0283   // Line number for display; in the case of inlined functions, we use the
0284   // DW_AT_call_line attribute; otherwise use DW_AT_decl_line attribute.
0285   virtual std::string lineNumberAsString(bool ShowZero = false) const {
0286     return lineAsString(getLineNumber(), 0, ShowZero);
0287   }
0288   std::string lineNumberAsStringStripped(bool ShowZero = false) const;
0289 
0290   // This function prints the logical view to an output stream.
0291   // Split: Prints the compilation unit view to a file.
0292   // Match: Prints the object only if it satisfies the patterns collected
0293   // from the command line. See the '--select' option.
0294   // Print: Print the object only if satisfies the conditions specified by
0295   // the different '--print' options.
0296   // Full: Prints full information for objects representing debug locations,
0297   // aggregated scopes, compile unit, functions and namespaces.
0298   virtual Error doPrint(bool Split, bool Match, bool Print, raw_ostream &OS,
0299                         bool Full = true) const;
0300   void printAttributes(raw_ostream &OS, bool Full = true) const;
0301   void printAttributes(raw_ostream &OS, bool Full, StringRef Name,
0302                        LVObject *Parent, StringRef Value,
0303                        bool UseQuotes = false, bool PrintRef = false) const;
0304 
0305   // Mark branch as missing (current element and parents).
0306   void markBranchAsMissing();
0307 
0308   // Prints the common information for an object (name, type, etc).
0309   virtual void print(raw_ostream &OS, bool Full = true) const;
0310   // Prints additional information for an object, depending on its kind
0311   // (class attributes, debug ranges, files, directories, etc).
0312   virtual void printExtra(raw_ostream &OS, bool Full = true) const {}
0313 
0314 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
0315   virtual void dump() const { print(dbgs()); }
0316 #endif
0317 
0318   uint64_t getID() const {
0319     return
0320 #ifndef NDEBUG
0321         ID;
0322 #else
0323         0;
0324 #endif
0325   }
0326 };
0327 
0328 } // end namespace logicalview
0329 } // end namespace llvm
0330 
0331 #endif // LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVOBJECT_H