#ifndef CODEGEN_ASMPRINTER_DWARFCOMPILEUNIT_H
#define CODEGEN_ASMPRINTER_DWARFCOMPILEUNIT_H
#include "DIE.h"
#include "DwarfDebug.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/DebugInfo.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCSection.h"
namespace llvm {
class MachineLocation;
class MachineOperand;
class ConstantInt;
class ConstantFP;
class DbgVariable;
class RangeSpan {
public:
RangeSpan(MCSymbol *S, MCSymbol *E) : Start(S), End(E) {}
const MCSymbol *getStart() const { return Start; }
const MCSymbol *getEnd() const { return End; }
private:
const MCSymbol *Start, *End;
};
class RangeSpanList {
private:
MCSymbol *RangeSym;
SmallVector<RangeSpan, 2> Ranges;
public:
RangeSpanList(MCSymbol *Sym) : RangeSym(Sym) {}
MCSymbol *getSym() const { return RangeSym; }
const SmallVectorImpl<RangeSpan> &getRanges() const { return Ranges; }
void addRange(RangeSpan Range) { Ranges.push_back(Range); }
};
class DwarfUnit {
protected:
unsigned UniqueID;
DICompileUnit CUNode;
const OwningPtr<DIE> UnitDie;
unsigned DebugInfoOffset;
AsmPrinter *Asm;
DwarfDebug *DD;
DwarfFile *DU;
DIE *IndexTyDie;
DenseMap<const MDNode *, DIE *> MDNodeToDieMap;
DenseMap<const MDNode *, DIEEntry *> MDNodeToDIEEntryMap;
StringMap<const DIE *> GlobalNames;
StringMap<const DIE *> GlobalTypes;
StringMap<std::vector<const DIE *> > AccelNames;
StringMap<std::vector<const DIE *> > AccelObjC;
StringMap<std::vector<const DIE *> > AccelNamespace;
StringMap<std::vector<std::pair<const DIE *, unsigned> > > AccelTypes;
std::vector<DIEBlock *> DIEBlocks;
DenseMap<DIE *, const MDNode *> ContainingTypeMap;
SmallVector<RangeSpan, 1> CURanges;
SmallVector<RangeSpanList, 1> CURangeLists;
BumpPtrAllocator DIEValueAllocator;
DIEInteger *DIEIntegerOne;
const MCSection *Section;
MCSymbol *SectionSym;
MCSymbol *LabelBegin;
MCSymbol *LabelEnd;
MCSymbol *LabelRange;
DwarfUnit *Skeleton;
DwarfUnit(unsigned UID, DIE *D, DICompileUnit CU, AsmPrinter *A,
DwarfDebug *DW, DwarfFile *DWU);
public:
virtual ~DwarfUnit();
void setSkeleton(DwarfUnit *Skel) { Skeleton = Skel; }
DwarfUnit *getSkeleton() const { return Skeleton; }
void initSection(const MCSection *Section, MCSymbol *SectionSym) {
assert(!this->Section);
this->Section = Section;
this->SectionSym = SectionSym;
this->LabelBegin =
Asm->GetTempSymbol(Section->getLabelBeginName(), getUniqueID());
this->LabelEnd =
Asm->GetTempSymbol(Section->getLabelEndName(), getUniqueID());
this->LabelRange = Asm->GetTempSymbol("gnu_ranges", getUniqueID());
}
const MCSection *getSection() const {
assert(Section);
return Section;
}
MCSymbol *getLocalSectionSym() const {
if (Skeleton)
return Skeleton->getSectionSym();
return getSectionSym();
}
MCSymbol *getSectionSym() const {
assert(Section);
return SectionSym;
}
MCSymbol *getLocalLabelBegin() const {
if (Skeleton)
return Skeleton->getLabelBegin();
return getLabelBegin();
}
MCSymbol *getLabelBegin() const {
assert(Section);
return LabelBegin;
}
MCSymbol *getLabelEnd() const {
assert(Section);
return LabelEnd;
}
MCSymbol *getLabelRange() const {
assert(Section);
return LabelRange;
}
unsigned getUniqueID() const { return UniqueID; }
uint16_t getLanguage() const { return CUNode.getLanguage(); }
DICompileUnit getCUNode() const { return CUNode; }
DIE *getUnitDie() const { return UnitDie.get(); }
const StringMap<const DIE *> &getGlobalNames() const { return GlobalNames; }
const StringMap<const DIE *> &getGlobalTypes() const { return GlobalTypes; }
const StringMap<std::vector<const DIE *> > &getAccelNames() const {
return AccelNames;
}
const StringMap<std::vector<const DIE *> > &getAccelObjC() const {
return AccelObjC;
}
const StringMap<std::vector<const DIE *> > &getAccelNamespace() const {
return AccelNamespace;
}
const StringMap<std::vector<std::pair<const DIE *, unsigned> > > &
getAccelTypes() const {
return AccelTypes;
}
unsigned getDebugInfoOffset() const { return DebugInfoOffset; }
void setDebugInfoOffset(unsigned DbgInfoOff) { DebugInfoOffset = DbgInfoOff; }
bool hasContent() const { return !UnitDie->getChildren().empty(); }
void addRange(RangeSpan Range) { CURanges.push_back(Range); }
const SmallVectorImpl<RangeSpan> &getRanges() const { return CURanges; }
SmallVectorImpl<RangeSpan> &getRanges() { return CURanges; }
void addRangeList(RangeSpanList Ranges) { CURangeLists.push_back(Ranges); }
const SmallVectorImpl<RangeSpanList> &getRangeLists() const {
return CURangeLists;
}
SmallVectorImpl<RangeSpanList> &getRangeLists() { return CURangeLists; }
std::string getParentContextString(DIScope Context) const;
void addGlobalName(StringRef Name, DIE *Die, DIScope Context);
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, std::pair<const DIE *, unsigned> Die);
DIE *getDIE(DIDescriptor D) const;
DIEBlock *getDIEBlock() { return new (DIEValueAllocator) DIEBlock(); }
void insertDIE(DIDescriptor Desc, DIE *D);
void addDie(DIE *Buffer) { UnitDie->addChild(Buffer); }
void addFlag(DIE *Die, dwarf::Attribute Attribute);
void addUInt(DIE *Die, dwarf::Attribute Attribute, Optional<dwarf::Form> Form,
uint64_t Integer);
void addUInt(DIEBlock *Block, dwarf::Form Form, uint64_t Integer);
void addSInt(DIE *Die, dwarf::Attribute Attribute, Optional<dwarf::Form> Form,
int64_t Integer);
void addSInt(DIEBlock *Die, Optional<dwarf::Form> Form, int64_t Integer);
void addString(DIE *Die, dwarf::Attribute Attribute, const StringRef Str);
void addLocalString(DIE *Die, dwarf::Attribute Attribute,
const StringRef Str);
void addExpr(DIEBlock *Die, dwarf::Form Form, const MCExpr *Expr);
void addLabel(DIE *Die, dwarf::Attribute Attribute, dwarf::Form Form,
const MCSymbol *Label);
void addLabel(DIEBlock *Die, dwarf::Form Form, const MCSymbol *Label);
void addSectionLabel(DIE *Die, dwarf::Attribute Attribute,
const MCSymbol *Label);
void addSectionOffset(DIE *Die, dwarf::Attribute Attribute, uint64_t Integer);
void addOpAddress(DIEBlock *Die, const MCSymbol *Label);
void addSectionDelta(DIE *Die, dwarf::Attribute Attribute, const MCSymbol *Hi,
const MCSymbol *Lo);
void addDIEEntry(DIE *Die, dwarf::Attribute Attribute, DIE *Entry);
void addDIEEntry(DIE *Die, dwarf::Attribute Attribute, DIEEntry *Entry);
void addDIETypeSignature(DIE *Die, const DwarfTypeUnit &Type);
void addBlock(DIE *Die, dwarf::Attribute Attribute, DIEBlock *Block);
void addSourceLine(DIE *Die, DIVariable V);
void addSourceLine(DIE *Die, DIGlobalVariable G);
void addSourceLine(DIE *Die, DISubprogram SP);
void addSourceLine(DIE *Die, DIType Ty);
void addSourceLine(DIE *Die, DINameSpace NS);
void addSourceLine(DIE *Die, DIModule M);
void addSourceLine(DIE *Die, DIObjCProperty Ty);
void addAddress(DIE *Die, dwarf::Attribute Attribute,
const MachineLocation &Location, bool Indirect = false);
void addConstantValue(DIE *Die, const MachineOperand &MO, DIType Ty);
void addConstantValue(DIE *Die, const ConstantInt *CI, bool Unsigned);
void addConstantValue(DIE *Die, const APInt &Val, bool Unsigned);
void addConstantFPValue(DIE *Die, const MachineOperand &MO);
void addConstantFPValue(DIE *Die, const ConstantFP *CFP);
void addTemplateParams(DIE &Buffer, DIArray TParams);
void addRegisterOp(DIEBlock *TheDie, unsigned Reg);
void addRegisterOffset(DIEBlock *TheDie, unsigned Reg, int64_t Offset);
void addComplexAddress(const DbgVariable &DV, DIE *Die,
dwarf::Attribute Attribute,
const MachineLocation &Location);
void addBlockByrefAddress(const DbgVariable &DV, DIE *Die,
dwarf::Attribute Attribute,
const MachineLocation &Location);
void addVariableAddress(const DbgVariable &DV, DIE *Die,
MachineLocation Location);
void addType(DIE *Entity, DIType Ty,
dwarf::Attribute Attribute = dwarf::DW_AT_type);
DIE *getOrCreateNameSpace(DINameSpace NS);
DIE *getOrCreateModule(DIModule M);
DIE *getOrCreateSubprogramDIE(DISubprogram SP);
DIE *getOrCreateTypeDIE(const MDNode *N);
DIE *createTypeDIE(DICompositeType Ty);
DIE *getOrCreateContextDIE(DIScope Context);
void constructContainingTypeDIEs();
DIE *constructVariableDIE(DbgVariable &DV, bool isScopeAbstract);
void constructSubprogramArguments(DIE &Buffer, DIArray Args);
DIE *createAndAddDIE(unsigned Tag, DIE &Parent,
DIDescriptor N = DIDescriptor());
virtual unsigned getHeaderSize() const {
return sizeof(int16_t) + sizeof(int32_t) + sizeof(int8_t); }
virtual void emitHeader(const MCSection *ASection,
const MCSymbol *ASectionSym) const;
protected:
DIE *getOrCreateStaticMemberDIE(DIDerivedType DT);
private:
void constructTypeDIE(DIE &Buffer, DIBasicType BTy);
void constructTypeDIE(DIE &Buffer, DIDerivedType DTy);
void constructTypeDIE(DIE &Buffer, DICompositeType CTy);
void constructSubrangeDIE(DIE &Buffer, DISubrange SR, DIE *IndexTy);
void constructArrayTypeDIE(DIE &Buffer, DICompositeType CTy);
void constructEnumTypeDIE(DIE &Buffer, DICompositeType CTy);
void constructMemberDIE(DIE &Buffer, DIDerivedType DT);
void constructTemplateTypeParameterDIE(DIE &Buffer,
DITemplateTypeParameter TP);
void constructTemplateValueParameterDIE(DIE &Buffer,
DITemplateValueParameter TVP);
int64_t getDefaultLowerBound() const;
DIEEntry *getDIEEntry(const MDNode *N) const {
return MDNodeToDIEEntryMap.lookup(N);
}
void insertDIEEntry(const MDNode *N, DIEEntry *E) {
MDNodeToDIEEntryMap.insert(std::make_pair(N, E));
}
DIE *getIndexTyDie() { return IndexTyDie; }
void setIndexTyDie(DIE *D) { IndexTyDie = D; }
DIEEntry *createDIEEntry(DIE *Entry);
template <typename T> T resolve(DIRef<T> Ref) const {
return DD->resolve(Ref);
}
void updateAcceleratorTables(DIScope Context, DIType Ty, const DIE *TyDIE);
};
class DwarfCompileUnit : public DwarfUnit {
public:
DwarfCompileUnit(unsigned UID, DIE *D, DICompileUnit Node, AsmPrinter *A,
DwarfDebug *DW, DwarfFile *DWU);
virtual ~DwarfCompileUnit() LLVM_OVERRIDE;
void createGlobalVariableDIE(DIGlobalVariable GV);
void addLabelAddress(DIE *Die, dwarf::Attribute Attribute, MCSymbol *Label);
};
class DwarfTypeUnit : public DwarfUnit {
private:
uint64_t TypeSignature;
const DIE *Ty;
public:
DwarfTypeUnit(unsigned UID, DIE *D, DICompileUnit CUNode, AsmPrinter *A,
DwarfDebug *DW, DwarfFile *DWU);
virtual ~DwarfTypeUnit() LLVM_OVERRIDE;
void setTypeSignature(uint64_t Signature) { TypeSignature = Signature; }
uint64_t getTypeSignature() const { return TypeSignature; }
void setType(const DIE *Ty) { this->Ty = Ty; }
void emitHeader(const MCSection *ASection, const MCSymbol *ASectionSym) const
LLVM_OVERRIDE;
unsigned getHeaderSize() const LLVM_OVERRIDE {
return DwarfUnit::getHeaderSize() + sizeof(uint64_t) + sizeof(uint32_t); }
void initSection(const MCSection *Section);
};
} #endif