#include "DIE.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/LexicalScopes.h"
-#include "llvm/DebugInfo.h"
+#include "llvm/IR/DebugInfo.h"
+#include "llvm/IR/DebugLoc.h"
#include "llvm/MC/MachineLocation.h"
#include "llvm/Support/Allocator.h"
-#include "llvm/Support/DebugLoc.h"
namespace llvm {
+class ByteStreamer;
class DwarfUnit;
-class CompileUnit;
+class DwarfCompileUnit;
class ConstantInt;
class ConstantFP;
class DbgVariable;
class MCObjectFileInfo;
class DIEAbbrev;
class DIE;
-class DIEBlock;
+class DIELoc;
class DIEEntry;
//===----------------------------------------------------------------------===//
/// \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; }
+ bool isEmpty() const { return Begin == 0 && End == 0; }
+ bool isMerged() const { return Merged; }
void Merge(DotDebugLocEntry *Next) {
if (!(Begin && Loc == Next->Loc && End == Next->Begin))
return;
unsigned NextStringPoolNumber;
std::string StringPref;
+ struct AddressPoolEntry {
+ unsigned Number;
+ bool TLS;
+ AddressPoolEntry(unsigned Number, bool TLS) : Number(Number), TLS(TLS) {}
+ };
// 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;
+ typedef DenseMap<const MCSymbol *, AddressPoolEntry> AddrPool;
AddrPool AddressPool;
unsigned NextAddrPoolNumber;
/// \brief Returns the index into the address pool with the given
/// label/symbol.
- unsigned getAddrPoolIndex(const MCExpr *Sym);
- unsigned getAddrPoolIndex(const MCSymbol *Sym);
+ unsigned getAddrPoolIndex(const MCSymbol *Sym, bool TLS = false);
/// \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.
// this is just so that the DIEValue allocator has a place to store
// the particular elements.
// FIXME: Store these off of DwarfDebug instead?
- CompileUnit *FirstCU;
+ 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
/// be shared across CUs, that is why we keep the map here instead
- /// of in CompileUnit.
+ /// of in DwarfCompileUnit.
DenseMap<const MDNode *, DIE *> MDTypeNodeToDieMap;
// Stores the current file ID for a given compile unit.
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
ImportedEntityMap;
ImportedEntityMap ScopesWithImportedEntities;
- // Map from type MDNodes to a pair used as a union. If the pointer is
- // non-null, proxy DIEs in CUs meant to reference this type should be stored
- // in the vector. The hash will be added to these DIEs once it is computed. If
- // the pointer is null, the hash is immediately available in the uint64_t and
- // should be directly used for proxy DIEs.
- DenseMap<const MDNode *, std::pair<uint64_t, SmallVectorImpl<DIE *> *> >
- TypeUnits;
+ // Map from MDNodes for user-defined types to the type units that describe
+ // them.
+ DenseMap<const MDNode *, const DwarfTypeUnit *> DwarfTypeUnits;
// 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;
/// 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.
/// \brief A helper function to construct a RangeSpanList for a given
/// lexical scope.
- void addScopeRangeList(CompileUnit *TheCU, DIE *ScopeDIE,
+ 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);
+ 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);
+ DIE *constructInlinedScopeDIE(DwarfCompileUnit *TheCU, LexicalScope *Scope);
/// \brief Construct a DIE for this scope.
- DIE *constructScopeDIE(CompileUnit *TheCU, LexicalScope *Scope);
+ DIE *constructScopeDIE(DwarfCompileUnit *TheCU, LexicalScope *Scope);
/// A helper function to create children of a Scope DIE.
- DIE *createScopeChildrenDIE(CompileUnit *TheCU, LexicalScope *Scope,
+ DIE *createScopeChildrenDIE(DwarfCompileUnit *TheCU, LexicalScope *Scope,
SmallVectorImpl<DIE *> &Children);
/// \brief Emit initial Dwarf sections with a label at the start of each one.
/// \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, DwarfUnit *NewU);
+
+ /// \brief Construct the split debug info compile unit for the debug info
+ /// section.
+ DwarfCompileUnit *constructSkeletonCU(const DwarfCompileUnit *CU);
+
/// \brief Construct the split debug info compile unit for the debug info
/// section.
- CompileUnit *constructSkeletonCU(const CompileUnit *CU);
+ DwarfTypeUnit *constructSkeletonTU(DwarfTypeUnit *TU);
/// \brief Emit the debug info dwo section.
void emitDebugInfoDWO();
/// emit it here if we don't have a skeleton CU for split dwarf.
void addGnuPubAttributes(DwarfUnit *U, DIE *D) const;
- /// \brief Create new CompileUnit for the given metadata node with tag
+ /// \brief Create new DwarfCompileUnit for the given metadata node with tag
/// DW_TAG_compile_unit.
- CompileUnit *constructCompileUnit(DICompileUnit DIUnit);
+ DwarfCompileUnit *constructDwarfCompileUnit(DICompileUnit DIUnit);
/// \brief Construct subprogram DIE.
- void constructSubprogramDIE(CompileUnit *TheCU, const MDNode *N);
+ void constructSubprogramDIE(DwarfCompileUnit *TheCU, const MDNode *N);
/// \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,
+ void constructImportedEntityDIE(DwarfCompileUnit *TheCU, const MDNode *N,
DIE *Context);
/// \brief Construct import_module DIE.
- void constructImportedEntityDIE(CompileUnit *TheCU,
+ void constructImportedEntityDIE(DwarfCompileUnit *TheCU,
const DIImportedEntity &Module, DIE *Context);
/// \brief Register a source line with debug info. Returns the unique
/// \brief Return Label immediately following the instruction.
MCSymbol *getLabelAfterInsn(const MachineInstr *MI);
+ void attachLowHighPC(DwarfCompileUnit *Unit, DIE *D, MCSymbol *Begin,
+ MCSymbol *End);
+
public:
//===--------------------------------------------------------------------===//
// Main entry points.
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();
+ void endInstruction() override;
/// \brief Add a DIE to the set of types that we're going to pull into
/// type units.
- void addTypeUnitType(uint16_t Language, DIE *Die, DICompositeType CTy);
+ 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) {
+ void setSymbolSize(const MCSymbol *Sym, uint64_t Size) override {
SymSize[Sym] = Size;
}
/// \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; }
+
+ /// \brief Returns whether or not to use AT_ranges for compilation units.
+ bool useCURanges() const { return HasCURanges; }
/// 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 entries for the .debug_loc section.
+ const SmallVectorImpl<DotDebugLocEntry> &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 DotDebugLocEntry &Entry);
+
/// Find the MDNode for the given reference.
template <typename T> T resolve(DIRef<T> Ref) const {
return Ref.resolve(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);