#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 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; }
};
class DotDebugLocEntry {
const MCSymbol *Begin;
const MCSymbol *End;
enum EntryType {
E_Location,
E_Integer,
E_ConstantFP,
E_ConstantInt
};
enum EntryType EntryKind;
union {
int64_t Int;
const ConstantFP *CFP;
const ConstantInt *CIP;
} Constants;
MachineLocation Loc;
const MDNode *Variable;
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;
}
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; }
};
class DbgVariable {
DIVariable Var; DIE *TheDIE; unsigned DotDebugLocOffset; DbgVariable *AbsVar; const MachineInstr *MInsn; int FrameIndex;
DwarfDebug *DD;
public:
DbgVariable(DIVariable V, DbgVariable *AV, DwarfDebug *DD)
: Var(V), TheDIE(0), DotDebugLocOffset(~0U), AbsVar(AV), MInsn(0),
FrameIndex(~0), DD(DD) {}
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; }
uint16_t 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.isVariable() && "Invalid complex DbgVariable!");
return Var.hasComplexAddress();
}
bool isBlockByrefVariable() const {
assert(Var.isVariable() && "Invalid complex DbgVariable!");
return Var.isBlockByrefVariable();
}
unsigned getNumAddrElements() const {
assert(Var.isVariable() && "Invalid complex DbgVariable!");
return Var.getNumAddrElements();
}
uint64_t getAddrElement(unsigned i) const {
return Var.getAddrElement(i);
}
DIType getType() const;
private:
template <typename T> T resolve(DIRef<T> Ref) const;
};
class DwarfUnits {
AsmPrinter *Asm;
FoldingSet<DIEAbbrev> *AbbreviationsSet;
std::vector<DIEAbbrev *> &Abbreviations;
SmallVector<CompileUnit *, 1> CUs;
typedef StringMap<std::pair<MCSymbol*, unsigned>,
BumpPtrAllocator&> StrPool;
StrPool StringPool;
unsigned NextStringPoolNumber;
std::string StringPref;
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) {}
unsigned computeSizeAndOffset(DIE *Die, unsigned Offset);
void computeSizeAndOffsets();
void assignAbbrevNumber(DIEAbbrev &Abbrev);
void addUnit(CompileUnit *CU) { CUs.push_back(CU); }
void emitUnits(DwarfDebug *DD, const MCSection *USection,
const MCSection *ASection, const MCSymbol *ASectionSym);
void emitStrings(const MCSection *StrSection, const MCSection *OffsetSection,
const MCSymbol *StrSecSym);
void emitAddresses(const MCSection *AddrSection);
MCSymbol *getStringPoolSym();
MCSymbol *getStringPoolEntry(StringRef Str);
unsigned getStringPoolIndex(StringRef Str);
StrPool *getStringPool() { return &StringPool; }
unsigned getAddrPoolIndex(const MCExpr *Sym);
unsigned getAddrPoolIndex(const MCSymbol *Sym);
AddrPool *getAddrPool() { return &AddressPool; }
};
struct SymbolCU {
SymbolCU(CompileUnit *CU, const MCSymbol *Sym) : Sym(Sym), CU(CU) {}
const MCSymbol *Sym;
CompileUnit *CU;
};
class DwarfDebug {
AsmPrinter *Asm;
MachineModuleInfo *MMI;
BumpPtrAllocator DIEValueAllocator;
CompileUnit *FirstCU;
DenseMap <const MDNode *, CompileUnit *> CUMap;
DenseMap <const MDNode *, CompileUnit *> SPMap;
DenseMap <const DIE *, CompileUnit *> CUDieMap;
DenseMap<const MDNode *, DIE *> MDTypeNodeToDieMap;
FoldingSet<DIEAbbrev> AbbreviationsSet;
std::vector<DIEAbbrev *> Abbreviations;
DenseMap <unsigned, unsigned> FileIDCUMap;
StringMap<unsigned, BumpPtrAllocator&> SourceIdMap;
std::vector<SymbolCU> ArangeLabels;
DenseMap <const MCSymbol *, uint64_t> SymSize;
typedef DenseMap<const MCSection *, SmallVector<SymbolCU, 8> > SectionMapType;
SectionMapType SectionMap;
SmallVector<DbgVariable *, 8> CurrentFnArguments;
LexicalScopes LScopes;
DenseMap<const MDNode *, DIE *> AbstractSPDies;
typedef DenseMap<LexicalScope *,
SmallVector<DbgVariable *, 8> > ScopeVariablesMap;
ScopeVariablesMap ScopeVariables;
DenseMap<const MDNode *, DbgVariable *> AbstractVariables;
SmallVector<DotDebugLocEntry, 4> DotDebugLocEntries;
SmallPtrSet<DIE *, 4> InlinedSubprogramDIEs;
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;
MCSymbol *DwarfInfoSectionSym, *DwarfAbbrevSectionSym;
MCSymbol *DwarfStrSectionSym, *TextSectionSym, *DwarfDebugRangeSectionSym;
MCSymbol *DwarfDebugLocSectionSym, *DwarfLineSectionSym, *DwarfAddrSectionSym;
MCSymbol *FunctionBeginSym, *FunctionEndSym;
MCSymbol *DwarfAbbrevDWOSectionSym, *DwarfStrDWOSectionSym;
MCSymbol *DwarfGnuPubNamesSectionSym, *DwarfGnuPubTypesSectionSym;
StringRef CompilationDir;
unsigned GlobalCUIndexCount;
DwarfUnits InfoHolder;
typedef SmallVector<std::pair<const MDNode *, const MDNode *>, 32>
ImportedEntityMap;
ImportedEntityMap ScopesWithImportedEntities;
std::vector<DIE *> TypeUnits;
bool HasDwarfPubSections;
unsigned DwarfVersion;
bool HasDwarfAccelTables;
bool HasSplitDwarf;
SmallVector<CompileUnit *, 1> SkeletonCUs;
FoldingSet<DIEAbbrev> SkeletonAbbrevSet;
std::vector<DIEAbbrev *> SkeletonAbbrevs;
DwarfUnits SkeletonHolder;
DITypeIdentifierMap TypeIdentifierMap;
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);
bool isLexicalScopeDIENull(LexicalScope *Scope);
DIE *constructInlinedScopeDIE(CompileUnit *TheCU, LexicalScope *Scope);
DIE *constructScopeDIE(CompileUnit *TheCU, LexicalScope *Scope);
DIE *createScopeChildrenDIE(CompileUnit *TheCU, LexicalScope *Scope,
SmallVectorImpl<DIE*> &Children);
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 emitDebugPubNames(bool GnuStyle = false);
void emitDebugPubTypes(bool GnuStyle = false);
void emitDebugStr();
void emitDebugLoc();
void emitDebugARanges();
void emitDebugRanges();
void emitDebugMacInfo();
void emitDebugInlineInfo();
CompileUnit *constructSkeletonCU(const CompileUnit *CU);
void emitSkeletonAbbrevs(const MCSection *);
void emitDebugInfoDWO();
void emitDebugAbbrevDWO();
void emitDebugStrDWO();
CompileUnit *constructCompileUnit(const MDNode *N);
void constructSubprogramDIE(CompileUnit *TheCU, const MDNode *N);
void constructImportedEntityDIE(CompileUnit *TheCU, const MDNode *N);
void constructImportedEntityDIE(CompileUnit *TheCU, const MDNode *N,
DIE *Context);
void constructImportedEntityDIE(CompileUnit *TheCU,
const DIImportedEntity &Module,
DIE *Context);
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);
void insertDIE(const MDNode *TypeMD, DIE *Die) {
MDTypeNodeToDieMap.insert(std::make_pair(TypeMD, Die));
}
DIE *getDIE(const MDNode *TypeMD) {
return MDTypeNodeToDieMap.lookup(TypeMD);
}
void beginModule();
void endModule();
void beginFunction(const MachineFunction *MF);
void endFunction(const MachineFunction *MF);
void beginInstruction(const MachineInstr *MI);
void endInstruction(const MachineInstr *MI);
void addTypeUnitType(DIE *Die) { TypeUnits.push_back(Die); }
void addArangeLabel(SymbolCU SCU) { ArangeLabels.push_back(SCU); }
void setSymbolSize(const MCSymbol *Sym, uint64_t Size) { SymSize[Sym] = Size;}
unsigned getOrCreateSourceID(StringRef DirName, StringRef FullName,
unsigned CUID);
void emitDIE(DIE *Die, ArrayRef<DIEAbbrev *> Abbrevs);
bool useDwarfAccelTables() { return HasDwarfAccelTables; }
bool useSplitDwarf() { return HasSplitDwarf; }
unsigned getDwarfVersion() const { return DwarfVersion; }
template <typename T> T resolve(DIRef<T> Ref) const {
return Ref.resolve(TypeIdentifierMap);
}
bool isSubprogramContext(const MDNode *Context);
};
}
#endif