X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FAsmPrinter%2FDwarfDebug.cpp;h=663ebef250bfab5a7269d070f80b5991e4894f05;hb=9e0dae166f9616e6b33b1bc7d8f493cb5b5e4f1b;hp=7f8d152a691a690137bc084deada1ccf31b94d93;hpb=622de3b2eb0901585f1e83749787f60b0bf59204;p=oota-llvm.git diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 7f8d152a691..663ebef250b 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -346,9 +346,7 @@ bool DwarfDebug::isLexicalScopeDIENull(LexicalScope *Scope) { // We don't create a DIE if we have a single Range and the end label // is null. - SmallVectorImpl::const_iterator RI = Ranges.begin(); - MCSymbol *End = getLabelAfterInsn(RI->second); - return !End; + return !getLabelAfterInsn(Ranges.front().second); } static void addSectionLabel(AsmPrinter &Asm, DwarfUnit &U, DIE &D, @@ -457,48 +455,35 @@ static std::unique_ptr constructVariableDIE(DwarfCompileUnit &TheCU, DIE *DwarfDebug::createScopeChildrenDIE( DwarfCompileUnit &TheCU, LexicalScope *Scope, - SmallVectorImpl> &Children) { + SmallVectorImpl> &Children, + unsigned *ChildScopeCount) { DIE *ObjectPointer = nullptr; - // Collect arguments for current function. - if (LScopes.isCurrentFunctionScope(Scope)) { - for (DbgVariable *ArgDV : CurrentFnArguments) - if (ArgDV) - Children.push_back( - constructVariableDIE(TheCU, *ArgDV, *Scope, ObjectPointer)); - - // If this is a variadic function, add an unspecified parameter. - DISubprogram SP(Scope->getScopeNode()); - DITypeArray FnArgs = SP.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)) - Children.push_back( - make_unique(dwarf::DW_TAG_unspecified_parameters)); - } - - // Collect lexical scope children first. for (DbgVariable *DV : ScopeVariables.lookup(Scope)) Children.push_back(constructVariableDIE(TheCU, *DV, *Scope, ObjectPointer)); + unsigned ChildCountWithoutScopes = Children.size(); + for (LexicalScope *LS : Scope->getChildren()) - if (std::unique_ptr Nested = constructScopeDIE(TheCU, LS)) - Children.push_back(std::move(Nested)); + constructScopeDIE(TheCU, LS, Children); + + if (ChildScopeCount) + *ChildScopeCount = Children.size() - ChildCountWithoutScopes; + return ObjectPointer; } -void DwarfDebug::createAndAddScopeChildren(DwarfCompileUnit &TheCU, +DIE *DwarfDebug::createAndAddScopeChildren(DwarfCompileUnit &TheCU, LexicalScope *Scope, DIE &ScopeDIE) { // We create children when the scope DIE is not null. SmallVector, 8> Children; - if (DIE *ObjectPointer = createScopeChildrenDIE(TheCU, Scope, Children)) - TheCU.addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, *ObjectPointer); + DIE *ObjectPointer = createScopeChildrenDIE(TheCU, Scope, Children); // Add children for (auto &I : Children) ScopeDIE.addChild(std::move(I)); + + return ObjectPointer; } void DwarfDebug::constructAbstractSubprogramScopeDIE(DwarfCompileUnit &TheCU, @@ -537,7 +522,8 @@ void DwarfDebug::constructAbstractSubprogramScopeDIE(DwarfCompileUnit &TheCU, SPCU.applySubprogramAttributesToDefinition(SP, *AbsDef); SPCU.addUInt(*AbsDef, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined); - createAndAddScopeChildren(SPCU, Scope, *AbsDef); + if (DIE *ObjectPointer = createAndAddScopeChildren(SPCU, Scope, *AbsDef)) + SPCU.addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer); } DIE &DwarfDebug::constructSubprogramScopeDIE(DwarfCompileUnit &TheCU, @@ -553,16 +539,43 @@ DIE &DwarfDebug::constructSubprogramScopeDIE(DwarfCompileUnit &TheCU, DIE &ScopeDIE = updateSubprogramScopeDIE(TheCU, Sub); - createAndAddScopeChildren(TheCU, Scope, ScopeDIE); + // 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(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); return ScopeDIE; } // Construct a DIE for this scope. -std::unique_ptr DwarfDebug::constructScopeDIE(DwarfCompileUnit &TheCU, - LexicalScope *Scope) { +void DwarfDebug::constructScopeDIE( + DwarfCompileUnit &TheCU, LexicalScope *Scope, + SmallVectorImpl> &FinalChildren) { if (!Scope || !Scope->getScopeNode()) - return nullptr; + return; DIScope DS(Scope->getScopeNode()); @@ -580,17 +593,19 @@ std::unique_ptr DwarfDebug::constructScopeDIE(DwarfCompileUnit &TheCU, if (Scope->getParent() && DS.isSubprogram()) { ScopeDIE = constructInlinedScopeDIE(TheCU, Scope); if (!ScopeDIE) - return nullptr; + return; // We create children when the scope DIE is not null. createScopeChildrenDIE(TheCU, Scope, Children); } else { // Early exit when we know the scope DIE is going to be null. if (isLexicalScopeDIENull(Scope)) - return nullptr; + return; + + unsigned ChildScopeCount; // We create children here when we know the scope DIE is not going to be // null and the children will be added to the scope DIE. - createScopeChildrenDIE(TheCU, Scope, Children); + createScopeChildrenDIE(TheCU, Scope, Children, &ChildScopeCount); // There is no need to emit empty lexical block DIE. std::pair DwarfDebug::constructScopeDIE(DwarfCompileUnit &TheCU, ScopesWithImportedEntities.end(), std::pair(DS, nullptr), less_first()); - if (Children.empty() && Range.first == Range.second) - return nullptr; - ScopeDIE = constructLexicalScopeDIE(TheCU, Scope); - assert(ScopeDIE && "Scope DIE should not be null."); for (ImportedEntityMap::const_iterator i = Range.first; i != Range.second; ++i) - constructImportedEntityDIE(TheCU, i->second, *ScopeDIE); + Children.push_back( + constructImportedEntityDIE(TheCU, DIImportedEntity(i->second))); + // If there are only other scopes as children, put them directly in the + // parent instead, as this scope would serve no purpose. + if (Children.size() == ChildScopeCount) { + FinalChildren.insert(FinalChildren.end(), + std::make_move_iterator(Children.begin()), + std::make_move_iterator(Children.end())); + return; + } + ScopeDIE = constructLexicalScopeDIE(TheCU, Scope); + assert(ScopeDIE && "Scope DIE should not be null."); } // Add children for (auto &I : Children) ScopeDIE->addChild(std::move(I)); - return ScopeDIE; + FinalChildren.push_back(std::move(ScopeDIE)); } void DwarfDebug::addGnuPubAttributes(DwarfUnit &U, DIE &D) const { @@ -685,27 +707,21 @@ DwarfCompileUnit &DwarfDebug::constructDwarfCompileUnit(DICompileUnit DIUnit) { return NewCU; } -void DwarfDebug::constructImportedEntityDIE(DwarfCompileUnit &TheCU, - const MDNode *N) { +void DwarfDebug::constructAndAddImportedEntityDIE(DwarfCompileUnit &TheCU, + const MDNode *N) { DIImportedEntity Module(N); assert(Module.Verify()); if (DIE *D = TheCU.getOrCreateContextDIE(Module.getContext())) - constructImportedEntityDIE(TheCU, Module, *D); + D->addChild(constructImportedEntityDIE(TheCU, Module)); } -void DwarfDebug::constructImportedEntityDIE(DwarfCompileUnit &TheCU, - const MDNode *N, DIE &Context) { - DIImportedEntity Module(N); - assert(Module.Verify()); - return constructImportedEntityDIE(TheCU, Module, Context); -} - -void DwarfDebug::constructImportedEntityDIE(DwarfCompileUnit &TheCU, - const DIImportedEntity &Module, - DIE &Context) { +std::unique_ptr +DwarfDebug::constructImportedEntityDIE(DwarfCompileUnit &TheCU, + const DIImportedEntity &Module) { assert(Module.Verify() && "Use one of the MDNode * overloads to handle invalid metadata"); - DIE &IMDie = TheCU.createAndAddDIE(Module.getTag(), Context, Module); + std::unique_ptr IMDie = make_unique((dwarf::Tag)Module.getTag()); + TheCU.insertDIE(Module, IMDie.get()); DIE *EntityDie; DIDescriptor Entity = resolve(Module.getEntity()); if (Entity.isNameSpace()) @@ -716,13 +732,16 @@ void DwarfDebug::constructImportedEntityDIE(DwarfCompileUnit &TheCU, EntityDie = TheCU.getOrCreateTypeDIE(DIType(Entity)); else EntityDie = TheCU.getDIE(Entity); - TheCU.addSourceLine(IMDie, Module.getLineNumber(), + assert(EntityDie); + TheCU.addSourceLine(*IMDie, Module.getLineNumber(), Module.getContext().getFilename(), Module.getContext().getDirectory()); - TheCU.addDIEEntry(IMDie, dwarf::DW_AT_import, *EntityDie); + TheCU.addDIEEntry(*IMDie, dwarf::DW_AT_import, *EntityDie); StringRef Name = Module.getName(); if (!Name.empty()) - TheCU.addString(IMDie, dwarf::DW_AT_name, Name); + TheCU.addString(*IMDie, dwarf::DW_AT_name, Name); + + return IMDie; } // Emit all Dwarf sections that should come prior to the content. Create @@ -783,7 +802,7 @@ void DwarfDebug::beginModule() { // Emit imported_modules last so that the relevant context is already // available. for (unsigned i = 0, e = ImportedEntities.getNumElements(); i != e; ++i) - constructImportedEntityDIE(CU, ImportedEntities.getElement(i)); + constructAndAddImportedEntityDIE(CU, ImportedEntities.getElement(i)); } // Tell MMI that we have debug info. @@ -1648,7 +1667,6 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { // If we don't have a lexical scope for this function then there will // be a hole in the range information. Keep note of this by setting the // previously used section to nullptr. - PrevSection = nullptr; PrevCU = nullptr; CurFn = nullptr; return; @@ -1691,7 +1709,6 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { // Add the range of this function to the list of ranges for the CU. RangeSpan Span(FunctionBeginSym, FunctionEndSym); TheCU.addRange(std::move(Span)); - PrevSection = Asm->getCurrentSection(); PrevCU = &TheCU; // Clear debug info