+void DwarfDebug::finishVariableDefinitions() {
+ for (const auto &Var : ConcreteVariables) {
+ DIE *VariableDie = Var->getDIE();
+ // FIXME: There shouldn't be any variables without DIEs.
+ if (!VariableDie)
+ continue;
+ // FIXME: Consider the time-space tradeoff of just storing the unit pointer
+ // in the ConcreteVariables list, rather than looking it up again here.
+ // DIE::getUnit isn't simple - it walks parent pointers, etc.
+ DwarfCompileUnit *Unit = lookupUnit(VariableDie->getUnit());
+ assert(Unit);
+ DbgVariable *AbsVar = getExistingAbstractVariable(Var->getVariable());
+ if (AbsVar && AbsVar->getDIE()) {
+ Unit->addDIEEntry(*VariableDie, dwarf::DW_AT_abstract_origin,
+ *AbsVar->getDIE());
+ } else
+ Unit->applyVariableAttributes(*Var, *VariableDie);
+ }
+}
+
+void DwarfDebug::finishSubprogramDefinitions() {
+ const Module *M = MMI->getModule();
+
+ NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
+ for (MDNode *N : CU_Nodes->operands()) {
+ DICompileUnit TheCU(N);
+ // Construct subprogram DIE and add variables DIEs.
+ DwarfCompileUnit *SPCU =
+ static_cast<DwarfCompileUnit *>(CUMap.lookup(TheCU));
+ DIArray Subprograms = TheCU.getSubprograms();
+ for (unsigned i = 0, e = Subprograms.getNumElements(); i != e; ++i) {
+ DISubprogram SP(Subprograms.getElement(i));
+ // Perhaps the subprogram is in another CU (such as due to comdat
+ // folding, etc), in which case ignore it here.
+ if (SPMap[SP] != SPCU)
+ continue;
+ DIE *D = SPCU->getDIE(SP);
+ if (DIE *AbsSPDIE = AbstractSPDies.lookup(SP)) {
+ if (D)
+ // If this subprogram has an abstract definition, reference that
+ SPCU->addDIEEntry(*D, dwarf::DW_AT_abstract_origin, *AbsSPDIE);
+ } else {
+ if (!D)
+ // Lazily construct the subprogram if we didn't see either concrete or
+ // inlined versions during codegen.
+ D = SPCU->getOrCreateSubprogramDIE(SP);
+ // And attach the attributes
+ SPCU->applySubprogramAttributesToDefinition(SP, *D);
+ }
+ }
+ }
+}
+
+