diff --git a/lib/CodeGen/AsmPrinter/DIE.cpp b/lib/CodeGen/AsmPrinter/DIE.cpp index 264d89152cf..e973541ee5b 100644 --- a/lib/CodeGen/AsmPrinter/DIE.cpp +++ b/lib/CodeGen/AsmPrinter/DIE.cpp @@ -13,6 +13,7 @@ #include "DIE.h" #include "DwarfDebug.h" +#include "DwarfUnit.h" #include "llvm/ADT/Twine.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/IR/DataLayout.h" @@ -403,6 +404,22 @@ void DIEEntry::print(raw_ostream &O) const { } #endif +//===----------------------------------------------------------------------===// +// DIETypeSignature Implementation +//===----------------------------------------------------------------------===// +void DIETypeSignature::EmitValue(AsmPrinter *Asm, dwarf::Form Form) const { + assert(Form == dwarf::DW_FORM_ref_sig8); + Asm->OutStreamer.EmitIntValue(Unit.getTypeSignature(), 8); +} + +#ifndef NDEBUG +void DIETypeSignature::print(raw_ostream &O) const { + O << format("Type Unit: 0x%lx", Unit.getTypeSignature()); +} + +void DIETypeSignature::dump() const { print(dbgs()); } +#endif + //===----------------------------------------------------------------------===// // DIEBlock Implementation //===----------------------------------------------------------------------===// diff --git a/lib/CodeGen/AsmPrinter/DIE.h b/lib/CodeGen/AsmPrinter/DIE.h index e28ddd38bc4..1655c8f1b20 100644 --- a/lib/CodeGen/AsmPrinter/DIE.h +++ b/lib/CodeGen/AsmPrinter/DIE.h @@ -26,6 +26,7 @@ namespace llvm { class MCSymbol; class MCSymbolRefExpr; class raw_ostream; + class DwarfTypeUnit; //===--------------------------------------------------------------------===// /// DIEAbbrevData - Dwarf abbreviation data, describes one attribute of a @@ -195,6 +196,7 @@ namespace llvm { isLabel, isDelta, isEntry, + isTypeSignature, isBlock }; protected: @@ -411,6 +413,33 @@ namespace llvm { #endif }; + //===--------------------------------------------------------------------===// + /// \brief A signature reference to a type unit. + class DIETypeSignature : public DIEValue { + const DwarfTypeUnit &Unit; + public: + explicit DIETypeSignature(const DwarfTypeUnit &Unit) + : DIEValue(isTypeSignature), Unit(Unit) {} + + /// \brief Emit type unit signature. + virtual void EmitValue(AsmPrinter *Asm, dwarf::Form Form) const; + + /// Returns size of a ref_sig8 entry. + virtual unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const { + assert(Form == dwarf::DW_FORM_ref_sig8); + return 8; + } + + // \brief Implement isa/cast/dyncast. + static bool classof(const DIEValue *E) { + return E->getType() == isTypeSignature; + } +#ifndef NDEBUG + virtual void print(raw_ostream &O) const; + void dump() const; +#endif + }; + //===--------------------------------------------------------------------===// /// DIEBlock - A block of values. Primarily used for location expressions. // diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 7c61407e873..06ad1624383 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -3015,35 +3015,18 @@ void DwarfDebug::emitDebugStrDWO() { void DwarfDebug::addDwarfTypeUnitType(uint16_t Language, DIE *RefDie, DICompositeType CTy) { - DenseMap *> >::iterator I = - DwarfTypeUnits.find(CTy); - SmallVector References; - References.push_back(RefDie); - if (I != DwarfTypeUnits.end()) { - if (I->second.second) { - I->second.second->push_back(RefDie); - return; - } - } else { + const DwarfTypeUnit *&TU = DwarfTypeUnits[CTy]; + if (!TU) { DIE *UnitDie = new DIE(dwarf::DW_TAG_type_unit); DwarfTypeUnit *NewTU = new DwarfTypeUnit(InfoHolder.getUnits().size(), UnitDie, Language, Asm, this, &InfoHolder); + TU = NewTU; InfoHolder.addUnit(NewTU); NewTU->addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2, Language); - // Register the type in the DwarfTypeUnits map with a vector of references - // to be - // populated whenever a reference is required. - I = DwarfTypeUnits.insert(std::make_pair( - CTy, std::make_pair(0, &References))).first; - - // Construct the type, this may, recursively, require more type units that - // may in turn require this type again - in which case they will add DIEs to - // the References vector. DIE *Die = NewTU->createTypeDIE(CTy); if (GenerateODRHash && shouldAddODRHash(NewTU, Die)) @@ -3059,19 +3042,11 @@ void DwarfDebug::addDwarfTypeUnitType(uint16_t Language, DIE *RefDie, NewTU->setTypeSignature(Signature); NewTU->setType(Die); - // Remove the References vector and add the type hash. - I->second.first = Signature; - I->second.second = NULL; - NewTU->initSection( useSplitDwarf() ? Asm->getObjFileLowering().getDwarfTypesDWOSection(Signature) : Asm->getObjFileLowering().getDwarfTypesSection(Signature)); } - // Populate all the signatures. - for (unsigned i = 0, e = References.size(); i != e; ++i) { - CUMap.begin()->second->addUInt(References[i], dwarf::DW_AT_signature, - dwarf::DW_FORM_ref_sig8, I->second.first); - } + CUMap.begin()->second->addDIETypeSignature(RefDie, *TU); } diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h index 2eda0e883ee..10ce17fa2dd 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -450,13 +450,9 @@ class DwarfDebug : public AsmPrinterHandler { ImportedEntityMap; ImportedEntityMap ScopesWithImportedEntities; - // Map from type MDNodes to a pair used as a union. If the pointer is - // non-null, proxy DIEs in CUs meant to reference this type should be stored - // in the vector. The hash will be added to these DIEs once it is computed. If - // the pointer is null, the hash is immediately available in the uint64_t and - // should be directly used for proxy DIEs. - DenseMap *> > - DwarfTypeUnits; + // Map from MDNodes for user-defined types to the type units that describe + // them. + DenseMap DwarfTypeUnits; // Whether to emit the pubnames/pubtypes sections. bool HasDwarfPubSections; diff --git a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index 87a38912448..85a76287434 100644 --- a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -322,6 +322,11 @@ void DwarfUnit::addDIEEntry(DIE *Die, dwarf::Attribute Attribute, DIE *Entry) { addDIEEntry(Die, Attribute, createDIEEntry(Entry)); } +void DwarfUnit::addDIETypeSignature(DIE *Die, const DwarfTypeUnit &Type) { + Die->addValue(dwarf::DW_AT_signature, dwarf::DW_FORM_ref_sig8, + new (DIEValueAllocator) DIETypeSignature(Type)); +} + void DwarfUnit::addDIEEntry(DIE *Die, dwarf::Attribute Attribute, DIEEntry *Entry) { const DIE *DieCU = Die->getUnitOrNull(); diff --git a/lib/CodeGen/AsmPrinter/DwarfUnit.h b/lib/CodeGen/AsmPrinter/DwarfUnit.h index 98623db7a61..5f9d4837967 100644 --- a/lib/CodeGen/AsmPrinter/DwarfUnit.h +++ b/lib/CodeGen/AsmPrinter/DwarfUnit.h @@ -319,6 +319,8 @@ public: /// 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); @@ -524,6 +526,7 @@ public: 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 LLVM_OVERRIDE { return Language; }