diff options
Diffstat (limited to 'lib/CodeGen/AsmPrinter/DwarfDebug.h')
| -rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfDebug.h | 605 | 
1 files changed, 271 insertions, 334 deletions
| diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h index cebac39a19b0..f2aa80845a05 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -14,44 +14,50 @@  #ifndef CODEGEN_ASMPRINTER_DWARFDEBUG_H__  #define CODEGEN_ASMPRINTER_DWARFDEBUG_H__ +#include "DwarfFile.h" +#include "AsmPrinterHandler.h"  #include "DIE.h" +#include "DbgValueHistoryCalculator.h" +#include "DebugLocEntry.h" +#include "DebugLocList.h" +#include "DwarfAccelTable.h"  #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/FoldingSet.h" -#include "llvm/ADT/SetVector.h" +#include "llvm/ADT/MapVector.h"  #include "llvm/ADT/SmallPtrSet.h"  #include "llvm/ADT/StringMap.h" -#include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/ADT/FoldingSet.h"  #include "llvm/CodeGen/LexicalScopes.h" -#include "llvm/DebugInfo.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/IR/DebugInfo.h" +#include "llvm/IR/DebugLoc.h"  #include "llvm/MC/MachineLocation.h" +#include "llvm/MC/MCDwarf.h"  #include "llvm/Support/Allocator.h" -#include "llvm/Support/DebugLoc.h" + +#include <memory>  namespace llvm { -class CompileUnit; +class AsmPrinter; +class ByteStreamer;  class ConstantInt;  class ConstantFP; -class DbgVariable; -class MachineFrameInfo; +class DwarfCompileUnit; +class DwarfDebug; +class DwarfTypeUnit; +class DwarfUnit;  class MachineModuleInfo; -class MachineOperand; -class MCAsmInfo; -class DIEAbbrev; -class DIE; -class DIEBlock; -class DIEEntry;  //===----------------------------------------------------------------------===//  /// \brief This class is used to record source line correspondence.  class SrcLineInfo { -  unsigned Line;                     // Source line number. -  unsigned Column;                   // Source column. -  unsigned SourceID;                 // Source ID number. -  MCSymbol *Label;                   // Label in code ID number. +  unsigned Line;     // Source line number. +  unsigned Column;   // Source column. +  unsigned SourceID; // Source ID number. +  MCSymbol *Label;   // Label in code ID number.  public:    SrcLineInfo(unsigned L, unsigned C, unsigned S, MCSymbol *label) -    : Line(L), Column(C), SourceID(S), Label(label) {} +      : Line(L), Column(C), SourceID(S), Label(label) {}    // Accessors    unsigned getLine() const { return Line; } @@ -60,124 +66,47 @@ public:    MCSymbol *getLabel() const { return Label; }  }; -/// \brief This struct describes location entries emitted in the .debug_loc -/// section. -class DotDebugLocEntry { -  // Begin and end symbols for the address range that this location is valid. -  const MCSymbol *Begin; -  const MCSymbol *End; - -  // Type of entry that this represents. -  enum EntryType { -    E_Location, -    E_Integer, -    E_ConstantFP, -    E_ConstantInt -  }; -  enum EntryType EntryKind; - -  union { -    int64_t Int; -    const ConstantFP *CFP; -    const ConstantInt *CIP; -  } Constants; - -  // The location in the machine frame. -  MachineLocation Loc; - -  // The variable to which this location entry corresponds. -  const MDNode *Variable; - -  // Whether this location has been merged. -  bool Merged; - -public: -  DotDebugLocEntry() : Begin(0), End(0), Variable(0), Merged(false) { -    Constants.Int = 0; -  } -  DotDebugLocEntry(const MCSymbol *B, const MCSymbol *E, MachineLocation &L, -                   const MDNode *V) -      : Begin(B), End(E), Loc(L), Variable(V), Merged(false) { -    Constants.Int = 0; -    EntryKind = E_Location; -  } -  DotDebugLocEntry(const MCSymbol *B, const MCSymbol *E, int64_t i) -      : Begin(B), End(E), Variable(0), Merged(false) { -    Constants.Int = i; -    EntryKind = E_Integer; -  } -  DotDebugLocEntry(const MCSymbol *B, const MCSymbol *E, const ConstantFP *FPtr) -      : Begin(B), End(E), Variable(0), Merged(false) { -    Constants.CFP = FPtr; -    EntryKind = E_ConstantFP; -  } -  DotDebugLocEntry(const MCSymbol *B, const MCSymbol *E, -                   const ConstantInt *IPtr) -      : Begin(B), End(E), Variable(0), Merged(false) { -    Constants.CIP = IPtr; -    EntryKind = E_ConstantInt; -  } - -  /// \brief Empty entries are also used as a trigger to emit temp label. Such -  /// labels are referenced is used to find debug_loc offset for a given DIE. -  bool isEmpty() { return Begin == 0 && End == 0; } -  bool isMerged() { return Merged; } -  void Merge(DotDebugLocEntry *Next) { -    if (!(Begin && Loc == Next->Loc && End == Next->Begin)) -      return; -    Next->Begin = Begin; -    Merged = true; -  } -  bool isLocation() const    { return EntryKind == E_Location; } -  bool isInt() const         { return EntryKind == E_Integer; } -  bool isConstantFP() const  { return EntryKind == E_ConstantFP; } -  bool isConstantInt() const { return EntryKind == E_ConstantInt; } -  int64_t getInt() const                    { return Constants.Int; } -  const ConstantFP *getConstantFP() const   { return Constants.CFP; } -  const ConstantInt *getConstantInt() const { return Constants.CIP; } -  const MDNode *getVariable() const { return Variable; } -  const MCSymbol *getBeginSym() const { return Begin; } -  const MCSymbol *getEndSym() const { return End; } -  MachineLocation getLoc() const { return Loc; } -}; -  //===----------------------------------------------------------------------===//  /// \brief This class is used to track local variable information.  class DbgVariable { -  DIVariable Var;                    // Variable Descriptor. -  DIE *TheDIE;                       // Variable DIE. -  unsigned DotDebugLocOffset;        // Offset in DotDebugLocEntries. -  DbgVariable *AbsVar;               // Corresponding Abstract variable, if any. -  const MachineInstr *MInsn;         // DBG_VALUE instruction of the variable. +  DIVariable Var;             // Variable Descriptor. +  DIE *TheDIE;                // Variable DIE. +  unsigned DotDebugLocOffset; // Offset in DotDebugLocEntries. +  const MachineInstr *MInsn;  // DBG_VALUE instruction of the variable.    int FrameIndex;    DwarfDebug *DD; +  public: -  // AbsVar may be NULL. -  DbgVariable(DIVariable V, DbgVariable *AV, DwarfDebug *DD) -    : Var(V), TheDIE(0), DotDebugLocOffset(~0U), AbsVar(AV), MInsn(0), -      FrameIndex(~0), DD(DD) {} +  /// Construct a DbgVariable from a DIVariable. +  DbgVariable(DIVariable V, DwarfDebug *DD) +      : Var(V), TheDIE(nullptr), DotDebugLocOffset(~0U), MInsn(nullptr), +        FrameIndex(~0), DD(DD) {} + +  /// Construct a DbgVariable from a DEBUG_VALUE. +  /// AbstractVar may be NULL. +  DbgVariable(const MachineInstr *DbgValue, DwarfDebug *DD) +      : Var(DbgValue->getDebugVariable()), TheDIE(nullptr), +        DotDebugLocOffset(~0U), MInsn(DbgValue), FrameIndex(~0), DD(DD) {}    // Accessors. -  DIVariable getVariable()           const { return Var; } -  void setDIE(DIE *D)                      { TheDIE = D; } -  DIE *getDIE()                      const { return TheDIE; } -  void setDotDebugLocOffset(unsigned O)    { DotDebugLocOffset = O; } -  unsigned getDotDebugLocOffset()    const { return DotDebugLocOffset; } -  StringRef getName()                const { return Var.getName(); } -  DbgVariable *getAbstractVariable() const { return AbsVar; } -  const MachineInstr *getMInsn()     const { return MInsn; } -  void setMInsn(const MachineInstr *M)     { MInsn = M; } -  int getFrameIndex()                const { return FrameIndex; } -  void setFrameIndex(int FI)               { FrameIndex = FI; } +  DIVariable getVariable() const { return Var; } +  void setDIE(DIE &D) { TheDIE = &D; } +  DIE *getDIE() const { return TheDIE; } +  void setDotDebugLocOffset(unsigned O) { DotDebugLocOffset = O; } +  unsigned getDotDebugLocOffset() const { return DotDebugLocOffset; } +  StringRef getName() const { return Var.getName(); } +  const MachineInstr *getMInsn() const { return MInsn; } +  int getFrameIndex() const { return FrameIndex; } +  void setFrameIndex(int FI) { FrameIndex = FI; }    // Translate tag to proper Dwarf tag. -  uint16_t getTag()                  const { +  dwarf::Tag getTag() const {      if (Var.getTag() == dwarf::DW_TAG_arg_variable)        return dwarf::DW_TAG_formal_parameter;      return dwarf::DW_TAG_variable;    }    /// \brief Return true if DbgVariable is artificial. -  bool isArtificial()                const { +  bool isArtificial() const {      if (Var.isArtificial())        return true;      if (getType().isArtificial()) @@ -185,7 +114,7 @@ public:      return false;    } -  bool isObjectPointer()             const { +  bool isObjectPointer() const {      if (Var.isObjectPointer())        return true;      if (getType().isObjectPointer()) @@ -193,21 +122,16 @@ public:      return false;    } -  bool variableHasComplexAddress()   const { +  bool variableHasComplexAddress() const {      assert(Var.isVariable() && "Invalid complex DbgVariable!");      return Var.hasComplexAddress();    } -  bool isBlockByrefVariable()        const { -    assert(Var.isVariable() && "Invalid complex DbgVariable!"); -    return Var.isBlockByrefVariable(); -  } -  unsigned getNumAddrElements()      const { +  bool isBlockByrefVariable() const; +  unsigned getNumAddrElements() const {      assert(Var.isVariable() && "Invalid complex DbgVariable!");      return Var.getNumAddrElements();    } -  uint64_t getAddrElement(unsigned i) const { -    return Var.getAddrElement(i); -  } +  uint64_t getAddrElement(unsigned i) const { return Var.getAddrElement(i); }    DIType getType() const;  private: @@ -216,101 +140,16 @@ private:    template <typename T> T resolve(DIRef<T> Ref) const;  }; -/// \brief Collects and handles information specific to a particular -/// collection of units. -class DwarfUnits { -  // Target of Dwarf emission, used for sizing of abbreviations. -  AsmPrinter *Asm; - -  // Used to uniquely define abbreviations. -  FoldingSet<DIEAbbrev> *AbbreviationsSet; - -  // A list of all the unique abbreviations in use. -  std::vector<DIEAbbrev *> &Abbreviations; - -  // A pointer to all units in the section. -  SmallVector<CompileUnit *, 1> CUs; - -  // Collection of strings for this unit and assorted symbols. -  // A String->Symbol mapping of strings used by indirect -  // references. -  typedef StringMap<std::pair<MCSymbol*, unsigned>, -                    BumpPtrAllocator&> StrPool; -  StrPool StringPool; -  unsigned NextStringPoolNumber; -  std::string StringPref; - -  // Collection of addresses for this unit and assorted labels. -  // A Symbol->unsigned mapping of addresses used by indirect -  // references. -  typedef DenseMap<const MCExpr *, unsigned> AddrPool; -  AddrPool AddressPool; -  unsigned NextAddrPoolNumber; - -public: -  DwarfUnits(AsmPrinter *AP, FoldingSet<DIEAbbrev> *AS, -             std::vector<DIEAbbrev *> &A, const char *Pref, -             BumpPtrAllocator &DA) -      : Asm(AP), AbbreviationsSet(AS), Abbreviations(A), StringPool(DA), -        NextStringPoolNumber(0), StringPref(Pref), AddressPool(), -        NextAddrPoolNumber(0) {} - -  /// \brief Compute the size and offset of a DIE given an incoming Offset. -  unsigned computeSizeAndOffset(DIE *Die, unsigned Offset); - -  /// \brief Compute the size and offset of all the DIEs. -  void computeSizeAndOffsets(); - -  /// \brief Define a unique number for the abbreviation. -  void assignAbbrevNumber(DIEAbbrev &Abbrev); - -  /// \brief Add a unit to the list of CUs. -  void addUnit(CompileUnit *CU) { CUs.push_back(CU); } - -  /// \brief Emit all of the units to the section listed with the given -  /// abbreviation section. -  void emitUnits(DwarfDebug *DD, const MCSection *USection, -                 const MCSection *ASection, const MCSymbol *ASectionSym); - -  /// \brief Emit all of the strings to the section given. -  void emitStrings(const MCSection *StrSection, const MCSection *OffsetSection, -                   const MCSymbol *StrSecSym); - -  /// \brief Emit all of the addresses to the section given. -  void emitAddresses(const MCSection *AddrSection); - -  /// \brief Returns the entry into the start of the pool. -  MCSymbol *getStringPoolSym(); - -  /// \brief Returns an entry into the string pool with the given -  /// string text. -  MCSymbol *getStringPoolEntry(StringRef Str); - -  /// \brief Returns the index into the string pool with the given -  /// string text. -  unsigned getStringPoolIndex(StringRef Str); - -  /// \brief Returns the string pool. -  StrPool *getStringPool() { return &StringPool; } - -  /// \brief Returns the index into the address pool with the given -  /// label/symbol. -  unsigned getAddrPoolIndex(const MCExpr *Sym); -  unsigned getAddrPoolIndex(const MCSymbol *Sym); - -  /// \brief Returns the address pool. -  AddrPool *getAddrPool() { return &AddressPool; } -};  /// \brief Helper used to pair up a symbol and its DWARF compile unit.  struct SymbolCU { -  SymbolCU(CompileUnit *CU, const MCSymbol *Sym) : Sym(Sym), CU(CU) {} +  SymbolCU(DwarfCompileUnit *CU, const MCSymbol *Sym) : Sym(Sym), CU(CU) {}    const MCSymbol *Sym; -  CompileUnit *CU; +  DwarfCompileUnit *CU;  };  /// \brief Collects and handles dwarf debug information. -class DwarfDebug { +class DwarfDebug : public AsmPrinterHandler {    // Target of Dwarf emission.    AsmPrinter *Asm; @@ -320,40 +159,31 @@ class DwarfDebug {    // All DIEValues are allocated through this allocator.    BumpPtrAllocator DIEValueAllocator; -  // Handle to the a compile unit used for the inline extension handling. -  CompileUnit *FirstCU; +  // Handle to the compile unit used for the inline extension handling, +  // this is just so that the DIEValue allocator has a place to store +  // the particular elements. +  // FIXME: Store these off of DwarfDebug instead? +  DwarfCompileUnit *FirstCU; -  // Maps MDNode with its corresponding CompileUnit. -  DenseMap <const MDNode *, CompileUnit *> CUMap; +  // Maps MDNode with its corresponding DwarfCompileUnit. +  MapVector<const MDNode *, DwarfCompileUnit *> CUMap; -  // Maps subprogram MDNode with its corresponding CompileUnit. -  DenseMap <const MDNode *, CompileUnit *> SPMap; +  // Maps subprogram MDNode with its corresponding DwarfCompileUnit. +  DenseMap<const MDNode *, DwarfCompileUnit *> SPMap; -  // Maps a CU DIE with its corresponding CompileUnit. -  DenseMap <const DIE *, CompileUnit *> CUDieMap; +  // Maps a CU DIE with its corresponding DwarfCompileUnit. +  DenseMap<const DIE *, DwarfCompileUnit *> CUDieMap; -  /// Maps MDNodes for type sysstem with the corresponding DIEs. These DIEs can +  /// Maps MDNodes for type system with the corresponding DIEs. These DIEs can    /// be shared across CUs, that is why we keep the map here instead -  /// of in CompileUnit. +  /// of in DwarfCompileUnit.    DenseMap<const MDNode *, DIE *> MDTypeNodeToDieMap; -  // Used to uniquely define abbreviations. -  FoldingSet<DIEAbbrev> AbbreviationsSet; - -  // A list of all the unique abbreviations in use. -  std::vector<DIEAbbrev *> Abbreviations; - -  // Stores the current file ID for a given compile unit. -  DenseMap <unsigned, unsigned> FileIDCUMap; -  // Source id map, i.e. CUID, source filename and directory, -  // separated by a zero byte, mapped to a unique id. -  StringMap<unsigned, BumpPtrAllocator&> SourceIdMap; -    // List of all labels used in aranges generation.    std::vector<SymbolCU> ArangeLabels;    // Size of each symbol emitted (for those symbols that have a specific size). -  DenseMap <const MCSymbol *, uint64_t> SymSize; +  DenseMap<const MCSymbol *, uint64_t> SymSize;    // Provides a unique id per text section.    typedef DenseMap<const MCSection *, SmallVector<SymbolCU, 8> > SectionMapType; @@ -368,15 +198,17 @@ class DwarfDebug {    DenseMap<const MDNode *, DIE *> AbstractSPDies;    // Collection of dbg variables of a scope. -  typedef DenseMap<LexicalScope *, -                   SmallVector<DbgVariable *, 8> > ScopeVariablesMap; +  typedef DenseMap<LexicalScope *, SmallVector<DbgVariable *, 8> > +  ScopeVariablesMap;    ScopeVariablesMap ScopeVariables;    // Collection of abstract variables. -  DenseMap<const MDNode *, DbgVariable *> AbstractVariables; +  DenseMap<const MDNode *, std::unique_ptr<DbgVariable>> AbstractVariables; +  SmallVector<std::unique_ptr<DbgVariable>, 64> ConcreteVariables; -  // Collection of DotDebugLocEntry. -  SmallVector<DotDebugLocEntry, 4> DotDebugLocEntries; +  // Collection of DebugLocEntry. Stored in a linked list so that DIELocLists +  // can refer to them in spite of insertions into this list. +  SmallVector<DebugLocList, 4> DotDebugLocEntries;    // Collection of subprogram DIEs that are marked (at the end of the module)    // as DW_AT_inline. @@ -392,19 +224,10 @@ class DwarfDebug {    // Maps instruction with label emitted after instruction.    DenseMap<const MachineInstr *, MCSymbol *> LabelsAfterInsn; -  // Every user variable mentioned by a DBG_VALUE instruction in order of -  // appearance. -  SmallVector<const MDNode*, 8> UserVariables; - -  // For each user variable, keep a list of DBG_VALUE instructions in order. -  // The list can also contain normal instructions that clobber the previous -  // DBG_VALUE. -  typedef DenseMap<const MDNode*, SmallVector<const MachineInstr*, 4> > -    DbgValueHistoryMap; +  // History of DBG_VALUE and clobber instructions for each user variable. +  // Variables are listed in order of appearance.    DbgValueHistoryMap DbgValues; -  SmallVector<const MCSymbol *, 8> DebugRangeSymbols; -    // Previous instruction's location information. This is used to determine    // label location to indicate scope boundries in dwarf debug info.    DebugLoc PrevInstLoc; @@ -414,6 +237,19 @@ class DwarfDebug {    // body.    DebugLoc PrologEndLoc; +  // If nonnull, stores the current machine function we're processing. +  const MachineFunction *CurFn; + +  // If nonnull, stores the current machine instruction we're processing. +  const MachineInstr *CurMI; + +  // If nonnull, stores the section that the previous function was allocated to +  // emitting. +  const MCSection *PrevSection; + +  // If nonnull, stores the CU in which the previous subprogram was contained. +  const DwarfCompileUnit *PrevCU; +    // Section Symbols: these are assembler temporary labels that are emitted at    // the beginning of each supported dwarf section.  These are used to form    // section offsets and are created by EmitSectionLabels. @@ -421,36 +257,50 @@ class DwarfDebug {    MCSymbol *DwarfStrSectionSym, *TextSectionSym, *DwarfDebugRangeSectionSym;    MCSymbol *DwarfDebugLocSectionSym, *DwarfLineSectionSym, *DwarfAddrSectionSym;    MCSymbol *FunctionBeginSym, *FunctionEndSym; -  MCSymbol *DwarfAbbrevDWOSectionSym, *DwarfStrDWOSectionSym; +  MCSymbol *DwarfInfoDWOSectionSym, *DwarfAbbrevDWOSectionSym; +  MCSymbol *DwarfStrDWOSectionSym;    MCSymbol *DwarfGnuPubNamesSectionSym, *DwarfGnuPubTypesSectionSym;    // As an optimization, there is no need to emit an entry in the directory    // table for the same directory as DW_AT_comp_dir.    StringRef CompilationDir; -  // Counter for assigning globally unique IDs for CUs. -  unsigned GlobalCUIndexCount; +  // Counter for assigning globally unique IDs for ranges. +  unsigned GlobalRangeCount;    // Holder for the file specific debug information. -  DwarfUnits InfoHolder; +  DwarfFile InfoHolder;    // Holders for the various debug information flags that we might need to    // have exposed. See accessor functions below for description.    // Holder for imported entities.    typedef SmallVector<std::pair<const MDNode *, const MDNode *>, 32> -    ImportedEntityMap; +  ImportedEntityMap;    ImportedEntityMap ScopesWithImportedEntities; -  // Holder for types that are going to be extracted out into a type unit. -  std::vector<DIE *> TypeUnits; +  // Map from MDNodes for user-defined types to the type units that describe +  // them. +  DenseMap<const MDNode *, const DwarfTypeUnit *> DwarfTypeUnits; + +  SmallVector<std::pair<std::unique_ptr<DwarfTypeUnit>, DICompositeType>, 1> TypeUnitsUnderConstruction;    // Whether to emit the pubnames/pubtypes sections.    bool HasDwarfPubSections; +  // Whether or not to use AT_ranges for compilation units. +  bool HasCURanges; + +  // Whether we emitted a function into a section other than the default +  // text. +  bool UsedNonDefaultText; +    // Version of dwarf we're emitting.    unsigned DwarfVersion; +  // Maps from a type identifier to the actual MDNode. +  DITypeIdentifierMap TypeIdentifierMap; +    // DWARF5 Experimental Options    bool HasDwarfAccelTables;    bool HasSplitDwarf; @@ -460,50 +310,83 @@ class DwarfDebug {    // original object file, rather than things that are meant    // to be in the .dwo sections. -  // The CUs left in the original object file for separated debug info. -  SmallVector<CompileUnit *, 1> SkeletonCUs; +  // Holder for the skeleton information. +  DwarfFile SkeletonHolder; -  // Used to uniquely define abbreviations for the skeleton emission. -  FoldingSet<DIEAbbrev> SkeletonAbbrevSet; +  /// Store file names for type units under fission in a line table header that +  /// will be emitted into debug_line.dwo. +  // FIXME: replace this with a map from comp_dir to table so that we can emit +  // multiple tables during LTO each of which uses directory 0, referencing the +  // comp_dir of all the type units that use it. +  MCDwarfDwoLineTable SplitTypeUnitFileTable; -  // A list of all the unique abbreviations in use. -  std::vector<DIEAbbrev *> SkeletonAbbrevs; +  // True iff there are multiple CUs in this module. +  bool SingleCU; -  // Holder for the skeleton information. -  DwarfUnits SkeletonHolder; +  AddressPool AddrPool; -  // Maps from a type identifier to the actual MDNode. -  DITypeIdentifierMap TypeIdentifierMap; +  DwarfAccelTable AccelNames; +  DwarfAccelTable AccelObjC; +  DwarfAccelTable AccelNamespace; +  DwarfAccelTable AccelTypes; -private: +  MCDwarfDwoLineTable *getDwoLineTable(const DwarfCompileUnit &);    void addScopeVariable(LexicalScope *LS, DbgVariable *Var); +  const SmallVectorImpl<std::unique_ptr<DwarfUnit>> &getUnits() { +    return InfoHolder.getUnits(); +  } +    /// \brief Find abstract variable associated with Var. -  DbgVariable *findAbstractVariable(DIVariable &Var, DebugLoc Loc); +  DbgVariable *getExistingAbstractVariable(const DIVariable &DV, +                                           DIVariable &Cleansed); +  DbgVariable *getExistingAbstractVariable(const DIVariable &DV); +  void createAbstractVariable(const DIVariable &DV, LexicalScope *Scope); +  void ensureAbstractVariableIsCreated(const DIVariable &Var, +                                       const MDNode *Scope); +  void ensureAbstractVariableIsCreatedIfScoped(const DIVariable &Var, +                                               const MDNode *Scope);    /// \brief Find DIE for the given subprogram and attach appropriate    /// DW_AT_low_pc and DW_AT_high_pc attributes. If there are global    /// variables in this scope then create and insert DIEs for these    /// variables. -  DIE *updateSubprogramScopeDIE(CompileUnit *SPCU, DISubprogram SP); +  DIE &updateSubprogramScopeDIE(DwarfCompileUnit &SPCU, DISubprogram SP); + +  /// \brief A helper function to check whether the DIE for a given Scope is +  /// going to be null. +  bool isLexicalScopeDIENull(LexicalScope *Scope); + +  /// \brief A helper function to construct a RangeSpanList for a given +  /// lexical scope. +  void addScopeRangeList(DwarfCompileUnit &TheCU, DIE &ScopeDIE, +                         const SmallVectorImpl<InsnRange> &Range);    /// \brief Construct new DW_TAG_lexical_block for this scope and    /// attach DW_AT_low_pc/DW_AT_high_pc labels. -  DIE *constructLexicalScopeDIE(CompileUnit *TheCU, LexicalScope *Scope); -  /// A helper function to check whether the DIE for a given Scope is going -  /// to be null. -  bool isLexicalScopeDIENull(LexicalScope *Scope); +  std::unique_ptr<DIE> constructLexicalScopeDIE(DwarfCompileUnit &TheCU, +                                                LexicalScope *Scope);    /// \brief This scope represents inlined body of a function. Construct    /// DIE to represent this concrete inlined copy of the function. -  DIE *constructInlinedScopeDIE(CompileUnit *TheCU, LexicalScope *Scope); +  std::unique_ptr<DIE> constructInlinedScopeDIE(DwarfCompileUnit &TheCU, +                                                LexicalScope *Scope);    /// \brief Construct a DIE for this scope. -  DIE *constructScopeDIE(CompileUnit *TheCU, LexicalScope *Scope); +  std::unique_ptr<DIE> constructScopeDIE(DwarfCompileUnit &TheCU, +                                         LexicalScope *Scope); +  void createAndAddScopeChildren(DwarfCompileUnit &TheCU, LexicalScope *Scope, +                                 DIE &ScopeDIE); +  /// \brief Construct a DIE for this abstract scope. +  void constructAbstractSubprogramScopeDIE(DwarfCompileUnit &TheCU, +                                           LexicalScope *Scope); +  /// \brief Construct a DIE for this subprogram scope. +  DIE &constructSubprogramScopeDIE(DwarfCompileUnit &TheCU, +                                   LexicalScope *Scope);    /// A helper function to create children of a Scope DIE. -  DIE *createScopeChildrenDIE(CompileUnit *TheCU, LexicalScope *Scope, -                              SmallVectorImpl<DIE*> &Children); +  DIE *createScopeChildrenDIE(DwarfCompileUnit &TheCU, LexicalScope *Scope, +                              SmallVectorImpl<std::unique_ptr<DIE>> &Children);    /// \brief Emit initial Dwarf sections with a label at the start of each one.    void emitSectionLabels(); @@ -514,12 +397,13 @@ private:    /// \brief Compute the size and offset of all the DIEs.    void computeSizeAndOffsets(); -  /// \brief Attach DW_AT_inline attribute with inlined subprogram DIEs. -  void computeInlinedDIEs(); -    /// \brief Collect info for variables that were optimized out.    void collectDeadVariables(); +  void finishVariableDefinitions(); + +  void finishSubprogramDefinitions(); +    /// \brief Finish off debug information after all functions have been    /// processed.    void finalizeModuleInfo(); @@ -528,9 +412,6 @@ private:    /// open.    void endSections(); -  /// \brief Emit a set of abbreviations to the specific section. -  void emitAbbrevs(const MCSection *, std::vector<DIEAbbrev*> *); -    /// \brief Emit the debug info section.    void emitDebugInfo(); @@ -566,32 +447,42 @@ private:    /// index.    void emitDebugPubTypes(bool GnuStyle = false); +  void +  emitDebugPubSection(bool GnuStyle, const MCSection *PSec, StringRef Name, +                      const StringMap<const DIE *> &(DwarfUnit::*Accessor)() +                      const); +    /// \brief Emit visible names into a debug str section.    void emitDebugStr();    /// \brief Emit visible names into a debug loc section.    void emitDebugLoc(); +  /// \brief Emit visible names into a debug loc dwo section. +  void emitDebugLocDWO(); +    /// \brief Emit visible names into a debug aranges section.    void emitDebugARanges();    /// \brief Emit visible names into a debug ranges section.    void emitDebugRanges(); -  /// \brief Emit visible names into a debug macinfo section. -  void emitDebugMacInfo(); -    /// \brief Emit inline info using custom format.    void emitDebugInlineInfo();    /// DWARF 5 Experimental Split Dwarf Emitters +  /// \brief Initialize common features of skeleton units. +  void initSkeletonUnit(const DwarfUnit &U, DIE &Die, +                        std::unique_ptr<DwarfUnit> NewU); +    /// \brief Construct the split debug info compile unit for the debug info    /// section. -  CompileUnit *constructSkeletonCU(const CompileUnit *CU); +  DwarfCompileUnit &constructSkeletonCU(const DwarfCompileUnit &CU); -  /// \brief Emit the local split abbreviations. -  void emitSkeletonAbbrevs(const MCSection *); +  /// \brief Construct the split debug info compile unit for the debug info +  /// section. +  DwarfTypeUnit &constructSkeletonTU(DwarfTypeUnit &TU);    /// \brief Emit the debug info dwo section.    void emitDebugInfoDWO(); @@ -599,27 +490,30 @@ private:    /// \brief Emit the debug abbrev dwo section.    void emitDebugAbbrevDWO(); +  /// \brief Emit the debug line dwo section. +  void emitDebugLineDWO(); +    /// \brief Emit the debug str dwo section.    void emitDebugStrDWO(); -  /// \brief Create new CompileUnit for the given metadata node with tag -  /// DW_TAG_compile_unit. -  CompileUnit *constructCompileUnit(DICompileUnit DIUnit); +  /// Flags to let the linker know we have emitted new style pubnames. Only +  /// emit it here if we don't have a skeleton CU for split dwarf. +  void addGnuPubAttributes(DwarfUnit &U, DIE &D) const; -  /// \brief Construct subprogram DIE. -  void constructSubprogramDIE(CompileUnit *TheCU, const MDNode *N); +  /// \brief Create new DwarfCompileUnit for the given metadata node with tag +  /// DW_TAG_compile_unit. +  DwarfCompileUnit &constructDwarfCompileUnit(DICompileUnit DIUnit);    /// \brief Construct imported_module or imported_declaration DIE. -  void constructImportedEntityDIE(CompileUnit *TheCU, const MDNode *N); +  void constructImportedEntityDIE(DwarfCompileUnit &TheCU, const MDNode *N);    /// \brief Construct import_module DIE. -  void constructImportedEntityDIE(CompileUnit *TheCU, const MDNode *N, -                                  DIE *Context); +  void constructImportedEntityDIE(DwarfCompileUnit &TheCU, const MDNode *N, +                                  DIE &Context);    /// \brief Construct import_module DIE. -  void constructImportedEntityDIE(CompileUnit *TheCU, -                                  const DIImportedEntity &Module, -                                  DIE *Context); +  void constructImportedEntityDIE(DwarfCompileUnit &TheCU, +                                  const DIImportedEntity &Module, DIE &Context);    /// \brief Register a source line with debug info. Returns the unique    /// label that was emitted and which provides correspondence to the @@ -633,21 +527,18 @@ private:    /// \brief If Var is an current function argument that add it in    /// CurrentFnArguments list. -  bool addCurrentFnArgument(const MachineFunction *MF, -                            DbgVariable *Var, LexicalScope *Scope); +  bool addCurrentFnArgument(DbgVariable *Var, LexicalScope *Scope);    /// \brief Populate LexicalScope entries with variables' info. -  void collectVariableInfo(const MachineFunction *, -                           SmallPtrSet<const MDNode *, 16> &ProcessedVars); +  void collectVariableInfo(SmallPtrSet<const MDNode *, 16> &ProcessedVars);    /// \brief Collect variable information from the side table maintained    /// by MMI. -  void collectVariableInfoFromMMITable(const MachineFunction * MF, -                                       SmallPtrSet<const MDNode *, 16> &P); +  void collectVariableInfoFromMMITable(SmallPtrSet<const MDNode *, 16> &P);    /// \brief Ensure that a label will be emitted before MI.    void requestLabelBeforeInsn(const MachineInstr *MI) { -    LabelsBeforeInsn.insert(std::make_pair(MI, (MCSymbol*)0)); +    LabelsBeforeInsn.insert(std::make_pair(MI, nullptr));    }    /// \brief Return Label preceding the instruction. @@ -655,18 +546,25 @@ private:    /// \brief Ensure that a label will be emitted after MI.    void requestLabelAfterInsn(const MachineInstr *MI) { -    LabelsAfterInsn.insert(std::make_pair(MI, (MCSymbol*)0)); +    LabelsAfterInsn.insert(std::make_pair(MI, nullptr));    }    /// \brief Return Label immediately following the instruction.    MCSymbol *getLabelAfterInsn(const MachineInstr *MI); +  void attachRangesOrLowHighPC(DwarfCompileUnit &Unit, DIE &D, +                               const SmallVectorImpl<InsnRange> &Ranges); +  void attachLowHighPC(DwarfCompileUnit &Unit, DIE &D, MCSymbol *Begin, +                       MCSymbol *End); +  public:    //===--------------------------------------------------------------------===//    // Main entry points.    //    DwarfDebug(AsmPrinter *A, Module *M); +  ~DwarfDebug() override; +    void insertDIE(const MDNode *TypeMD, DIE *Die) {      MDTypeNodeToDieMap.insert(std::make_pair(TypeMD, Die));    } @@ -679,62 +577,101 @@ public:    void beginModule();    /// \brief Emit all Dwarf sections that should come after the content. -  void endModule(); +  void endModule() override;    /// \brief Gather pre-function debug information. -  void beginFunction(const MachineFunction *MF); +  void beginFunction(const MachineFunction *MF) override;    /// \brief Gather and emit post-function debug information. -  void endFunction(const MachineFunction *MF); +  void endFunction(const MachineFunction *MF) override;    /// \brief Process beginning of an instruction. -  void beginInstruction(const MachineInstr *MI); +  void beginInstruction(const MachineInstr *MI) override;    /// \brief Process end of an instruction. -  void endInstruction(const MachineInstr *MI); +  void endInstruction() override;    /// \brief Add a DIE to the set of types that we're going to pull into    /// type units. -  void addTypeUnitType(DIE *Die) { TypeUnits.push_back(Die); } +  void addDwarfTypeUnitType(DwarfCompileUnit &CU, StringRef Identifier, +                            DIE &Die, DICompositeType CTy);    /// \brief Add a label so that arange data can be generated for it.    void addArangeLabel(SymbolCU SCU) { ArangeLabels.push_back(SCU); }    /// \brief For symbols that have a size designated (e.g. common symbols),    /// this tracks that size. -  void setSymbolSize(const MCSymbol *Sym, uint64_t Size) { SymSize[Sym] = Size;} - -  /// \brief Look up the source id with the given directory and source file -  /// names. If none currently exists, create a new id and insert it in the -  /// SourceIds map. -  unsigned getOrCreateSourceID(StringRef DirName, StringRef FullName, -                               unsigned CUID); +  void setSymbolSize(const MCSymbol *Sym, uint64_t Size) override { +    SymSize[Sym] = Size; +  }    /// \brief Recursively Emits a debug information entry. -  void emitDIE(DIE *Die, ArrayRef<DIEAbbrev *> Abbrevs); +  void emitDIE(DIE &Die);    // Experimental DWARF5 features.    /// \brief Returns whether or not to emit tables that dwarf consumers can    /// use to accelerate lookup. -  bool useDwarfAccelTables() { return HasDwarfAccelTables; } +  bool useDwarfAccelTables() const { return HasDwarfAccelTables; }    /// \brief Returns whether or not to change the current debug info for the    /// split dwarf proposal support. -  bool useSplitDwarf() { return HasSplitDwarf; } +  bool useSplitDwarf() const { return HasSplitDwarf; }    /// Returns the Dwarf Version.    unsigned getDwarfVersion() const { return DwarfVersion; } +  /// Returns the section symbol for the .debug_loc section. +  MCSymbol *getDebugLocSym() const { return DwarfDebugLocSectionSym; } + +  /// Returns the previous section that was emitted into. +  const MCSection *getPrevSection() const { return PrevSection; } + +  /// Returns the previous CU that was being updated +  const DwarfCompileUnit *getPrevCU() const { return PrevCU; } + +  /// Returns the entries for the .debug_loc section. +  const SmallVectorImpl<DebugLocList> & +  getDebugLocEntries() const { +    return DotDebugLocEntries; +  } + +  /// \brief Emit an entry for the debug loc section. This can be used to +  /// handle an entry that's going to be emitted into the debug loc section. +  void emitDebugLocEntry(ByteStreamer &Streamer, const DebugLocEntry &Entry); + +  /// Emit the location for a debug loc entry, including the size header. +  void emitDebugLocEntryLocation(const DebugLocEntry &Entry); +    /// Find the MDNode for the given reference.    template <typename T> T resolve(DIRef<T> Ref) const {      return Ref.resolve(TypeIdentifierMap);    } +  /// \brief Return the TypeIdentifierMap. +  const DITypeIdentifierMap &getTypeIdentifierMap() const { +    return TypeIdentifierMap; +  } + +  /// Find the DwarfCompileUnit for the given CU Die. +  DwarfCompileUnit *lookupUnit(const DIE *CU) const { +    return CUDieMap.lookup(CU); +  }    /// isSubprogramContext - Return true if Context is either a subprogram    /// or another context nested inside a subprogram.    bool isSubprogramContext(const MDNode *Context); +  void addSubprogramNames(DISubprogram SP, DIE &Die); + +  AddressPool &getAddressPool() { return AddrPool; } + +  void addAccelName(StringRef Name, const DIE &Die); + +  void addAccelObjC(StringRef Name, const DIE &Die); + +  void addAccelNamespace(StringRef Name, const DIE &Die); + +  void addAccelType(StringRef Name, const DIE &Die, char Flags);  };  } // End of namespace llvm | 
