#include "AsmPrinterHandler.h"
#include "DIE.h"
+#include "DebugLocEntry.h"
+#include "DebugLocList.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/ADT/FoldingSet.h"
#include "llvm/CodeGen/LexicalScopes.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"
namespace llvm {
+class AsmPrinter;
class ByteStreamer;
-class DwarfUnit;
-class DwarfCompileUnit;
class ConstantInt;
class ConstantFP;
-class DbgVariable;
-class MachineFrameInfo;
+class DwarfCompileUnit;
+class DwarfDebug;
+class DwarfTypeUnit;
+class DwarfUnit;
class MachineModuleInfo;
-class MachineOperand;
-class MCAsmInfo;
-class MCObjectFileInfo;
-class DIEAbbrev;
-class DIE;
-class DIELoc;
-class DIEEntry;
//===----------------------------------------------------------------------===//
/// \brief This class is used to record source line correspondence.
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() const { return Begin == 0 && End == 0; }
- bool isMerged() const { 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 {
assert(Var.isVariable() && "Invalid complex DbgVariable!");
return Var.hasComplexAddress();
}
- bool isBlockByrefVariable() const {
- assert(Var.isVariable() && "Invalid complex DbgVariable!");
- return Var.isBlockByrefVariable();
- }
+ bool isBlockByrefVariable() const;
unsigned getNumAddrElements() const {
assert(Var.isVariable() && "Invalid complex DbgVariable!");
return Var.getNumAddrElements();
/// \brief Emit all of the units to the section listed with the given
/// abbreviation section.
- void emitUnits(DwarfDebug *DD, const MCSection *ASection,
- const MCSymbol *ASectionSym);
+ void emitUnits(DwarfDebug *DD, const MCSymbol *ASectionSym);
/// \brief Emit a set of abbreviations to the specific section.
void emitAbbrevs(const MCSection *);
// 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 DwarfCompileUnit.
DenseMap<const MDNode *, DIE *> MDTypeNodeToDieMap;
- // Used to unique C++ member function declarations.
- StringMap<const MDNode *> OdrMemberMap;
-
- // 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;
// Collection of abstract variables.
DenseMap<const MDNode *, DbgVariable *> AbstractVariables;
- // 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.
// 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.
// Holder for the skeleton information.
DwarfFile SkeletonHolder;
+ /// 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;
+
+ // True iff there are multiple CUs in this module.
+ bool SingleCU;
+
+ MCDwarfDwoLineTable *getDwoLineTable(const DwarfCompileUnit &);
+
void addScopeVariable(LexicalScope *LS, DbgVariable *Var);
const SmallVectorImpl<DwarfUnit *> &getUnits() {
/// \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 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();
return MDTypeNodeToDieMap.lookup(TypeMD);
}
- /// \brief Look up or create an entry in the OdrMemberMap.
- const MDNode *&getOrCreateOdrMember(StringRef Key) {
- return OdrMemberMap.GetOrCreateValue(Key).getValue();
- }
-
/// \brief Emit all Dwarf sections that should come prior to the
/// content.
void beginModule();
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);
-
/// \brief Recursively Emits a debug information entry.
void emitDIE(DIE *Die);
/// split dwarf proposal support.
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 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<DotDebugLocEntry> &getDebugLocEntries() const {
+ 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 DotDebugLocEntry &Entry);
+ 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);