diff options
Diffstat (limited to 'contrib/llvm/include/llvm/CodeGen/DIE.h')
-rw-r--r-- | contrib/llvm/include/llvm/CodeGen/DIE.h | 342 |
1 files changed, 245 insertions, 97 deletions
diff --git a/contrib/llvm/include/llvm/CodeGen/DIE.h b/contrib/llvm/include/llvm/CodeGen/DIE.h index 7d6e66f..95c4b42 100644 --- a/contrib/llvm/include/llvm/CodeGen/DIE.h +++ b/contrib/llvm/include/llvm/CodeGen/DIE.h @@ -16,87 +16,108 @@ #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/PointerIntPair.h" -#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/iterator.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/CodeGen/DwarfStringPoolEntry.h" +#include "llvm/Support/AlignOf.h" +#include "llvm/Support/Allocator.h" #include "llvm/Support/Dwarf.h" +#include <cassert> +#include <cstddef> +#include <cstdint> +#include <iterator> +#include <new> +#include <type_traits> +#include <vector> namespace llvm { + class AsmPrinter; +class DIE; +class DIEUnit; class MCExpr; +class MCSection; class MCSymbol; class raw_ostream; -class DwarfTypeUnit; //===--------------------------------------------------------------------===// -/// DIEAbbrevData - Dwarf abbreviation data, describes one attribute of a -/// Dwarf abbreviation. +/// Dwarf abbreviation data, describes one attribute of a Dwarf abbreviation. class DIEAbbrevData { - /// Attribute - Dwarf attribute code. - /// + /// Dwarf attribute code. dwarf::Attribute Attribute; - /// Form - Dwarf form code. - /// + /// Dwarf form code. dwarf::Form Form; + /// Dwarf attribute value for DW_FORM_implicit_const + int64_t Value; + public: - DIEAbbrevData(dwarf::Attribute A, dwarf::Form F) : Attribute(A), Form(F) {} + DIEAbbrevData(dwarf::Attribute A, dwarf::Form F) + : Attribute(A), Form(F), Value(0) {} + DIEAbbrevData(dwarf::Attribute A, int64_t V) + : Attribute(A), Form(dwarf::DW_FORM_implicit_const), Value(V) {} - // Accessors. + /// Accessors. + /// @{ dwarf::Attribute getAttribute() const { return Attribute; } dwarf::Form getForm() const { return Form; } + int64_t getValue() const { return Value; } + /// @} - /// Profile - Used to gather unique data for the abbreviation folding set. - /// + /// Used to gather unique data for the abbreviation folding set. void Profile(FoldingSetNodeID &ID) const; }; //===--------------------------------------------------------------------===// -/// DIEAbbrev - Dwarf abbreviation, describes the organization of a debug -/// information object. +/// Dwarf abbreviation, describes the organization of a debug information +/// object. class DIEAbbrev : public FoldingSetNode { /// Unique number for node. - /// unsigned Number; - /// Tag - Dwarf tag code. - /// + /// Dwarf tag code. dwarf::Tag Tag; - /// Children - Whether or not this node has children. + /// Whether or not this node has children. /// - // This cheats a bit in all of the uses since the values in the standard - // are 0 and 1 for no children and children respectively. + /// This cheats a bit in all of the uses since the values in the standard + /// are 0 and 1 for no children and children respectively. bool Children; - /// Data - Raw data bytes for abbreviation. - /// + /// Raw data bytes for abbreviation. SmallVector<DIEAbbrevData, 12> Data; public: - DIEAbbrev(dwarf::Tag T, bool C) : Tag(T), Children(C), Data() {} + DIEAbbrev(dwarf::Tag T, bool C) : Tag(T), Children(C) {} - // Accessors. + /// Accessors. + /// @{ dwarf::Tag getTag() const { return Tag; } unsigned getNumber() const { return Number; } bool hasChildren() const { return Children; } const SmallVectorImpl<DIEAbbrevData> &getData() const { return Data; } void setChildrenFlag(bool hasChild) { Children = hasChild; } void setNumber(unsigned N) { Number = N; } + /// @} - /// AddAttribute - Adds another set of attribute information to the - /// abbreviation. + /// Adds another set of attribute information to the abbreviation. void AddAttribute(dwarf::Attribute Attribute, dwarf::Form Form) { Data.push_back(DIEAbbrevData(Attribute, Form)); } - /// Profile - Used to gather unique data for the abbreviation folding set. - /// + /// Adds attribute with DW_FORM_implicit_const value + void AddImplicitConstAttribute(dwarf::Attribute Attribute, int64_t Value) { + Data.push_back(DIEAbbrevData(Attribute, Value)); + } + + /// Used to gather unique data for the abbreviation folding set. void Profile(FoldingSetNodeID &ID) const; - /// Emit - Print the abbreviation using the specified asm printer. - /// + /// Print the abbreviation using the specified asm printer. void Emit(const AsmPrinter *AP) const; void print(raw_ostream &O); @@ -104,7 +125,38 @@ public: }; //===--------------------------------------------------------------------===// -/// DIEInteger - An integer value DIE. +/// Helps unique DIEAbbrev objects and assigns abbreviation numbers. +/// +/// This class will unique the DIE abbreviations for a llvm::DIE object and +/// assign a unique abbreviation number to each unique DIEAbbrev object it +/// finds. The resulting collection of DIEAbbrev objects can then be emitted +/// into the .debug_abbrev section. +class DIEAbbrevSet { + /// The bump allocator to use when creating DIEAbbrev objects in the uniqued + /// storage container. + BumpPtrAllocator &Alloc; + /// \brief FoldingSet that uniques the abbreviations. + llvm::FoldingSet<DIEAbbrev> AbbreviationsSet; + /// A list of all the unique abbreviations in use. + std::vector<DIEAbbrev *> Abbreviations; + +public: + DIEAbbrevSet(BumpPtrAllocator &A) : Alloc(A) {} + ~DIEAbbrevSet(); + /// Generate the abbreviation declaration for a DIE and return a pointer to + /// the generated abbreviation. + /// + /// \param Die the debug info entry to generate the abbreviation for. + /// \returns A reference to the uniqued abbreviation declaration that is + /// owned by this class. + DIEAbbrev &uniqueAbbreviation(DIE &Die); + + /// Print all abbreviations using the specified asm printer. + void Emit(const AsmPrinter *AP, MCSection *Section) const; +}; + +//===--------------------------------------------------------------------===// +/// An integer value DIE. /// class DIEInteger { uint64_t Integer; @@ -112,8 +164,7 @@ class DIEInteger { public: explicit DIEInteger(uint64_t I) : Integer(I) {} - /// BestForm - Choose the best form for integer. - /// + /// Choose the best form for integer. static dwarf::Form BestForm(bool IsSigned, uint64_t Int) { if (IsSigned) { const int64_t SignedInt = Int; @@ -144,16 +195,14 @@ public: }; //===--------------------------------------------------------------------===// -/// DIEExpr - An expression DIE. -// +/// An expression DIE. class DIEExpr { const MCExpr *Expr; public: explicit DIEExpr(const MCExpr *E) : Expr(E) {} - /// getValue - Get MCExpr. - /// + /// Get MCExpr. const MCExpr *getValue() const { return Expr; } void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; @@ -163,16 +212,14 @@ public: }; //===--------------------------------------------------------------------===// -/// DIELabel - A label DIE. -// +/// A label DIE. class DIELabel { const MCSymbol *Label; public: explicit DIELabel(const MCSymbol *L) : Label(L) {} - /// getValue - Get MCSymbol. - /// + /// Get MCSymbol. const MCSymbol *getValue() const { return Label; } void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; @@ -182,7 +229,7 @@ public: }; //===--------------------------------------------------------------------===// -/// DIEDelta - A simple label difference DIE. +/// A simple label difference DIE. /// class DIEDelta { const MCSymbol *LabelHi; @@ -198,15 +245,16 @@ public: }; //===--------------------------------------------------------------------===// -/// DIEString - A container for string values. +/// A container for string pool string values. /// +/// This class is used with the DW_FORM_strp and DW_FORM_GNU_str_index forms. class DIEString { DwarfStringPoolEntryRef S; public: DIEString(DwarfStringPoolEntryRef S) : S(S) {} - /// getString - Grab the string out of the object. + /// Grab the string out of the object. StringRef getString() const { return S.getString(); } void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; @@ -216,9 +264,31 @@ public: }; //===--------------------------------------------------------------------===// -/// DIEEntry - A pointer to another debug information entry. An instance of -/// this class can also be used as a proxy for a debug information entry not -/// yet defined (ie. types.) +/// A container for inline string values. +/// +/// This class is used with the DW_FORM_string form. +class DIEInlineString { + StringRef S; + +public: + template <typename Allocator> + explicit DIEInlineString(StringRef Str, Allocator &A) : S(Str.copy(A)) {} + + ~DIEInlineString() = default; + + /// Grab the string out of the object. + StringRef getString() const { return S; } + + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; + + void print(raw_ostream &O) const; +}; + +//===--------------------------------------------------------------------===// +/// A pointer to another debug information entry. An instance of this class can +/// also be used as a proxy for a debug information entry not yet defined +/// (ie. types.) class DIE; class DIEEntry { DIE *Entry; @@ -230,30 +300,23 @@ public: DIE &getEntry() const { return *Entry; } - /// Returns size of a ref_addr entry. - static unsigned getRefAddrSize(const AsmPrinter *AP); - void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; - unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const { - return Form == dwarf::DW_FORM_ref_addr ? getRefAddrSize(AP) - : sizeof(int32_t); - } + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; void print(raw_ostream &O) const; }; //===--------------------------------------------------------------------===// -/// DIELocList - Represents a pointer to a location list in the debug_loc +/// Represents a pointer to a location list in the debug_loc /// section. -// class DIELocList { - // Index into the .debug_loc vector. + /// Index into the .debug_loc vector. size_t Index; public: DIELocList(size_t I) : Index(I) {} - /// getValue - Grab the current index out. + /// Grab the current index out. size_t getValue() const { return Index; } void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; @@ -263,9 +326,8 @@ public: }; //===--------------------------------------------------------------------===// -/// DIEValue - A debug information entry value. Some of these roughly correlate +/// A debug information entry value. Some of these roughly correlate /// to DWARF attribute classes. -/// class DIEBlock; class DIELoc; class DIEValue { @@ -277,8 +339,7 @@ public: }; private: - /// Ty - Type of data stored in the value. - /// + /// Type of data stored in the value. Type Ty = isNone; dwarf::Attribute Attribute = (dwarf::Attribute)0; dwarf::Form Form = (dwarf::Form)0; @@ -355,9 +416,11 @@ private: public: DIEValue() = default; + DIEValue(const DIEValue &X) : Ty(X.Ty), Attribute(X.Attribute), Form(X.Form) { copyVal(X); } + DIEValue &operator=(const DIEValue &X) { destroyVal(); Ty = X.Ty; @@ -366,6 +429,7 @@ public: copyVal(X); return *this; } + ~DIEValue() { destroyVal(); } #define HANDLE_DIEVALUE_SMALL(T) \ @@ -381,11 +445,13 @@ public: } #include "llvm/CodeGen/DIEValue.def" - // Accessors + /// Accessors. + /// @{ Type getType() const { return Ty; } dwarf::Attribute getAttribute() const { return Attribute; } dwarf::Form getForm() const { return Form; } explicit operator bool() const { return Ty; } + /// @} #define HANDLE_DIEVALUE_SMALL(T) \ const DIE##T &getDIE##T() const { \ @@ -399,12 +465,10 @@ public: } #include "llvm/CodeGen/DIEValue.def" - /// EmitValue - Emit value via the Dwarf writer. - /// + /// Emit value via the Dwarf writer. void EmitValue(const AsmPrinter *AP) const; - /// SizeOf - Return the size of a value in bytes. - /// + /// Return the size of a value in bytes. unsigned SizeOf(const AsmPrinter *AP) const; void print(raw_ostream &O) const; @@ -413,6 +477,7 @@ public: struct IntrusiveBackListNode { PointerIntPair<IntrusiveBackListNode *, 1> Next; + IntrusiveBackListNode() : Next(this, true) {} IntrusiveBackListNode *getNext() const { @@ -576,54 +641,60 @@ public: } value_range values() { - return llvm::make_range(value_iterator(List.begin()), - value_iterator(List.end())); + return make_range(value_iterator(List.begin()), value_iterator(List.end())); } const_value_range values() const { - return llvm::make_range(const_value_iterator(List.begin()), - const_value_iterator(List.end())); + return make_range(const_value_iterator(List.begin()), + const_value_iterator(List.end())); } }; //===--------------------------------------------------------------------===// -/// DIE - A structured debug information entry. Has an abbreviation which +/// A structured debug information entry. Has an abbreviation which /// describes its organization. class DIE : IntrusiveBackListNode, public DIEValueList { friend class IntrusiveBackList<DIE>; + friend class DIEUnit; - /// Offset - Offset in debug info section. - /// + /// Dwarf unit relative offset. unsigned Offset; - - /// Size - Size of instance + children. - /// + /// Size of instance + children. unsigned Size; - unsigned AbbrevNumber = ~0u; - - /// Tag - Dwarf tag code. - /// + /// Dwarf tag code. dwarf::Tag Tag = (dwarf::Tag)0; - + /// Set to true to force a DIE to emit an abbreviation that says it has + /// children even when it doesn't. This is used for unit testing purposes. + bool ForceChildren; /// Children DIEs. IntrusiveBackList<DIE> Children; - DIE *Parent = nullptr; + /// The owner is either the parent DIE for children of other DIEs, or a + /// DIEUnit which contains this DIE as its unit DIE. + PointerUnion<DIE *, DIEUnit *> Owner; DIE() = delete; - explicit DIE(dwarf::Tag Tag) : Offset(0), Size(0), Tag(Tag) {} + explicit DIE(dwarf::Tag Tag) : Offset(0), Size(0), Tag(Tag), + ForceChildren(false) {} public: static DIE *get(BumpPtrAllocator &Alloc, dwarf::Tag Tag) { return new (Alloc) DIE(Tag); } + DIE(const DIE &RHS) = delete; + DIE(DIE &&RHS) = delete; + void operator=(const DIE &RHS) = delete; + void operator=(const DIE &&RHS) = delete; + // Accessors. unsigned getAbbrevNumber() const { return AbbrevNumber; } dwarf::Tag getTag() const { return Tag; } + /// Get the compile/type unit relative offset of this DIE. unsigned getOffset() const { return Offset; } unsigned getSize() const { return Size; } - bool hasChildren() const { return !Children.empty(); } + bool hasChildren() const { return ForceChildren || !Children.empty(); } + void setForceChildren(bool B) { ForceChildren = B; } typedef IntrusiveBackList<DIE>::iterator child_iterator; typedef IntrusiveBackList<DIE>::const_iterator const_child_iterator; @@ -631,13 +702,13 @@ public: typedef iterator_range<const_child_iterator> const_child_range; child_range children() { - return llvm::make_range(Children.begin(), Children.end()); + return make_range(Children.begin(), Children.end()); } const_child_range children() const { - return llvm::make_range(Children.begin(), Children.end()); + return make_range(Children.begin(), Children.end()); } - DIE *getParent() const { return Parent; } + DIE *getParent() const; /// Generate the abbreviation for this DIE. /// @@ -648,19 +719,50 @@ public: /// Set the abbreviation number for this DIE. void setAbbrevNumber(unsigned I) { AbbrevNumber = I; } - /// Climb up the parent chain to get the compile or type unit DIE this DIE - /// belongs to. - const DIE *getUnit() const; - /// Similar to getUnit, returns null when DIE is not added to an - /// owner yet. - const DIE *getUnitOrNull() const; + /// Get the absolute offset within the .debug_info or .debug_types section + /// for this DIE. + unsigned getDebugSectionOffset() const; + + /// Compute the offset of this DIE and all its children. + /// + /// This function gets called just before we are going to generate the debug + /// information and gives each DIE a chance to figure out its CU relative DIE + /// offset, unique its abbreviation and fill in the abbreviation code, and + /// return the unit offset that points to where the next DIE will be emitted + /// within the debug unit section. After this function has been called for all + /// DIE objects, the DWARF can be generated since all DIEs will be able to + /// properly refer to other DIE objects since all DIEs have calculated their + /// offsets. + /// + /// \param AP AsmPrinter to use when calculating sizes. + /// \param AbbrevSet the abbreviation used to unique DIE abbreviations. + /// \param CUOffset the compile/type unit relative offset in bytes. + /// \returns the offset for the DIE that follows this DIE within the + /// current compile/type unit. + unsigned computeOffsetsAndAbbrevs(const AsmPrinter *AP, + DIEAbbrevSet &AbbrevSet, unsigned CUOffset); + + /// Climb up the parent chain to get the compile unit or type unit DIE that + /// this DIE belongs to. + /// + /// \returns the compile or type unit DIE that owns this DIE, or NULL if + /// this DIE hasn't been added to a unit DIE. + const DIE *getUnitDie() const; + + /// Climb up the parent chain to get the compile unit or type unit that this + /// DIE belongs to. + /// + /// \returns the DIEUnit that represents the compile or type unit that owns + /// this DIE, or NULL if this DIE hasn't been added to a unit DIE. + const DIEUnit *getUnit() const; + void setOffset(unsigned O) { Offset = O; } void setSize(unsigned S) { Size = S; } /// Add a child to the DIE. DIE &addChild(DIE *Child) { assert(!Child->getParent() && "Child should be orphaned"); - Child->Parent = this; + Child->Owner = this; Children.push_back(*Child); return Children.back(); } @@ -676,6 +778,52 @@ public: }; //===--------------------------------------------------------------------===// +/// Represents a compile or type unit. +class DIEUnit { + /// The compile unit or type unit DIE. This variable must be an instance of + /// DIE so that we can calculate the DIEUnit from any DIE by traversing the + /// parent backchain and getting the Unit DIE, and then casting itself to a + /// DIEUnit. This allows us to be able to find the DIEUnit for any DIE without + /// having to store a pointer to the DIEUnit in each DIE instance. + DIE Die; + /// The section this unit will be emitted in. This may or may not be set to + /// a valid section depending on the client that is emitting DWARF. + MCSection *Section; + uint64_t Offset; /// .debug_info or .debug_types absolute section offset. + uint32_t Length; /// The length in bytes of all of the DIEs in this unit. + const uint16_t Version; /// The Dwarf version number for this unit. + const uint8_t AddrSize; /// The size in bytes of an address for this unit. +public: + DIEUnit(uint16_t Version, uint8_t AddrSize, dwarf::Tag UnitTag); + DIEUnit(const DIEUnit &RHS) = delete; + DIEUnit(DIEUnit &&RHS) = delete; + void operator=(const DIEUnit &RHS) = delete; + void operator=(const DIEUnit &&RHS) = delete; + /// Set the section that this DIEUnit will be emitted into. + /// + /// This function is used by some clients to set the section. Not all clients + /// that emit DWARF use this section variable. + void setSection(MCSection *Section) { + assert(!this->Section); + this->Section = Section; + } + + /// Return the section that this DIEUnit will be emitted into. + /// + /// \returns Section pointer which can be NULL. + MCSection *getSection() const { return Section; } + void setDebugSectionOffset(unsigned O) { Offset = O; } + unsigned getDebugSectionOffset() const { return Offset; } + void setLength(uint64_t L) { Length = L; } + uint64_t getLength() const { return Length; } + uint16_t getDwarfVersion() const { return Version; } + uint16_t getAddressSize() const { return AddrSize; } + DIE &getUnitDie() { return Die; } + const DIE &getUnitDie() const { return Die; } +}; + + +//===--------------------------------------------------------------------===// /// DIELoc - Represents an expression location. // class DIELoc : public DIEValueList { @@ -740,6 +888,6 @@ public: void print(raw_ostream &O) const; }; -} // end llvm namespace +} // end namespace llvm -#endif +#endif // LLVM_LIB_CODEGEN_ASMPRINTER_DIE_H |