#include "llvm/ADT/StringMap.h"
#include "llvm/DebugInfo.h"
#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCSection.h"
namespace llvm {
//===----------------------------------------------------------------------===//
/// Unit - This dwarf writer support class manages information associated
/// with a source file.
-class Unit {
+class DwarfUnit {
protected:
/// UniqueID - a numeric ID unique among all CUs in the module
unsigned UniqueID;
/// Node - MDNode for the compile unit.
- DICompileUnit Node;
+ DICompileUnit CUNode;
/// Unit debug information entry.
const OwningPtr<DIE> UnitDie;
/// corresponds to the MDNode mapped with the subprogram DIE.
DenseMap<DIE *, const MDNode *> ContainingTypeMap;
+ // List of ranges for a given compile unit.
+ SmallVector<RangeSpan, 1> CURanges;
+
// List of range lists for a given compile unit, separate from the ranges for
// the CU itself.
SmallVector<RangeSpanList, 1> CURangeLists;
// DIEIntegerOne - A preallocated DIEValue because 1 is used frequently.
DIEInteger *DIEIntegerOne;
- Unit(unsigned UID, DIE *D, DICompileUnit CU, AsmPrinter *A, DwarfDebug *DW,
- DwarfFile *DWU);
+ /// The section this unit will be emitted in.
+ const MCSection *Section;
+
+ /// A label at the start of the non-dwo section related to this unit.
+ MCSymbol *SectionSym;
+
+ /// The start of the unit within its section.
+ MCSymbol *LabelBegin;
+
+ /// The end of the unit within its section.
+ MCSymbol *LabelEnd;
+
+ /// The label for the start of the range sets for the elements of this unit.
+ MCSymbol *LabelRange;
+
+ /// Skeleton unit associated with this unit.
+ DwarfUnit *Skeleton;
+
+ DwarfUnit(unsigned UID, DIE *D, DICompileUnit CU, AsmPrinter *A,
+ DwarfDebug *DW, DwarfFile *DWU);
public:
- virtual ~Unit();
+ virtual ~DwarfUnit();
+
+ /// Set the skeleton unit associated with this unit.
+ void setSkeleton(DwarfUnit *Skel) { Skeleton = Skel; }
+
+ /// Get the skeleton unit associated with this unit.
+ DwarfUnit *getSkeleton() const { return Skeleton; }
+
+ /// Pass in the SectionSym even though we could recreate it in every compile
+ /// unit (type units will have actually distinct symbols once they're in
+ /// comdat sections).
+ 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;
+ }
+
+ /// If there's a skeleton then return the section symbol for the skeleton
+ /// unit, otherwise return the section symbol for this unit.
+ MCSymbol *getLocalSectionSym() const {
+ if (Skeleton)
+ return Skeleton->getSectionSym();
+ return getSectionSym();
+ }
+
+ MCSymbol *getSectionSym() const {
+ assert(Section);
+ return SectionSym;
+ }
+
+ /// If there's a skeleton then return the begin label for the skeleton unit,
+ /// otherwise return the local label for this unit.
+ 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;
+ }
// Accessors.
unsigned getUniqueID() const { return UniqueID; }
- virtual uint16_t getLanguage() const = 0;
- DICompileUnit getNode() const { return Node; }
+ 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; }
/// hasContent - Return true if this compile unit has something to write out.
bool hasContent() const { return !UnitDie->getChildren().empty(); }
+ /// addRange - Add an address range to the list of ranges for this unit.
+ void addRange(RangeSpan Range) { CURanges.push_back(Range); }
+
+ /// getRanges - Get the list of ranges for this unit.
+ const SmallVectorImpl<RangeSpan> &getRanges() const { return CURanges; }
+ SmallVectorImpl<RangeSpan> &getRanges() { return CURanges; }
+
/// addRangeList - Add an address range list to the list of range lists.
void addRangeList(RangeSpanList Ranges) { CURangeLists.push_back(Ranges); }
/// addDIEEntry - Add a DIE attribute data and value.
void addDIEEntry(DIE *Die, dwarf::Attribute Attribute, DIEEntry *Entry);
+ void addDIETypeSignature(DIE *Die, const DwarfTypeUnit &Type);
+
/// addBlock - Add block data.
void addBlock(DIE *Die, dwarf::Attribute Attribute, DIEBlock *Block);
/// Compute the size of a header for this unit, not including the initial
/// length field.
- unsigned getHeaderSize() const {
+ virtual unsigned getHeaderSize() const {
return sizeof(int16_t) + // DWARF version number
sizeof(int32_t) + // Offset Into Abbrev. Section
sizeof(int8_t); // Pointer Size (in bytes)
}
/// Emit the header for this unit, not including the initial length field.
- void emitHeader(const MCSection *ASection, const MCSymbol *ASectionSym);
+ virtual void emitHeader(const MCSection *ASection,
+ const MCSymbol *ASectionSym) const;
protected:
/// getOrCreateStaticMemberDIE - Create new static data member DIE.
void updateAcceleratorTables(DIScope Context, DIType Ty, const DIE *TyDIE);
};
-class CompileUnit : public Unit {
+class DwarfCompileUnit : public DwarfUnit {
+ unsigned statementListIndex;
+
public:
- CompileUnit(unsigned UID, DIE *D, DICompileUnit Node, AsmPrinter *A,
- DwarfDebug *DW, DwarfFile *DWU);
+ DwarfCompileUnit(unsigned UID, DIE *D, DICompileUnit Node, AsmPrinter *A,
+ DwarfDebug *DW, DwarfFile *DWU);
+ virtual ~DwarfCompileUnit() LLVM_OVERRIDE;
/// createGlobalVariableDIE - create global variable DIE.
void createGlobalVariableDIE(DIGlobalVariable GV);
/// either DW_FORM_addr or DW_FORM_GNU_addr_index.
void addLabelAddress(DIE *Die, dwarf::Attribute Attribute, MCSymbol *Label);
- uint16_t getLanguage() const { return getNode().getLanguage(); }
+ void setStatementListIndex(unsigned statementListIndex) {
+ this->statementListIndex = statementListIndex;
+ }
+
+ void initStatementList(DIE *D) const {
+ DIE *UD = getUnitDie();
+ D->addValue(dwarf::DW_AT_stmt_list,
+ UD->getAbbrev().getData()[statementListIndex].getForm(),
+ UD->getValues()[statementListIndex]);
+ }
};
-class TypeUnit : public Unit {
+class DwarfTypeUnit : public DwarfUnit {
private:
- uint16_t Language;
+ uint64_t TypeSignature;
+ const DIE *Ty;
public:
- TypeUnit(unsigned UID, DIE *D, uint16_t Language, AsmPrinter *A,
- DwarfDebug *DW, DwarfFile *DWU);
+ 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; }
- uint16_t getLanguage() const { return Language; }
+ /// Emit the header for this unit, not including the initial length field.
+ void emitHeader(const MCSection *ASection, const MCSymbol *ASectionSym) const
+ LLVM_OVERRIDE;
+ unsigned getHeaderSize() const LLVM_OVERRIDE {
+ return DwarfUnit::getHeaderSize() + sizeof(uint64_t) + // Type Signature
+ sizeof(uint32_t); // Type DIE Offset
+ }
+ void initSection(const MCSection *Section);
};
} // end llvm namespace
#endif