#ifndef CODEGEN_ASMPRINTER_DWARFDEBUG_H__
#define CODEGEN_ASMPRINTER_DWARFDEBUG_H__
#include "DIE.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.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/MC/MachineLocation.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/DebugLoc.h"
namespace llvm {
class CompileUnit;
class ConstantInt;
class ConstantFP;
class DbgVariable;
class MachineFrameInfo;
class MachineModuleInfo;
class MachineOperand;
class MCAsmInfo;
class DIEAbbrev;
class DIE;
class DIEBlock;
class DIEEntry;
class DwarfDebug;
class SrcLineInfo {
unsigned Line; unsigned Column; unsigned SourceID; MCSymbol *Label; public:
SrcLineInfo(unsigned L, unsigned C, unsigned S, MCSymbol *label)
: Line(L), Column(C), SourceID(S), Label(label) {}
unsigned getLine() const { return Line; }
unsigned getColumn() const { return Column; }
unsigned getSourceID() const { return SourceID; }
MCSymbol *getLabel() const { return Label; }
};
typedef struct DotDebugLocEntry {
const MCSymbol *Begin;
const MCSymbol *End;
MachineLocation Loc;
const MDNode *Variable;
bool Merged;
bool Constant;
enum EntryType {
E_Location,
E_Integer,
E_ConstantFP,
E_ConstantInt
};
enum EntryType EntryKind;
union {
int64_t Int;
const ConstantFP *CFP;
const ConstantInt *CIP;
} Constants;
DotDebugLocEntry()
: Begin(0), End(0), Variable(0), Merged(false),
Constant(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),
Constant(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),
Constant(true) { Constants.Int = i; EntryKind = E_Integer; }
DotDebugLocEntry(const MCSymbol *B, const MCSymbol *E, const ConstantFP *FPtr)
: Begin(B), End(E), Variable(0), Merged(false),
Constant(true) { Constants.CFP = FPtr; EntryKind = E_ConstantFP; }
DotDebugLocEntry(const MCSymbol *B, const MCSymbol *E,
const ConstantInt *IPtr)
: Begin(B), End(E), Variable(0), Merged(false),
Constant(true) { Constants.CIP = IPtr; EntryKind = E_ConstantInt; }
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() { return Constants.Int; }
const ConstantFP *getConstantFP() { return Constants.CFP; }
const ConstantInt *getConstantInt() { return Constants.CIP; }
} DotDebugLocEntry;
class DbgVariable {
DIVariable Var; DIE *TheDIE; unsigned DotDebugLocOffset; DbgVariable *AbsVar; const MachineInstr *MInsn; int FrameIndex;
public:
DbgVariable(DIVariable V, DbgVariable *AV)
: Var(V), TheDIE(0), DotDebugLocOffset(~0U), AbsVar(AV), MInsn(0),
FrameIndex(~0) {}
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; }
unsigned getTag() const {
if (Var.getTag() == dwarf::DW_TAG_arg_variable)
return dwarf::DW_TAG_formal_parameter;
return dwarf::DW_TAG_variable;
}
bool isArtificial() const {
if (Var.isArtificial())
return true;
if (getType().isArtificial())
return true;
return false;
}
bool isObjectPointer() const {
if (Var.isObjectPointer())
return true;
if (getType().isObjectPointer())
return true;
return false;
}
bool variableHasComplexAddress() const {
assert(Var.Verify() && "Invalid complex DbgVariable!");
return Var.hasComplexAddress();
}
bool isBlockByrefVariable() const {
assert(Var.Verify() && "Invalid complex DbgVariable!");
return Var.isBlockByrefVariable();
}
unsigned getNumAddrElements() const {
assert(Var.Verify() && "Invalid complex DbgVariable!");
return Var.getNumAddrElements();
}
uint64_t getAddrElement(unsigned i) const {
return Var.getAddrElement(i);
}
DIType getType() const;
};
typedef StringMap<std::pair<MCSymbol*, unsigned>,
BumpPtrAllocator&> StrPool;
typedef DenseMap<MCSymbol *, std::pair<MCSymbol *, unsigned> > AddrPool;
class DwarfUnits {
AsmPrinter *Asm;
FoldingSet<DIEAbbrev> *AbbreviationsSet;
std::vector<DIEAbbrev *> *Abbreviations;
SmallVector<CompileUnit *, 1> CUs;
StrPool StringPool;
unsigned NextStringPoolNumber;
std::string StringPref;
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) {}
unsigned computeSizeAndOffset(DIE *Die, unsigned Offset);
void computeSizeAndOffsets();
void assignAbbrevNumber(DIEAbbrev &Abbrev);
void addUnit(CompileUnit *CU) { CUs.push_back(CU); }
void emitUnits(DwarfDebug *, const MCSection *, const MCSection *,
const MCSymbol *);
void emitStrings(const MCSection *, const MCSection *, const MCSymbol *);
void emitAddresses(const MCSection *);
MCSymbol *getStringPoolSym();
MCSymbol *getStringPoolEntry(StringRef Str);
unsigned getStringPoolIndex(StringRef Str);
StrPool *getStringPool() { return &StringPool; }
unsigned getAddrPoolIndex(MCSymbol *);
AddrPool *getAddrPool() { return &AddressPool; }
unsigned getCUOffset(DIE *Die);
};
class DwarfDebug {
AsmPrinter *Asm;
MachineModuleInfo *MMI;
BumpPtrAllocator DIEValueAllocator;
CompileUnit *FirstCU;
DenseMap <const MDNode *, CompileUnit *> CUMap;
DenseMap <const MDNode *, CompileUnit *> SPMap;
FoldingSet<DIEAbbrev> AbbreviationsSet;
std::vector<DIEAbbrev *> Abbreviations;
DenseMap <unsigned, unsigned> FileIDCUMap;
StringMap<unsigned, BumpPtrAllocator&> SourceIdMap;
SetVector<const MCSection*> SectionMap;
SmallVector<DbgVariable *, 8> CurrentFnArguments;
LexicalScopes LScopes;
DenseMap<const MDNode *, DIE *> AbstractSPDies;
DenseMap<LexicalScope *, SmallVector<DbgVariable *, 8> > ScopeVariables;
DenseMap<const MDNode *, DbgVariable *> AbstractVariables;
SmallVector<DotDebugLocEntry, 4> DotDebugLocEntries;
SmallPtrSet<DIE *, 4> InlinedSubprogramDIEs;
typedef std::pair<const MCSymbol *, DIE *> InlineInfoLabels;
DenseMap<const MDNode *, SmallVector<InlineInfoLabels, 4> > InlineInfo;
SmallVector<const MDNode *, 4> InlinedSPNodes;
SmallPtrSet<const MDNode *, 16> ProcessedSPNodes;
DenseMap<const MachineInstr *, MCSymbol *> LabelsBeforeInsn;
DenseMap<const MachineInstr *, MCSymbol *> LabelsAfterInsn;
SmallVector<const MDNode*, 8> UserVariables;
typedef DenseMap<const MDNode*, SmallVector<const MachineInstr*, 4> >
DbgValueHistoryMap;
DbgValueHistoryMap DbgValues;
SmallVector<const MCSymbol *, 8> DebugRangeSymbols;
DebugLoc PrevInstLoc;
MCSymbol *PrevLabel;
DebugLoc PrologEndLoc;
struct FunctionDebugFrameInfo {
unsigned Number;
std::vector<MachineMove> Moves;
FunctionDebugFrameInfo(unsigned Num, const std::vector<MachineMove> &M)
: Number(Num), Moves(M) {}
};
std::vector<FunctionDebugFrameInfo> DebugFrames;
MCSymbol *DwarfInfoSectionSym, *DwarfAbbrevSectionSym;
MCSymbol *DwarfStrSectionSym, *TextSectionSym, *DwarfDebugRangeSectionSym;
MCSymbol *DwarfDebugLocSectionSym;
MCSymbol *FunctionBeginSym, *FunctionEndSym;
MCSymbol *DwarfAbbrevDWOSectionSym, *DwarfStrDWOSectionSym;
StringRef CompilationDir;
unsigned GlobalCUIndexCount;
DwarfUnits InfoHolder;
bool IsDarwinGDBCompat;
bool HasDwarfAccelTables;
bool HasSplitDwarf;
CompileUnit *SkeletonCU;
FoldingSet<DIEAbbrev> SkeletonAbbrevSet;
std::vector<DIEAbbrev *> SkeletonAbbrevs;
DwarfUnits SkeletonHolder;
private:
void addScopeVariable(LexicalScope *LS, DbgVariable *Var);
DbgVariable *findAbstractVariable(DIVariable &Var, DebugLoc Loc);
DIE *updateSubprogramScopeDIE(CompileUnit *SPCU, const MDNode *SPNode);
DIE *constructLexicalScopeDIE(CompileUnit *TheCU, LexicalScope *Scope);
DIE *constructInlinedScopeDIE(CompileUnit *TheCU, LexicalScope *Scope);
DIE *constructScopeDIE(CompileUnit *TheCU, LexicalScope *Scope);
void emitSectionLabels();
unsigned computeSizeAndOffset(DIE *Die, unsigned Offset);
void computeSizeAndOffsets();
void computeInlinedDIEs();
void collectDeadVariables();
void finalizeModuleInfo();
void endSections();
void emitAbbrevs(const MCSection *, std::vector<DIEAbbrev*> *);
void emitDebugInfo();
void emitAbbreviations();
void emitEndOfLineMatrix(unsigned SectionEnd);
void emitAccelNames();
void emitAccelObjC();
void emitAccelNamespaces();
void emitAccelTypes();
void emitDebugPubTypes();
void emitDebugStr();
void emitDebugLoc();
void emitDebugARanges();
void emitDebugRanges();
void emitDebugMacInfo();
void emitDebugInlineInfo();
CompileUnit *constructSkeletonCU(const MDNode *);
void emitSkeletonCU(const MCSection *);
void emitSkeletonAbbrevs(const MCSection *);
void emitDebugInfoDWO();
void emitDebugAbbrevDWO();
void emitDebugStrDWO();
CompileUnit *constructCompileUnit(const MDNode *N);
void constructSubprogramDIE(CompileUnit *TheCU, const MDNode *N);
void recordSourceLine(unsigned Line, unsigned Col, const MDNode *Scope,
unsigned Flags);
void identifyScopeMarkers();
bool addCurrentFnArgument(const MachineFunction *MF,
DbgVariable *Var, LexicalScope *Scope);
void collectVariableInfo(const MachineFunction *,
SmallPtrSet<const MDNode *, 16> &ProcessedVars);
void collectVariableInfoFromMMITable(const MachineFunction * MF,
SmallPtrSet<const MDNode *, 16> &P);
void requestLabelBeforeInsn(const MachineInstr *MI) {
LabelsBeforeInsn.insert(std::make_pair(MI, (MCSymbol*)0));
}
MCSymbol *getLabelBeforeInsn(const MachineInstr *MI);
void requestLabelAfterInsn(const MachineInstr *MI) {
LabelsAfterInsn.insert(std::make_pair(MI, (MCSymbol*)0));
}
MCSymbol *getLabelAfterInsn(const MachineInstr *MI);
public:
DwarfDebug(AsmPrinter *A, Module *M);
~DwarfDebug();
void collectInfoFromNamedMDNodes(const Module *M);
bool collectLegacyDebugInfo(const Module *M);
void beginModule();
void endModule();
void beginFunction(const MachineFunction *MF);
void endFunction(const MachineFunction *MF);
void beginInstruction(const MachineInstr *MI);
void endInstruction(const MachineInstr *MI);
unsigned getOrCreateSourceID(StringRef DirName, StringRef FullName,
unsigned CUID);
void emitDIE(DIE *Die, std::vector<DIEAbbrev *> *Abbrevs);
bool useDarwinGDBCompat() { return IsDarwinGDBCompat; }
bool useDwarfAccelTables() { return HasDwarfAccelTables; }
bool useSplitDwarf() { return HasSplitDwarf; }
};
}
#endif