+
+void DwarfDebug::addTypeUnitType(uint16_t Language, 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);
+ TypeUnit *NewTU = new TypeUnit(GlobalCUIndexCount++, UnitDie, Language, Asm,
+ this, &InfoHolder);
+ NewTU->addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
+ Language);
+
+ // 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 = NewTU->createTypeDIE(CTy);
+
+ if (GenerateODRHash && shouldAddODRHash(NewTU, Die))
+ NewTU->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(NewTU);
+ }
+
+ // 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);
+ }
+}