DebugInfo: Partial implementation of DWARF type units.

Emit DW_TAG_type_units into the debug_info section using compile unit
headers. This is bogus/unusable by debuggers, but testable and provides
more isolated review.

Subsequent patches will include support for type unit headers and
emission into the debug_types section, as well as comdat grouping the
types based on their hash. Also the CompileUnit type will be renamed
'Unit' and relevant portions pulled out into respective CompileUnit and
TypeUnit types.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@195166 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
David Blaikie
2013-11-19 23:08:21 +00:00
parent d4010998b0
commit 6fe6dc19f8
8 changed files with 151 additions and 54 deletions

View File

@ -1051,22 +1051,6 @@ void DwarfDebug::finalizeModuleInfo() {
// Attach DW_AT_inline attribute with inlined subprogram DIEs.
computeInlinedDIEs();
// Split out type units and conditionally add an ODR tag to the split
// out type.
// FIXME: Do type splitting.
for (unsigned i = 0, e = TypeUnits.size(); i != e; ++i) {
DIE *Die = TypeUnits[i];
DIEHash Hash;
// If we've requested ODR hashes and it's applicable for an ODR hash then
// add the ODR signature now.
// FIXME: This should be added onto the type unit, not the type, but this
// works as an intermediate stage.
if (GenerateODRHash && shouldAddODRHash(CUMap.begin()->second, Die))
CUMap.begin()->second->addUInt(Die, dwarf::DW_AT_GNU_odr_signature,
dwarf::DW_FORM_data8,
Hash.computeDIEODRSignature(*Die));
}
// Handle anything that needs to be done on a per-cu basis.
for (DenseMap<const MDNode *, CompileUnit *>::iterator CUI = CUMap.begin(),
CUE = CUMap.end();
@ -2071,7 +2055,7 @@ void DwarfDebug::emitDIE(DIE *Die, ArrayRef<DIEAbbrev *> Abbrevs) {
// For DW_FORM_ref_addr, output the offset from beginning of debug info
// section. Origin->getOffset() returns the offset from start of the
// compile unit.
CompileUnit *CU = CUDieMap.lookup(Origin->getCompileUnit());
CompileUnit *CU = CUDieMap.lookup(Origin->getUnit());
assert(CU && "CUDie should belong to a CU.");
Addr += CU->getDebugInfoOffset();
if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
@ -2083,7 +2067,7 @@ void DwarfDebug::emitDIE(DIE *Die, ArrayRef<DIEAbbrev *> Abbrevs) {
DIEEntry::getRefAddrSize(Asm));
} else {
// Make sure Origin belong to the same CU.
assert(Die->getCompileUnit() == Origin->getCompileUnit() &&
assert(Die->getUnit() == Origin->getUnit() &&
"The referenced DIE should belong to the same CU in ref4");
Asm->EmitInt32(Addr);
}
@ -3063,3 +3047,57 @@ void DwarfDebug::emitDebugStrDWO() {
InfoHolder.emitStrings(Asm->getObjFileLowering().getDwarfStrDWOSection(),
OffSec, StrSym);
}
void DwarfDebug::addTypeUnitType(DIE *RefDie, DICompositeType CTy) {
DenseMap<const MDNode*, std::pair<uint64_t, SmallVectorImpl<DIE*>* > >::iterator I = TypeUnits.find(CTy);
SmallVector<DIE *, 8> References;
References.push_back(RefDie);
if (I != TypeUnits.end()) {
if (I->second.second) {
I->second.second->push_back(RefDie);
return;
}
} else {
DIE *UnitDie = new DIE(dwarf::DW_TAG_type_unit);
CompileUnit *NewCU =
new CompileUnit(GlobalCUIndexCount++, UnitDie,
dwarf::DW_LANG_C_plus_plus, Asm, this, &InfoHolder);
CUDieMap.insert(std::make_pair(UnitDie, NewCU));
NewCU->addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
dwarf::DW_LANG_C_plus_plus);
// Register the type in the TypeUnits map with a vector of references to be
// populated whenever a reference is required.
I = TypeUnits.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 = NewCU->createTypeDIE(CTy);
if (GenerateODRHash && shouldAddODRHash(NewCU, Die))
NewCU->addUInt(UnitDie, dwarf::DW_AT_GNU_odr_signature,
dwarf::DW_FORM_data8,
DIEHash().computeDIEODRSignature(*Die));
// FIXME: This won't handle circularly referential structures, as the DIE
// may have references to other DIEs still under construction and missing
// their signature. Hashing should walk through the signatures to their
// referenced type, or possibly walk the precomputed hashes of related types
// at the end.
uint64_t Signature = DIEHash().computeTypeSignature(*Die);
// Remove the References vector and add the type hash.
I->second.first = Signature;
I->second.second = NULL;
InfoHolder.addUnit(NewCU);
}
// 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);
}
}