#include "DIE.h"
#include "DwarfDebug.h"
+#include "DwarfUnit.h"
#include "llvm/ADT/Twine.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/IR/DataLayout.h"
}
#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
//===----------------------------------------------------------------------===//
class MCSymbol;
class MCSymbolRefExpr;
class raw_ostream;
+ class DwarfTypeUnit;
//===--------------------------------------------------------------------===//
/// DIEAbbrevData - Dwarf abbreviation data, describes one attribute of a
isLabel,
isDelta,
isEntry,
+ isTypeSignature,
isBlock
};
protected:
#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.
//
void DwarfDebug::addDwarfTypeUnitType(uint16_t Language, DIE *RefDie,
DICompositeType CTy) {
- DenseMap<const MDNode *,
- std::pair<uint64_t, SmallVectorImpl<DIE *> *> >::iterator I =
- DwarfTypeUnits.find(CTy);
- SmallVector<DIE *, 8> 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))
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);
}
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<const MDNode *, std::pair<uint64_t, SmallVectorImpl<DIE *> *> >
- DwarfTypeUnits;
+ // Map from MDNodes for user-defined types to the type units that describe
+ // them.
+ DenseMap<const MDNode *, const DwarfTypeUnit *> DwarfTypeUnits;
// Whether to emit the pubnames/pubtypes sections.
bool HasDwarfPubSections;
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();
/// 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);
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; }