- DwarfCompileUnit &SPCU = *SPMap[SP];
- DIE *ContextDIE;
-
- // Some of this is duplicated from DwarfUnit::getOrCreateSubprogramDIE, with
- // the important distinction that the DIDescriptor is not associated with the
- // DIE (since the DIDescriptor will be associated with the concrete DIE, if
- // any). It could be refactored to some common utility function.
- if (DISubprogram SPDecl = SP.getFunctionDeclaration()) {
- ContextDIE = &SPCU.getUnitDie();
- SPCU.getOrCreateSubprogramDIE(SPDecl);
- } else
- ContextDIE = SPCU.getOrCreateContextDIE(resolve(SP.getContext()));
-
- // Passing null as the associated DIDescriptor because the abstract definition
- // shouldn't be found by lookup.
- AbsDef = &SPCU.createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE,
- DIDescriptor());
- SPCU.applySubprogramAttributesToDefinition(SP, *AbsDef);
-
- if (TheCU.getCUNode().getEmissionKind() != DIBuilder::LineTablesOnly)
- SPCU.addUInt(*AbsDef, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined);
- if (DIE *ObjectPointer = createAndAddScopeChildren(SPCU, Scope, *AbsDef))
- SPCU.addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer);
-}
-
-void DwarfDebug::constructSubprogramScopeDIE(DwarfCompileUnit &TheCU,
- LexicalScope *Scope) {
- assert(Scope && Scope->getScopeNode());
- assert(!Scope->getInlinedAt());
- assert(!Scope->isAbstractScope());
- DISubprogram Sub(Scope->getScopeNode());
-
- assert(Sub.isSubprogram());
-
- ProcessedSPNodes.insert(Sub);
-
- DIE &ScopeDIE = TheCU.updateSubprogramScopeDIE(Sub);
-
- // Collect arguments for current function.
- assert(LScopes.isCurrentFunctionScope(Scope));
- DIE *ObjectPointer = nullptr;
- for (DbgVariable *ArgDV : CurrentFnArguments)
- if (ArgDV)
- ScopeDIE.addChild(
- constructVariableDIE(TheCU, *ArgDV, *Scope, ObjectPointer));
-
- // If this is a variadic function, add an unspecified parameter.
- DITypeArray FnArgs = Sub.getType().getTypeArray();
- // If we have a single element of null, it is a function that returns void.
- // If we have more than one elements and the last one is null, it is a
- // variadic function.
- if (FnArgs.getNumElements() > 1 &&
- !FnArgs.getElement(FnArgs.getNumElements() - 1))
- ScopeDIE.addChild(make_unique<DIE>(dwarf::DW_TAG_unspecified_parameters));
-
- // Collect lexical scope children first.
- // ObjectPointer might be a local (non-argument) local variable if it's a
- // block's synthetic this pointer.
- if (DIE *BlockObjPtr = createAndAddScopeChildren(TheCU, Scope, ScopeDIE)) {
- assert(!ObjectPointer && "multiple object pointers can't be described");
- ObjectPointer = BlockObjPtr;
- }
-
- if (ObjectPointer)
- TheCU.addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, *ObjectPointer);