X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FCodeGen%2FAsmPrinter%2FDwarfDebug.cpp;h=95dedb5549b6efbcb5cd6524ab4881c2a932c225;hp=75206d2d85d7516f359f7e590cef855a5a908bb5;hb=dc1d16ae54aceebdecc7262b2ef806387f98ace3;hpb=81a95a816bf3a020a30597c0cd86d7ebcc58f9c0 diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 75206d2d85d..95dedb5549b 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -169,10 +169,10 @@ static LLVM_CONSTEXPR DwarfAccelTable::Atom TypeAtoms[] = { DwarfAccelTable::Atom(dwarf::DW_ATOM_type_flags, dwarf::DW_FORM_data1)}; DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M) - : Asm(A), MMI(Asm->MMI), FirstCU(nullptr), PrevLabel(nullptr), - GlobalRangeCount(0), InfoHolder(A, "info_string", DIEValueAllocator), + : Asm(A), MMI(Asm->MMI), PrevLabel(nullptr), GlobalRangeCount(0), + InfoHolder(A, *this, "info_string", DIEValueAllocator), UsedNonDefaultText(false), - SkeletonHolder(A, "skel_string", DIEValueAllocator), + SkeletonHolder(A, *this, "skel_string", DIEValueAllocator), IsDarwin(Triple(A->getTargetTriple()).isOSDarwin()), AccelNames(DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4)), @@ -330,120 +330,18 @@ bool DwarfDebug::isLexicalScopeDIENull(LexicalScope *Scope) { return !getLabelAfterInsn(Ranges.front().second); } -DIE *DwarfDebug::createScopeChildrenDIE( - DwarfCompileUnit &TheCU, LexicalScope *Scope, - SmallVectorImpl> &Children, - unsigned *ChildScopeCount) { - DIE *ObjectPointer = nullptr; - - for (DbgVariable *DV : ScopeVariables.lookup(Scope)) - Children.push_back(TheCU.constructVariableDIE(*DV, *Scope, ObjectPointer)); - - unsigned ChildCountWithoutScopes = Children.size(); - - for (LexicalScope *LS : Scope->getChildren()) - TheCU.constructScopeDIE(LS, Children); - - if (ChildScopeCount) - *ChildScopeCount = Children.size() - ChildCountWithoutScopes; - - return ObjectPointer; -} - -DIE *DwarfDebug::createAndAddScopeChildren(DwarfCompileUnit &TheCU, - LexicalScope *Scope, DIE &ScopeDIE) { - // We create children when the scope DIE is not null. - SmallVector, 8> Children; - DIE *ObjectPointer = createScopeChildrenDIE(TheCU, Scope, Children); - - // Add children - for (auto &I : Children) - ScopeDIE.addChild(std::move(I)); - - return ObjectPointer; -} - -void DwarfDebug::constructAbstractSubprogramScopeDIE(DwarfCompileUnit &TheCU, - LexicalScope *Scope) { +void DwarfDebug::constructAbstractSubprogramScopeDIE(LexicalScope *Scope) { assert(Scope && Scope->getScopeNode()); assert(Scope->isAbstractScope()); assert(!Scope->getInlinedAt()); - DISubprogram SP(Scope->getScopeNode()); + const MDNode *SP = Scope->getScopeNode(); ProcessedSPNodes.insert(SP); - DIE *&AbsDef = AbstractSPDies[SP]; - if (AbsDef) - return; - // Find the subprogram's DwarfCompileUnit in the SPMap in case the subprogram // was inlined from another compile unit. - 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( - TheCU.constructVariableDIE(*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); + SPMap[SP]->constructAbstractSubprogramScopeDIE(Scope); } void DwarfDebug::addGnuPubAttributes(DwarfUnit &U, DIE &D) const { @@ -464,6 +362,8 @@ DwarfCompileUnit &DwarfDebug::constructDwarfCompileUnit(DICompileUnit DIUnit) { DwarfCompileUnit &NewCU = *OwnedUnit; DIE &Die = NewCU.getUnitDie(); InfoHolder.addUnit(std::move(OwnedUnit)); + if (useSplitDwarf()) + NewCU.setSkeleton(constructSkeletonCU(NewCU)); // LTO with assembly output shares a single line table amongst multiple CUs. // To avoid the compilation directory being ambiguous, let the line table @@ -500,14 +400,10 @@ DwarfCompileUnit &DwarfDebug::constructDwarfCompileUnit(DICompileUnit DIUnit) { NewCU.addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers, dwarf::DW_FORM_data1, RVer); - if (!FirstCU) - FirstCU = &NewCU; - - if (useSplitDwarf()) { + if (useSplitDwarf()) NewCU.initSection(Asm->getObjFileLowering().getDwarfInfoDWOSection(), DwarfInfoDWOSectionSym); - NewCU.setSkeleton(constructSkeletonCU(NewCU)); - } else + else NewCU.initSection(Asm->getObjFileLowering().getDwarfInfoSection(), DwarfInfoSectionSym); @@ -535,8 +431,6 @@ void DwarfDebug::beginModule() { FunctionDIs = makeSubprogramMap(*M); - // If module has named metadata anchors then use them, otherwise scan the - // module using debug info finder to collect debug info. NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); if (!CU_Nodes) return; @@ -611,38 +505,8 @@ void DwarfDebug::finishVariableDefinitions() { } 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(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 && TheCU.getEmissionKind() != DIBuilder::LineTablesOnly) - // Lazily construct the subprogram if we didn't see either concrete or - // inlined versions during codegen. (except in -gmlt ^ where we want - // to omit these entirely) - D = SPCU->getOrCreateSubprogramDIE(SP); - if (D) - // And attach the attributes - SPCU->applySubprogramAttributesToDefinition(SP, *D); - } - } - } + for (const auto &P : SPMap) + P.second->finishSubprogramDefinition(DISubprogram(P.first)); } @@ -662,26 +526,7 @@ void DwarfDebug::collectDeadVariables() { DISubprogram SP(Subprograms.getElement(i)); if (ProcessedSPNodes.count(SP) != 0) continue; - assert(SP.isSubprogram() && - "CU's subprogram list contains a non-subprogram"); - assert(SP.isDefinition() && - "CU's subprogram list contains a subprogram declaration"); - DIArray Variables = SP.getVariables(); - if (Variables.getNumElements() == 0) - continue; - - DIE *SPDIE = AbstractSPDies.lookup(SP); - if (!SPDIE) - SPDIE = SPCU->getDIE(SP); - assert(SPDIE); - for (unsigned vi = 0, ve = Variables.getNumElements(); vi != ve; ++vi) { - DIVariable DV(Variables.getElement(vi)); - assert(DV.isVariable()); - DbgVariable NewVar(DV, DIExpression(nullptr), this); - auto VariableDie = SPCU->constructVariableDIE(NewVar); - SPCU->applyVariableAttributes(NewVar, *VariableDie); - SPDIE->addChild(std::move(VariableDie)); - } + SPCU->collectDeadVariables(SP); } } } @@ -697,61 +542,58 @@ void DwarfDebug::finalizeModuleInfo() { // Handle anything that needs to be done on a per-unit basis after // all other generation. - for (const auto &TheU : getUnits()) { + for (const auto &P : CUMap) { + auto &TheCU = *P.second; // Emit DW_AT_containing_type attribute to connect types with their // vtable holding type. - TheU->constructContainingTypeDIEs(); + TheCU.constructContainingTypeDIEs(); // Add CU specific attributes if we need to add any. - if (TheU->getUnitDie().getTag() == dwarf::DW_TAG_compile_unit) { - // If we're splitting the dwarf out now that we've got the entire - // CU then add the dwo id to it. - DwarfCompileUnit *SkCU = - static_cast(TheU->getSkeleton()); - if (useSplitDwarf()) { - // Emit a unique identifier for this CU. - uint64_t ID = DIEHash(Asm).computeCUSignature(TheU->getUnitDie()); - TheU->addUInt(TheU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id, - dwarf::DW_FORM_data8, ID); - SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id, - dwarf::DW_FORM_data8, ID); - - // We don't keep track of which addresses are used in which CU so this - // is a bit pessimistic under LTO. - if (!AddrPool.isEmpty()) - SkCU->addSectionLabel(SkCU->getUnitDie(), dwarf::DW_AT_GNU_addr_base, - DwarfAddrSectionSym, DwarfAddrSectionSym); - if (!TheU->getRangeLists().empty()) - SkCU->addSectionLabel( - SkCU->getUnitDie(), dwarf::DW_AT_GNU_ranges_base, - DwarfDebugRangeSectionSym, DwarfDebugRangeSectionSym); - } + // If we're splitting the dwarf out now that we've got the entire + // CU then add the dwo id to it. + auto *SkCU = TheCU.getSkeleton(); + if (useSplitDwarf()) { + // Emit a unique identifier for this CU. + uint64_t ID = DIEHash(Asm).computeCUSignature(TheCU.getUnitDie()); + TheCU.addUInt(TheCU.getUnitDie(), dwarf::DW_AT_GNU_dwo_id, + dwarf::DW_FORM_data8, ID); + SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id, + dwarf::DW_FORM_data8, ID); + + // We don't keep track of which addresses are used in which CU so this + // is a bit pessimistic under LTO. + if (!AddrPool.isEmpty()) + SkCU->addSectionLabel(SkCU->getUnitDie(), dwarf::DW_AT_GNU_addr_base, + DwarfAddrSectionSym, DwarfAddrSectionSym); + if (!TheCU.getRangeLists().empty()) + SkCU->addSectionLabel(SkCU->getUnitDie(), dwarf::DW_AT_GNU_ranges_base, + DwarfDebugRangeSectionSym, + DwarfDebugRangeSectionSym); + } - // If we have code split among multiple sections or non-contiguous - // ranges of code then emit a DW_AT_ranges attribute on the unit that will - // remain in the .o file, otherwise add a DW_AT_low_pc. - // FIXME: We should use ranges allow reordering of code ala - // .subsections_via_symbols in mach-o. This would mean turning on - // ranges for all subprogram DIEs for mach-o. - DwarfCompileUnit &U = - SkCU ? *SkCU : static_cast(*TheU); - unsigned NumRanges = TheU->getRanges().size(); - if (NumRanges) { - if (NumRanges > 1) { - U.addSectionLabel(U.getUnitDie(), dwarf::DW_AT_ranges, - Asm->GetTempSymbol("cu_ranges", U.getUniqueID()), - DwarfDebugRangeSectionSym); - - // A DW_AT_low_pc attribute may also be specified in combination with - // DW_AT_ranges to specify the default base address for use in - // location lists (see Section 2.6.2) and range lists (see Section - // 2.17.3). - U.addUInt(U.getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, - 0); - } else { - RangeSpan &Range = TheU->getRanges().back(); - U.attachLowHighPC(U.getUnitDie(), Range.getStart(), Range.getEnd()); - } + // If we have code split among multiple sections or non-contiguous + // ranges of code then emit a DW_AT_ranges attribute on the unit that will + // remain in the .o file, otherwise add a DW_AT_low_pc. + // FIXME: We should use ranges allow reordering of code ala + // .subsections_via_symbols in mach-o. This would mean turning on + // ranges for all subprogram DIEs for mach-o. + DwarfCompileUnit &U = SkCU ? *SkCU : TheCU; + unsigned NumRanges = TheCU.getRanges().size(); + if (NumRanges) { + if (NumRanges > 1) { + U.addSectionLabel(U.getUnitDie(), dwarf::DW_AT_ranges, + Asm->GetTempSymbol("cu_ranges", U.getUniqueID()), + DwarfDebugRangeSectionSym); + + // A DW_AT_low_pc attribute may also be specified in combination with + // DW_AT_ranges to specify the default base address for use in + // location lists (see Section 2.6.2) and range lists (see Section + // 2.17.3). + U.addUInt(U.getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, 0); + } else { + const RangeSpan &Range = TheCU.getRanges().back(); + TheCU.setBaseAddress(Range.getStart()); + U.attachLowHighPC(U.getUnitDie(), Range.getStart(), Range.getEnd()); } } } @@ -814,7 +656,10 @@ void DwarfDebug::endModule() { assert(CurFn == nullptr); assert(CurMI == nullptr); - if (!FirstCU) + // If we aren't actually generating debug info (check beginModule - + // conditionalized on !DisableDebugInfoPrinting and the presence of the + // llvm.dbg.cu metadata node) + if (!DwarfInfoSectionSym) return; // End any existing sections. @@ -868,9 +713,6 @@ void DwarfDebug::endModule() { // clean up. SPMap.clear(); AbstractVariables.clear(); - - // Reset these for the next Module if we have one. - FirstCU = nullptr; } // Find abstract variable, if any, associated with Var. @@ -897,7 +739,7 @@ DbgVariable *DwarfDebug::getExistingAbstractVariable(const DIVariable &DV) { void DwarfDebug::createAbstractVariable(const DIVariable &Var, LexicalScope *Scope) { auto AbsDbgVariable = make_unique(Var, DIExpression(), this); - addScopeVariable(Scope, AbsDbgVariable.get()); + InfoHolder.addScopeVariable(Scope, AbsDbgVariable.get()); AbstractVariables[Var] = std::move(AbsDbgVariable); } @@ -921,29 +763,6 @@ DwarfDebug::ensureAbstractVariableIsCreatedIfScoped(const DIVariable &DV, createAbstractVariable(Cleansed, Scope); } -// If Var is a current function argument then add it to CurrentFnArguments list. -bool DwarfDebug::addCurrentFnArgument(DbgVariable *Var, LexicalScope *Scope) { - if (!LScopes.isCurrentFunctionScope(Scope)) - return false; - DIVariable DV = Var->getVariable(); - if (DV.getTag() != dwarf::DW_TAG_arg_variable) - return false; - unsigned ArgNo = DV.getArgNumber(); - if (ArgNo == 0) - return false; - - size_t Size = CurrentFnArguments.size(); - if (Size == 0) - CurrentFnArguments.resize(CurFn->getFunction()->arg_size()); - // llvm::Function argument size is not good indicator of how many - // arguments does the function have at source level. - if (ArgNo > Size) - CurrentFnArguments.resize(ArgNo * 2); - assert(!CurrentFnArguments[ArgNo - 1]); - CurrentFnArguments[ArgNo - 1] = Var; - return true; -} - // Collect variable information from side table maintained by MMI. void DwarfDebug::collectVariableInfoFromMMITable( SmallPtrSetImpl &Processed) { @@ -951,19 +770,19 @@ void DwarfDebug::collectVariableInfoFromMMITable( if (!VI.Var) continue; Processed.insert(VI.Var); - DIVariable DV(VI.Var); - DIExpression Expr(VI.Expr); LexicalScope *Scope = LScopes.findLexicalScope(VI.Loc); // If variable scope is not found then skip this variable. if (!Scope) continue; + DIVariable DV(VI.Var); + DIExpression Expr(VI.Expr); ensureAbstractVariableIsCreatedIfScoped(DV, Scope->getScopeNode()); ConcreteVariables.push_back(make_unique(DV, Expr, this)); DbgVariable *RegVar = ConcreteVariables.back().get(); RegVar->setFrameIndex(VI.Slot); - addScopeVariable(Scope, RegVar); + InfoHolder.addScopeVariable(Scope, RegVar); } } @@ -1111,10 +930,8 @@ DwarfDebug::buildLocationList(SmallVectorImpl &DebugLoc, // Find variables for each lexical scope. void -DwarfDebug::collectVariableInfo(SmallPtrSetImpl &Processed) { - LexicalScope *FnScope = LScopes.getCurrentFunctionScope(); - DwarfCompileUnit *TheCU = SPMap.lookup(FnScope->getScopeNode()); - +DwarfDebug::collectVariableInfo(DwarfCompileUnit &TheCU, DISubprogram SP, + SmallPtrSetImpl &Processed) { // Grab the variable info that was squirreled away in the MMI side-table. collectVariableInfoFromMMITable(Processed); @@ -1145,7 +962,7 @@ DwarfDebug::collectVariableInfo(SmallPtrSetImpl &Processed) { ensureAbstractVariableIsCreatedIfScoped(DV, Scope->getScopeNode()); ConcreteVariables.push_back(make_unique(MInsn, this)); DbgVariable *RegVar = ConcreteVariables.back().get(); - addScopeVariable(Scope, RegVar); + InfoHolder.addScopeVariable(Scope, RegVar); // Check if the first DBG_VALUE is valid for the rest of the function. if (Ranges.size() == 1 && Ranges.front().second == nullptr) @@ -1156,7 +973,7 @@ DwarfDebug::collectVariableInfo(SmallPtrSetImpl &Processed) { DotDebugLocEntries.resize(DotDebugLocEntries.size() + 1); DebugLocList &LocList = DotDebugLocEntries.back(); - LocList.CU = TheCU; + LocList.CU = &TheCU; LocList.Label = Asm->GetTempSymbol("debug_loc", DotDebugLocEntries.size() - 1); @@ -1165,7 +982,7 @@ DwarfDebug::collectVariableInfo(SmallPtrSetImpl &Processed) { } // Collect info for variables that were optimized out. - DIArray Variables = DISubprogram(FnScope->getScopeNode()).getVariables(); + DIArray Variables = SP.getVariables(); for (unsigned i = 0, e = Variables.getNumElements(); i != e; ++i) { DIVariable DV(Variables.getElement(i)); assert(DV.isVariable()); @@ -1175,7 +992,7 @@ DwarfDebug::collectVariableInfo(SmallPtrSetImpl &Processed) { ensureAbstractVariableIsCreatedIfScoped(DV, Scope->getScopeNode()); DIExpression NoExpr; ConcreteVariables.push_back(make_unique(DV, NoExpr, this)); - addScopeVariable(Scope, ConcreteVariables.back().get()); + InfoHolder.addScopeVariable(Scope, ConcreteVariables.back().get()); } } } @@ -1405,49 +1222,10 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) { } } -void DwarfDebug::addScopeVariable(LexicalScope *LS, DbgVariable *Var) { - if (addCurrentFnArgument(Var, LS)) - return; - SmallVectorImpl &Vars = ScopeVariables[LS]; - DIVariable DV = Var->getVariable(); - // Variables with positive arg numbers are parameters. - if (unsigned ArgNum = DV.getArgNumber()) { - // Keep all parameters in order at the start of the variable list to ensure - // function types are correct (no out-of-order parameters) - // - // This could be improved by only doing it for optimized builds (unoptimized - // builds have the right order to begin with), searching from the back (this - // would catch the unoptimized case quickly), or doing a binary search - // rather than linear search. - SmallVectorImpl::iterator I = Vars.begin(); - while (I != Vars.end()) { - unsigned CurNum = (*I)->getVariable().getArgNumber(); - // A local (non-parameter) variable has been found, insert immediately - // before it. - if (CurNum == 0) - break; - // A later indexed parameter has been found, insert immediately before it. - if (CurNum > ArgNum) - break; - ++I; - } - Vars.insert(I, Var); - return; - } - - Vars.push_back(Var); -} - // Gather and emit post-function debug information. void DwarfDebug::endFunction(const MachineFunction *MF) { - // Every beginFunction(MF) call should be followed by an endFunction(MF) call, - // though the beginFunction may not be called at all. - // We should handle both cases. - if (!CurFn) - CurFn = MF; - else - assert(CurFn == MF); - assert(CurFn != nullptr); + assert(CurFn == MF && + "endFunction should be called with the same function as beginFunction"); if (!MMI->hasDebugInfo() || LScopes.empty() || !FunctionDIs.count(MF->getFunction())) { @@ -1467,11 +1245,12 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { // Set DwarfDwarfCompileUnitID in MCContext to default value. Asm->OutStreamer.getContext().setDwarfCompileUnitID(0); - SmallPtrSet ProcessedVars; - collectVariableInfo(ProcessedVars); - LexicalScope *FnScope = LScopes.getCurrentFunctionScope(); - DwarfCompileUnit &TheCU = *SPMap.lookup(FnScope->getScopeNode()); + DISubprogram SP(FnScope->getScopeNode()); + DwarfCompileUnit &TheCU = *SPMap.lookup(SP); + + SmallPtrSet ProcessedVars; + collectVariableInfo(TheCU, SP, ProcessedVars); // Add the range of this function to the list of ranges for the CU. TheCU.addRange(RangeSpan(FunctionBeginSym, FunctionEndSym)); @@ -1480,9 +1259,10 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { // subroutines inside it. if (TheCU.getCUNode().getEmissionKind() == DIBuilder::LineTablesOnly && LScopes.getAbstractScopesList().empty() && !IsDarwin) { - assert(ScopeVariables.empty()); - assert(CurrentFnArguments.empty()); + assert(InfoHolder.getScopeVariables().empty()); assert(DbgValues.empty()); + // FIXME: This wouldn't be true in LTO with a -g (with inlining) CU followed + // by a -gmlt CU. Add a test and remove this assertion. assert(AbstractVariables.empty()); LabelsBeforeInsn.clear(); LabelsAfterInsn.clear(); @@ -1491,6 +1271,9 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { return; } +#ifndef NDEBUG + size_t NumAbstractScopes = LScopes.getAbstractScopesList().size(); +#endif // Construct abstract scopes. for (LexicalScope *AScope : LScopes.getAbstractScopesList()) { DISubprogram SP(AScope->getScopeNode()); @@ -1503,18 +1286,19 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { if (!ProcessedVars.insert(DV)) continue; ensureAbstractVariableIsCreated(DV, DV.getContext()); + assert(LScopes.getAbstractScopesList().size() == NumAbstractScopes + && "ensureAbstractVariableIsCreated inserted abstract scopes"); } - constructAbstractSubprogramScopeDIE(TheCU, AScope); + constructAbstractSubprogramScopeDIE(AScope); } - constructSubprogramScopeDIE(TheCU, FnScope); + TheCU.constructSubprogramScopeDIE(FnScope); // Clear debug info // Ownership of DbgVariables is a bit subtle - ScopeVariables owns all the // DbgVariables except those that are also in AbstractVariables (since they // can be used cross-function) - ScopeVariables.clear(); - CurrentFnArguments.clear(); + InfoHolder.getScopeVariables().clear(); DbgValues.clear(); LabelsBeforeInsn.clear(); LabelsAfterInsn.clear(); @@ -1645,7 +1429,7 @@ void DwarfDebug::emitDIE(DIE &Die) { void DwarfDebug::emitDebugInfo() { DwarfFile &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder; - Holder.emitUnits(this, DwarfAbbrevSectionSym); + Holder.emitUnits(DwarfAbbrevSectionSym); } // Emit the abbreviation section. @@ -1780,12 +1564,13 @@ void DwarfDebug::emitDebugPubNames(bool GnuStyle) { GnuStyle ? Asm->getObjFileLowering().getDwarfGnuPubNamesSection() : Asm->getObjFileLowering().getDwarfPubNamesSection(); - emitDebugPubSection(GnuStyle, PSec, "Names", &DwarfUnit::getGlobalNames); + emitDebugPubSection(GnuStyle, PSec, "Names", + &DwarfCompileUnit::getGlobalNames); } void DwarfDebug::emitDebugPubSection( bool GnuStyle, const MCSection *PSec, StringRef Name, - const StringMap &(DwarfUnit::*Accessor)() const) { + const StringMap &(DwarfCompileUnit::*Accessor)() const) { for (const auto &NU : CUMap) { DwarfCompileUnit *TheU = NU.second; @@ -1794,7 +1579,7 @@ void DwarfDebug::emitDebugPubSection( if (Globals.empty()) continue; - if (auto Skeleton = static_cast(TheU->getSkeleton())) + if (auto *Skeleton = TheU->getSkeleton()) TheU = Skeleton; unsigned ID = TheU->getUniqueID(); @@ -1816,7 +1601,7 @@ void DwarfDebug::emitDebugPubSection( Asm->EmitSectionOffset(TheU->getLabelBegin(), TheU->getSectionSym()); Asm->OutStreamer.AddComment("Compilation Unit Length"); - Asm->EmitLabelDifference(TheU->getLabelEnd(), TheU->getLabelBegin(), 4); + Asm->EmitInt32(TheU->getLength()); // Emit the pubnames for this compilation unit. for (const auto &GI : Globals) { @@ -1849,7 +1634,8 @@ void DwarfDebug::emitDebugPubTypes(bool GnuStyle) { GnuStyle ? Asm->getObjFileLowering().getDwarfGnuPubTypesSection() : Asm->getObjFileLowering().getDwarfPubTypesSection(); - emitDebugPubSection(GnuStyle, PSec, "Types", &DwarfUnit::getGlobalTypes); + emitDebugPubSection(GnuStyle, PSec, "Types", + &DwarfCompileUnit::getGlobalTypes); } // Emit visible names into a debug str section. @@ -2006,9 +1792,7 @@ void DwarfDebug::emitDebugLoc() { // Set up the range. This range is relative to the entry point of the // compile unit. This is a hard coded 0 for low_pc when we're emitting // ranges, or the DW_AT_low_pc on the compile unit otherwise. - if (CU->getRanges().size() == 1) { - // Grab the begin symbol from the first range as our base. - const MCSymbol *Base = CU->getRanges()[0].getStart(); + if (auto *Base = CU->getBaseAddress()) { Asm->EmitLabelDifference(Entry.getBeginSym(), Base, Size); Asm->EmitLabelDifference(Entry.getEndSym(), Base, Size); } else { @@ -2138,6 +1922,10 @@ void DwarfDebug::emitDebugARanges() { for (DwarfCompileUnit *CU : CUs) { std::vector &List = Spans[CU]; + // Describe the skeleton CU's offset and length, not the dwo file's. + if (auto *Skel = CU->getSkeleton()) + CU = Skel; + // Emit size of content not including length itself. unsigned ContentSize = sizeof(int16_t) + // DWARF ARange version number @@ -2160,7 +1948,7 @@ void DwarfDebug::emitDebugARanges() { Asm->OutStreamer.AddComment("DWARF Arange version number"); Asm->EmitInt16(dwarf::DW_ARANGES_VERSION); Asm->OutStreamer.AddComment("Offset Into Debug Info Section"); - Asm->EmitSectionOffset(CU->getLocalLabelBegin(), CU->getLocalSectionSym()); + Asm->EmitSectionOffset(CU->getLabelBegin(), CU->getSectionSym()); Asm->OutStreamer.AddComment("Address Size (in bytes)"); Asm->EmitInt8(PtrSize); Asm->OutStreamer.AddComment("Segment Size (in bytes)"); @@ -2214,9 +2002,7 @@ void DwarfDebug::emitDebugRanges() { const MCSymbol *End = Range.getEnd(); assert(Begin && "Range without a begin symbol?"); assert(End && "Range without an end symbol?"); - if (TheCU->getRanges().size() == 1) { - // Grab the begin symbol from the first range as our base. - const MCSymbol *Base = TheCU->getRanges()[0].getStart(); + if (auto *Base = TheCU->getBaseAddress()) { Asm->EmitLabelDifference(Begin, Base, Size); Asm->EmitLabelDifference(End, Base, Size); } else { @@ -2253,11 +2039,11 @@ void DwarfDebug::emitDebugRanges() { void DwarfDebug::initSkeletonUnit(const DwarfUnit &U, DIE &Die, std::unique_ptr NewU) { - NewU->addLocalString(Die, dwarf::DW_AT_GNU_dwo_name, - U.getCUNode().getSplitDebugFilename()); + NewU->addString(Die, dwarf::DW_AT_GNU_dwo_name, + U.getCUNode().getSplitDebugFilename()); if (!CompilationDir.empty()) - NewU->addLocalString(Die, dwarf::DW_AT_comp_dir, CompilationDir); + NewU->addString(Die, dwarf::DW_AT_comp_dir, CompilationDir); addGnuPubAttributes(*NewU, Die); @@ -2288,7 +2074,7 @@ void DwarfDebug::emitDebugInfoDWO() { assert(useSplitDwarf() && "No split dwarf debug info?"); // Don't pass an abbrev symbol, using a constant zero instead so as not to // emit relocations into the dwo file. - InfoHolder.emitUnits(this, /* AbbrevSymbol */ nullptr); + InfoHolder.emitUnits(/* AbbrevSymbol */ nullptr); } // Emit the .debug_abbrev.dwo section for separated dwarf. This contains the @@ -2369,8 +2155,7 @@ void DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU, NewTU.setTypeSignature(Signature); if (useSplitDwarf()) - NewTU.initSection(Asm->getObjFileLowering().getDwarfTypesDWOSection(), - DwarfTypesDWOSectionSym); + NewTU.initSection(Asm->getObjFileLowering().getDwarfTypesDWOSection()); else { CU.applyStmtList(UnitDie); NewTU.initSection(