Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===-- LVObject.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 LVObject class, which is used to describe a debug
  10. // information object.
  11. //
  12. //===----------------------------------------------------------------------===//
  13.  
  14. #ifndef LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVOBJECT_H
  15. #define LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVOBJECT_H
  16.  
  17. #include "llvm/BinaryFormat/Dwarf.h"
  18. #include "llvm/DebugInfo/CodeView/CodeView.h"
  19. #include "llvm/DebugInfo/CodeView/TypeIndex.h"
  20. #include "llvm/DebugInfo/LogicalView/Core/LVSupport.h"
  21. #include <limits>
  22. #include <list>
  23. #include <map>
  24. #include <string>
  25.  
  26. namespace llvm {
  27. namespace dwarf {
  28. // Support for CodeView ModifierOptions::Unaligned.
  29. constexpr Tag DW_TAG_unaligned = Tag(dwarf::DW_TAG_hi_user + 1);
  30. } // namespace dwarf
  31. } // namespace llvm
  32.  
  33. namespace llvm {
  34. namespace logicalview {
  35.  
  36. using LVSectionIndex = uint64_t;
  37. using LVAddress = uint64_t;
  38. using LVHalf = uint16_t;
  39. using LVLevel = uint32_t;
  40. using LVOffset = uint64_t;
  41. using LVSigned = int64_t;
  42. using LVUnsigned = uint64_t;
  43. using LVSmall = uint8_t;
  44.  
  45. class LVElement;
  46. class LVLine;
  47. class LVLocation;
  48. class LVLocationSymbol;
  49. class LVObject;
  50. class LVOperation;
  51. class LVScope;
  52. class LVSymbol;
  53. class LVType;
  54.  
  55. class LVOptions;
  56. class LVPatterns;
  57.  
  58. StringRef typeNone();
  59. StringRef typeVoid();
  60. StringRef typeInt();
  61. StringRef typeUnknown();
  62. StringRef emptyString();
  63.  
  64. using LVElementSetFunction = void (LVElement::*)();
  65. using LVElementGetFunction = bool (LVElement::*)() const;
  66. using LVLineSetFunction = void (LVLine::*)();
  67. using LVLineGetFunction = bool (LVLine::*)() const;
  68. using LVObjectSetFunction = void (LVObject::*)();
  69. using LVObjectGetFunction = bool (LVObject::*)() const;
  70. using LVScopeSetFunction = void (LVScope::*)();
  71. using LVScopeGetFunction = bool (LVScope::*)() const;
  72. using LVSymbolSetFunction = void (LVSymbol::*)();
  73. using LVSymbolGetFunction = bool (LVSymbol::*)() const;
  74. using LVTypeSetFunction = void (LVType::*)();
  75. using LVTypeGetFunction = bool (LVType::*)() const;
  76.  
  77. // The LVScope class represents a logical scope and uses vectors to store its
  78. // children, which are pointers to other allocated logical elements (types,
  79. // symbols, lines, scopes, ranges). On destruction, we have to traverse each
  80. // vector and destroy its elements. The other case is LVSymbol.
  81. // These definitions are intended to be used by the LVScope and LVSymbol
  82. // to support automatic vector cleanup.
  83. using LVAutoLines = LVAutoSmallVector<LVLine *>;
  84. using LVAutoLocations = LVAutoSmallVector<LVLocation *>;
  85. using LVAutoOperations = LVAutoSmallVector<LVOperation *, 8>;
  86. using LVAutoScopes = LVAutoSmallVector<LVScope *>;
  87. using LVAutoSymbols = LVAutoSmallVector<LVSymbol *>;
  88. using LVAutoTypes = LVAutoSmallVector<LVType *>;
  89.  
  90. // These definitions are intended to be used when the vector will be used
  91. // just a container, with no automatic destruction.
  92. using LVElements = SmallVector<LVElement *, 8>;
  93. using LVLines = SmallVector<LVLine *, 8>;
  94. using LVLocations = SmallVector<LVLocation *, 8>;
  95. using LVOperations = SmallVector<LVOperation *, 8>;
  96. using LVScopes = SmallVector<LVScope *, 8>;
  97. using LVSymbols = SmallVector<LVSymbol *, 8>;
  98. using LVTypes = SmallVector<LVType *, 8>;
  99.  
  100. using LVOffsets = SmallVector<LVOffset, 8>;
  101.  
  102. const LVAddress MaxAddress = std::numeric_limits<uint64_t>::max();
  103.  
  104. enum class LVBinaryType { NONE, ELF, COFF };
  105. enum class LVComparePass { Missing, Added };
  106.  
  107. // Validate functions.
  108. using LVValidLocation = bool (LVLocation::*)();
  109.  
  110. // Keep counters of objects.
  111. struct LVCounter {
  112.   unsigned Lines = 0;
  113.   unsigned Scopes = 0;
  114.   unsigned Symbols = 0;
  115.   unsigned Types = 0;
  116.   void reset() {
  117.     Lines = 0;
  118.     Scopes = 0;
  119.     Symbols = 0;
  120.     Types = 0;
  121.   }
  122. };
  123.  
  124. class LVObject {
  125.   enum class Property {
  126.     IsLocation,          // Location.
  127.     IsGlobalReference,   // This object is being referenced from another CU.
  128.     IsGeneratedName,     // The Object name was generated.
  129.     IsResolved,          // Object has been resolved.
  130.     IsResolvedName,      // Object name has been resolved.
  131.     IsDiscarded,         // Object has been stripped by the linker.
  132.     IsOptimized,         // Object has been optimized by the compiler.
  133.     IsAdded,             // Object has been 'added'.
  134.     IsMatched,           // Object has been matched to a given pattern.
  135.     IsMissing,           // Object is 'missing'.
  136.     IsMissingLink,       // Object is indirectly 'missing'.
  137.     IsInCompare,         // In 'compare' mode.
  138.     IsFileFromReference, // File ID from specification.
  139.     IsLineFromReference, // Line No from specification.
  140.     HasMoved,            // The object was moved from 'target' to 'reference'.
  141.     HasPattern,          // The object has a pattern.
  142.     IsFinalized,         // CodeView object is finalized.
  143.     IsReferenced,        // CodeView object being referenced.
  144.     HasCodeViewLocation, // CodeView object with debug location.
  145.     LastEntry
  146.   };
  147.   // Typed bitvector with properties for this object.
  148.   LVProperties<Property> Properties;
  149.  
  150.   LVOffset Offset = 0;
  151.   uint32_t LineNumber = 0;
  152.   LVLevel ScopeLevel = 0;
  153.   union {
  154.     dwarf::Tag Tag;
  155.     dwarf::Attribute Attr;
  156.     LVSmall Opcode;
  157.   } TagAttrOpcode = {dwarf::DW_TAG_null};
  158.  
  159.   // The parent of this object (nullptr if the root scope). For locations,
  160.   // the parent is a symbol object; otherwise it is a scope object.
  161.   union {
  162.     LVElement *Element;
  163.     LVScope *Scope;
  164.     LVSymbol *Symbol;
  165.   } Parent = {nullptr};
  166.  
  167.   // We do not support any object duplication, as they are created by parsing
  168.   // the debug information. There is only the case where we need a very basic
  169.   // object, to manipulate its offset, line number and scope level. Allow the
  170.   // copy constructor to create that object; it is used to print a reference
  171.   // to another object and in the case of templates, to print its encoded args.
  172.   LVObject(const LVObject &Object) {
  173. #ifndef NDEBUG
  174.     incID();
  175. #endif
  176.     Properties = Object.Properties;
  177.     Offset = Object.Offset;
  178.     LineNumber = Object.LineNumber;
  179.     ScopeLevel = Object.ScopeLevel;
  180.     TagAttrOpcode = Object.TagAttrOpcode;
  181.     Parent = Object.Parent;
  182.   }
  183.  
  184. #ifndef NDEBUG
  185.   // This is an internal ID used for debugging logical elements. It is used
  186.   // for cases where an unique offset within the binary input file is not
  187.   // available.
  188.   static uint64_t GID;
  189.   uint64_t ID = 0;
  190.  
  191.   void incID() {
  192.     ++GID;
  193.     ID = GID;
  194.   }
  195. #endif
  196.  
  197. protected:
  198.   // Get a string representation for the given number and discriminator.
  199.   std::string lineAsString(uint32_t LineNumber, LVHalf Discriminator,
  200.                            bool ShowZero) const;
  201.  
  202.   // Get a string representation for the given number.
  203.   std::string referenceAsString(uint32_t LineNumber, bool Spaces) const;
  204.  
  205.   // Print the Filename or Pathname.
  206.   // Empty implementation for those objects that do not have any user
  207.   // source file references, such as debug locations.
  208.   virtual void printFileIndex(raw_ostream &OS, bool Full = true) const {}
  209.  
  210. public:
  211.   LVObject() {
  212. #ifndef NDEBUG
  213.     incID();
  214. #endif
  215.   };
  216.   LVObject &operator=(const LVObject &) = delete;
  217.   virtual ~LVObject() = default;
  218.  
  219.   PROPERTY(Property, IsLocation);
  220.   PROPERTY(Property, IsGlobalReference);
  221.   PROPERTY(Property, IsGeneratedName);
  222.   PROPERTY(Property, IsResolved);
  223.   PROPERTY(Property, IsResolvedName);
  224.   PROPERTY(Property, IsDiscarded);
  225.   PROPERTY(Property, IsOptimized);
  226.   PROPERTY(Property, IsAdded);
  227.   PROPERTY(Property, IsMatched);
  228.   PROPERTY(Property, IsMissing);
  229.   PROPERTY(Property, IsMissingLink);
  230.   PROPERTY(Property, IsInCompare);
  231.   PROPERTY(Property, IsFileFromReference);
  232.   PROPERTY(Property, IsLineFromReference);
  233.   PROPERTY(Property, HasMoved);
  234.   PROPERTY(Property, HasPattern);
  235.   PROPERTY(Property, IsFinalized);
  236.   PROPERTY(Property, IsReferenced);
  237.   PROPERTY(Property, HasCodeViewLocation);
  238.  
  239.   // True if the scope has been named or typed or with line number.
  240.   virtual bool isNamed() const { return false; }
  241.   virtual bool isTyped() const { return false; }
  242.   virtual bool isFiled() const { return false; }
  243.   bool isLined() const { return LineNumber != 0; }
  244.  
  245.   // DWARF tag, attribute or expression opcode.
  246.   dwarf::Tag getTag() const { return TagAttrOpcode.Tag; }
  247.   void setTag(dwarf::Tag Tag) { TagAttrOpcode.Tag = Tag; }
  248.   dwarf::Attribute getAttr() const { return TagAttrOpcode.Attr; }
  249.   void setAttr(dwarf::Attribute Attr) { TagAttrOpcode.Attr = Attr; }
  250.   LVSmall getOpcode() const { return TagAttrOpcode.Opcode; }
  251.   void setOpcode(LVSmall Opcode) { TagAttrOpcode.Opcode = Opcode; }
  252.  
  253.   // DIE offset.
  254.   LVOffset getOffset() const { return Offset; }
  255.   void setOffset(LVOffset DieOffset) { Offset = DieOffset; }
  256.  
  257.   // Level where this object is located.
  258.   LVLevel getLevel() const { return ScopeLevel; }
  259.   void setLevel(LVLevel Level) { ScopeLevel = Level; }
  260.  
  261.   virtual StringRef getName() const { return StringRef(); }
  262.   virtual void setName(StringRef ObjectName) {}
  263.  
  264.   LVElement *getParent() const {
  265.     assert((!Parent.Element ||
  266.             (Parent.Element && static_cast<LVElement *>(Parent.Element))) &&
  267.            "Invalid element");
  268.     return Parent.Element;
  269.   }
  270.   LVScope *getParentScope() const {
  271.     assert((!Parent.Scope ||
  272.             (Parent.Scope && static_cast<LVScope *>(Parent.Scope))) &&
  273.            "Invalid scope");
  274.     return Parent.Scope;
  275.   }
  276.   LVSymbol *getParentSymbol() const {
  277.     assert((!Parent.Symbol ||
  278.             (Parent.Symbol && static_cast<LVSymbol *>(Parent.Symbol))) &&
  279.            "Invalid symbol");
  280.     return Parent.Symbol;
  281.   }
  282.   void setParent(LVScope *Scope);
  283.   void setParent(LVSymbol *Symbol);
  284.   void resetParent() { Parent = {nullptr}; }
  285.  
  286.   virtual LVAddress getLowerAddress() const { return 0; }
  287.   virtual void setLowerAddress(LVAddress Address) {}
  288.   virtual LVAddress getUpperAddress() const { return 0; }
  289.   virtual void setUpperAddress(LVAddress Address) {}
  290.  
  291.   uint32_t getLineNumber() const { return LineNumber; }
  292.   void setLineNumber(uint32_t Number) { LineNumber = Number; }
  293.  
  294.   virtual const char *kind() const { return nullptr; }
  295.  
  296.   std::string indentAsString() const;
  297.   std::string indentAsString(LVLevel Level) const;
  298.  
  299.   // String used as padding for printing objects with no line number.
  300.   virtual std::string noLineAsString(bool ShowZero) const;
  301.  
  302.   // Line number for display; in the case of inlined functions, we use the
  303.   // DW_AT_call_line attribute; otherwise use DW_AT_decl_line attribute.
  304.   virtual std::string lineNumberAsString(bool ShowZero = false) const {
  305.     return lineAsString(getLineNumber(), 0, ShowZero);
  306.   }
  307.   std::string lineNumberAsStringStripped(bool ShowZero = false) const;
  308.  
  309.   // This function prints the logical view to an output stream.
  310.   // Split: Prints the compilation unit view to a file.
  311.   // Match: Prints the object only if it satisfies the patterns collected
  312.   // from the command line. See the '--select' option.
  313.   // Print: Print the object only if satisfies the conditions specified by
  314.   // the different '--print' options.
  315.   // Full: Prints full information for objects representing debug locations,
  316.   // aggregated scopes, compile unit, functions and namespaces.
  317.   virtual Error doPrint(bool Split, bool Match, bool Print, raw_ostream &OS,
  318.                         bool Full = true) const;
  319.   void printAttributes(raw_ostream &OS, bool Full = true) const;
  320.   void printAttributes(raw_ostream &OS, bool Full, StringRef Name,
  321.                        LVObject *Parent, StringRef Value,
  322.                        bool UseQuotes = false, bool PrintRef = false) const;
  323.  
  324.   // Mark branch as missing (current element and parents).
  325.   void markBranchAsMissing();
  326.  
  327.   // Prints the common information for an object (name, type, etc).
  328.   virtual void print(raw_ostream &OS, bool Full = true) const;
  329.   // Prints additional information for an object, depending on its kind
  330.   // (class attributes, debug ranges, files, directories, etc).
  331.   virtual void printExtra(raw_ostream &OS, bool Full = true) const {}
  332.  
  333. #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
  334.   virtual void dump() const { print(dbgs()); }
  335. #endif
  336.  
  337.   uint64_t getID() const {
  338.     return
  339. #ifndef NDEBUG
  340.         ID;
  341. #else
  342.         0;
  343. #endif
  344.   }
  345. };
  346.  
  347. } // end namespace logicalview
  348. } // end namespace llvm
  349.  
  350. #endif // LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVOBJECT_H
  351.