X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FAsmPrinter%2FDwarfDebug.cpp;h=010dcdf05556a9a687d99055dafefd2f8cfc86a9;hb=ac07cd54ed48cdc160eba7625eefe09c5f484eb2;hp=90f370ccf7161be63cfdf2899d4cf57d0f138387;hpb=a3507d4883b8ec5fd068b28dda7e928f450ba883;p=oota-llvm.git diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 90f370ccf71..010dcdf0555 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -16,7 +16,7 @@ #include "DIE.h" #include "DIEHash.h" #include "DwarfAccelTable.h" -#include "DwarfCompileUnit.h" +#include "DwarfUnit.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringExtras.h" @@ -185,8 +185,8 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M) : Asm(A), MMI(Asm->MMI), FirstCU(0), AbbreviationsSet(InitAbbreviationsSetSize), SourceIdMap(DIEValueAllocator), PrevLabel(NULL), GlobalCUIndexCount(0), - InfoHolder(A, &AbbreviationsSet, Abbreviations, "info_string", - DIEValueAllocator), + GlobalRangeCount(0), InfoHolder(A, &AbbreviationsSet, Abbreviations, + "info_string", DIEValueAllocator), SkeletonAbbrevSet(InitAbbreviationsSetSize), SkeletonHolder(A, &SkeletonAbbrevSet, SkeletonAbbrevs, "skel_string", DIEValueAllocator) { @@ -197,6 +197,7 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M) DwarfAddrSectionSym = 0; DwarfAbbrevDWOSectionSym = DwarfStrDWOSectionSym = 0; FunctionBeginSym = FunctionEndSym = 0; + CurFn = 0; CurMI = 0; // Turn on accelerator tables for Darwin by default, pubnames by // default for non-Darwin, and handle split dwarf. @@ -241,8 +242,8 @@ static MCSymbol *emitSectionSym(AsmPrinter *Asm, const MCSection *Section, } DwarfUnits::~DwarfUnits() { - for (SmallVectorImpl::iterator I = CUs.begin(), E = CUs.end(); - I != E; ++I) + for (SmallVectorImpl::iterator I = CUs.begin(), E = CUs.end(); I != E; + ++I) delete *I; } @@ -341,26 +342,26 @@ static bool SectionSort(const MCSection *A, const MCSection *B) { // TODO: Determine whether or not we should add names for programs // that do not have a DW_AT_name or DW_AT_linkage_name field - this // is only slightly different than the lookup of non-standard ObjC names. -static void addSubprogramNames(CompileUnit *TheCU, DISubprogram SP, DIE *Die) { +static void addSubprogramNames(Unit *TheU, DISubprogram SP, DIE *Die) { if (!SP.isDefinition()) return; - TheCU->addAccelName(SP.getName(), Die); + TheU->addAccelName(SP.getName(), Die); // If the linkage name is different than the name, go ahead and output // that as well into the name table. if (SP.getLinkageName() != "" && SP.getName() != SP.getLinkageName()) - TheCU->addAccelName(SP.getLinkageName(), Die); + TheU->addAccelName(SP.getLinkageName(), Die); // If this is an Objective-C selector name add it to the ObjC accelerator // too. if (isObjCClass(SP.getName())) { StringRef Class, Category; getObjCClassCategory(SP.getName(), Class, Category); - TheCU->addAccelObjC(Class, Die); + TheU->addAccelObjC(Class, Die); if (Category != "") - TheCU->addAccelObjC(Category, Die); + TheU->addAccelObjC(Category, Die); // Also add the base method name to the name table. - TheCU->addAccelName(getObjCMethodName(SP.getName()), Die); + TheU->addAccelName(getObjCMethodName(SP.getName()), Die); } } @@ -390,7 +391,8 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(CompileUnit *SPCU, DISubprogram SP) { // concrete DIE twice. if (DIE *AbsSPDIE = AbstractSPDies.lookup(SP)) { // Pick up abstract subprogram DIE. - SPDie = SPCU->createAndAddDIE(dwarf::DW_TAG_subprogram, *SPCU->getCUDie()); + SPDie = + SPCU->createAndAddDIE(dwarf::DW_TAG_subprogram, *SPCU->getUnitDie()); SPCU->addDIEEntry(SPDie, dwarf::DW_AT_abstract_origin, AbsSPDIE); } else { DISubprogram SPDecl = SP.getFunctionDeclaration(); @@ -421,19 +423,19 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(CompileUnit *SPCU, DISubprogram SP) { SPCU->addDIEEntry(SPDie, dwarf::DW_AT_object_pointer, Arg); } DIE *SPDeclDie = SPDie; - SPDie = - SPCU->createAndAddDIE(dwarf::DW_TAG_subprogram, *SPCU->getCUDie()); + SPDie = SPCU->createAndAddDIE(dwarf::DW_TAG_subprogram, + *SPCU->getUnitDie()); SPCU->addDIEEntry(SPDie, dwarf::DW_AT_specification, SPDeclDie); } } } - SPCU->addLabelAddress( - SPDie, dwarf::DW_AT_low_pc, - Asm->GetTempSymbol("func_begin", Asm->getFunctionNumber())); - SPCU->addLabelAddress( - SPDie, dwarf::DW_AT_high_pc, - Asm->GetTempSymbol("func_end", Asm->getFunctionNumber())); + MCSymbol *FuncBegin = + Asm->GetTempSymbol("func_begin", Asm->getFunctionNumber()); + MCSymbol *FuncEnd = Asm->GetTempSymbol("func_end", Asm->getFunctionNumber()); + SPCU->addLabelAddress(SPDie, dwarf::DW_AT_low_pc, FuncBegin); + SPCU->addLabelAddress(SPDie, dwarf::DW_AT_high_pc, FuncEnd); + const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo(); MachineLocation Location(RI->getFrameRegister(*Asm->MF)); SPCU->addAddress(SPDie, dwarf::DW_AT_frame_base, Location); @@ -466,6 +468,25 @@ bool DwarfDebug::isLexicalScopeDIENull(LexicalScope *Scope) { return !End; } +void DwarfDebug::addScopeRangeList(CompileUnit *TheCU, DIE *ScopeDIE, + const SmallVectorImpl &Range) { + // Emit offset in .debug_range as a relocatable label. emitDIE will handle + // emitting it appropriately. + TheCU->addSectionLabel(ScopeDIE, dwarf::DW_AT_ranges, + Asm->GetTempSymbol("debug_ranges", GlobalRangeCount)); + RangeSpanList *List = new RangeSpanList(GlobalRangeCount++); + for (SmallVectorImpl::const_iterator RI = Range.begin(), + RE = Range.end(); + RI != RE; ++RI) { + RangeSpan Span(getLabelBeforeInsn(RI->first), + getLabelAfterInsn(RI->second)); + List->addRange(Span); + } + + // Add the range list to the set of ranges to be emitted. + TheCU->addRangeList(List); +} + // Construct new DW_TAG_lexical_block for this scope and attach // DW_AT_low_pc/DW_AT_high_pc labels. DIE *DwarfDebug::constructLexicalScopeDIE(CompileUnit *TheCU, @@ -477,30 +498,16 @@ DIE *DwarfDebug::constructLexicalScopeDIE(CompileUnit *TheCU, if (Scope->isAbstractScope()) return ScopeDIE; - const SmallVectorImpl &Ranges = Scope->getRanges(); - // If we have multiple ranges, emit them into the range section. - if (Ranges.size() > 1) { - // .debug_range section has not been laid out yet. Emit offset in - // .debug_range as a relocatable label. emitDIE will handle - // emitting it appropriately. - unsigned Offset = DebugRangeSymbols.size(); - TheCU->addSectionLabel(ScopeDIE, dwarf::DW_AT_ranges, - Asm->GetTempSymbol("debug_ranges", Offset)); - for (SmallVectorImpl::const_iterator RI = Ranges.begin(), - RE = Ranges.end(); - RI != RE; ++RI) { - DebugRangeSymbols.push_back(getLabelBeforeInsn(RI->first)); - DebugRangeSymbols.push_back(getLabelAfterInsn(RI->second)); - } + const SmallVectorImpl &ScopeRanges = Scope->getRanges(); - // Terminate the range list. - DebugRangeSymbols.push_back(NULL); - DebugRangeSymbols.push_back(NULL); + // If we have multiple ranges, emit them into the range section. + if (ScopeRanges.size() > 1) { + addScopeRangeList(TheCU, ScopeDIE, ScopeRanges); return ScopeDIE; } // Construct the address range for this DIE. - SmallVectorImpl::const_iterator RI = Ranges.begin(); + SmallVectorImpl::const_iterator RI = ScopeRanges.begin(); MCSymbol *Start = getLabelBeforeInsn(RI->first); MCSymbol *End = getLabelAfterInsn(RI->second); assert(End && "End label should not be null!"); @@ -518,8 +525,8 @@ DIE *DwarfDebug::constructLexicalScopeDIE(CompileUnit *TheCU, // represent this concrete inlined copy of the function. DIE *DwarfDebug::constructInlinedScopeDIE(CompileUnit *TheCU, LexicalScope *Scope) { - const SmallVectorImpl &Ranges = Scope->getRanges(); - assert(Ranges.empty() == false && + const SmallVectorImpl &ScopeRanges = Scope->getRanges(); + assert(ScopeRanges.empty() == false && "LexicalScope does not have instruction markers!"); if (!Scope->getScopeNode()) @@ -535,23 +542,11 @@ DIE *DwarfDebug::constructInlinedScopeDIE(CompileUnit *TheCU, DIE *ScopeDIE = new DIE(dwarf::DW_TAG_inlined_subroutine); TheCU->addDIEEntry(ScopeDIE, dwarf::DW_AT_abstract_origin, OriginDIE); - if (Ranges.size() > 1) { - // .debug_range section has not been laid out yet. Emit offset in - // .debug_range as a relocatable label. emitDIE will handle - // emitting it appropriately. - unsigned Offset = DebugRangeSymbols.size(); - TheCU->addSectionLabel(ScopeDIE, dwarf::DW_AT_ranges, - Asm->GetTempSymbol("debug_ranges", Offset)); - for (SmallVectorImpl::const_iterator RI = Ranges.begin(), - RE = Ranges.end(); - RI != RE; ++RI) { - DebugRangeSymbols.push_back(getLabelBeforeInsn(RI->first)); - DebugRangeSymbols.push_back(getLabelAfterInsn(RI->second)); - } - DebugRangeSymbols.push_back(NULL); - DebugRangeSymbols.push_back(NULL); - } else { - SmallVectorImpl::const_iterator RI = Ranges.begin(); + // If we have multiple ranges, emit them into the range section. + if (ScopeRanges.size() > 1) + addScopeRangeList(TheCU, ScopeDIE, ScopeRanges); + else { + SmallVectorImpl::const_iterator RI = ScopeRanges.begin(); MCSymbol *StartLabel = getLabelBeforeInsn(RI->first); MCSymbol *EndLabel = getLabelAfterInsn(RI->second); @@ -685,9 +680,6 @@ DIE *DwarfDebug::constructScopeDIE(CompileUnit *TheCU, LexicalScope *Scope) { if (DS.isSubprogram() && ObjectPointer != NULL) TheCU->addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, ObjectPointer); - if (DS.isSubprogram()) - TheCU->addPubTypes(DISubprogram(DS)); - return ScopeDIE; } @@ -1004,7 +996,7 @@ void DwarfDebug::collectDeadVariables() { continue; // Construct subprogram DIE and add variables DIEs. - CompileUnit *SPCU = CUMap.lookup(TheCU); + CompileUnit *SPCU = static_cast(CUMap.lookup(TheCU)); assert(SPCU && "Unable to find Compile Unit!"); // FIXME: See the comment in constructSubprogramDIE about duplicate // subprogram DIEs. @@ -1052,7 +1044,7 @@ static bool isContainedInAnonNamespace(DIE *Die) { /// Test if the current CU language is C++ and that we have /// a named type that is not contained in an anonymous namespace. -static bool shouldAddODRHash(CompileUnit *CU, DIE *Die) { +static bool shouldAddODRHash(TypeUnit *CU, DIE *Die) { return CU->getLanguage() == dwarf::DW_LANG_C_plus_plus && getDIEStringAttr(Die, dwarf::DW_AT_name) != "" && !isContainedInAnonNamespace(Die); @@ -1066,29 +1058,30 @@ void DwarfDebug::finalizeModuleInfo() { computeInlinedDIEs(); // Handle anything that needs to be done on a per-cu basis. - for (DenseMap::iterator CUI = CUMap.begin(), - CUE = CUMap.end(); - CUI != CUE; ++CUI) { - CompileUnit *TheCU = CUI->second; + for (SmallVectorImpl::const_iterator I = getUnits().begin(), + E = getUnits().end(); + I != E; ++I) { + Unit *TheU = *I; // Emit DW_AT_containing_type attribute to connect types with their // vtable holding type. - TheCU->constructContainingTypeDIEs(); + TheU->constructContainingTypeDIEs(); // If we're splitting the dwarf out now that we've got the entire // CU then construct a skeleton CU based upon it. - if (useSplitDwarf()) { + if (useSplitDwarf() && + TheU->getUnitDie()->getTag() == dwarf::DW_TAG_compile_unit) { uint64_t ID = 0; if (GenerateCUHash) { DIEHash CUHash; - ID = CUHash.computeCUSignature(*TheCU->getCUDie()); + ID = CUHash.computeCUSignature(*TheU->getUnitDie()); } // This should be a unique identifier when we want to build .dwp files. - TheCU->addUInt(TheCU->getCUDie(), dwarf::DW_AT_GNU_dwo_id, - dwarf::DW_FORM_data8, ID); + TheU->addUInt(TheU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id, + dwarf::DW_FORM_data8, ID); // Now construct the skeleton CU associated. - CompileUnit *SkCU = constructSkeletonCU(TheCU); + CompileUnit *SkCU = constructSkeletonCU(static_cast(TheU)); // This should be a unique identifier when we want to build .dwp files. - SkCU->addUInt(SkCU->getCUDie(), dwarf::DW_AT_GNU_dwo_id, + SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id, dwarf::DW_FORM_data8, ID); } } @@ -1152,6 +1145,8 @@ void DwarfDebug::endSections() { // Emit all Dwarf sections that should come after the content. void DwarfDebug::endModule() { + assert(CurFn == 0); + assert(CurMI == 0); if (!FirstCU) return; @@ -1233,8 +1228,7 @@ DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &DV, } // If Var is a current function argument then add it to CurrentFnArguments list. -bool DwarfDebug::addCurrentFnArgument(const MachineFunction *MF, - DbgVariable *Var, LexicalScope *Scope) { +bool DwarfDebug::addCurrentFnArgument(DbgVariable *Var, LexicalScope *Scope) { if (!LScopes.isCurrentFunctionScope(Scope)) return false; DIVariable DV = Var->getVariable(); @@ -1246,7 +1240,7 @@ bool DwarfDebug::addCurrentFnArgument(const MachineFunction *MF, size_t Size = CurrentFnArguments.size(); if (Size == 0) - CurrentFnArguments.resize(MF->getFunction()->arg_size()); + 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) @@ -1257,7 +1251,7 @@ bool DwarfDebug::addCurrentFnArgument(const MachineFunction *MF, // Collect variable information from side table maintained by MMI. void DwarfDebug::collectVariableInfoFromMMITable( - const MachineFunction *MF, SmallPtrSet &Processed) { + SmallPtrSet &Processed) { MachineModuleInfo::VariableDbgInfoMapTy &VMap = MMI->getVariableDbgInfo(); for (MachineModuleInfo::VariableDbgInfoMapTy::iterator VI = VMap.begin(), VE = VMap.end(); @@ -1278,7 +1272,7 @@ void DwarfDebug::collectVariableInfoFromMMITable( DbgVariable *AbsDbgVariable = findAbstractVariable(DV, VP.second); DbgVariable *RegVar = new DbgVariable(DV, AbsDbgVariable, this); RegVar->setFrameIndex(VP.first); - if (!addCurrentFnArgument(MF, RegVar, Scope)) + if (!addCurrentFnArgument(RegVar, Scope)) addScopeVariable(Scope, RegVar); if (AbsDbgVariable) AbsDbgVariable->setFrameIndex(VP.first); @@ -1325,11 +1319,10 @@ static DotDebugLocEntry getDebugLocEntry(AsmPrinter *Asm, // Find variables for each lexical scope. void -DwarfDebug::collectVariableInfo(const MachineFunction *MF, - SmallPtrSet &Processed) { +DwarfDebug::collectVariableInfo(SmallPtrSet &Processed) { // Grab the variable info that was squirreled away in the MMI side-table. - collectVariableInfoFromMMITable(MF, Processed); + collectVariableInfoFromMMITable(Processed); for (SmallVectorImpl::const_iterator UVI = UserVariables.begin(), @@ -1349,7 +1342,7 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF, DIVariable DV(Var); LexicalScope *Scope = NULL; if (DV.getTag() == dwarf::DW_TAG_arg_variable && - DISubprogram(DV.getContext()).describes(MF->getFunction())) + DISubprogram(DV.getContext()).describes(CurFn->getFunction())) Scope = LScopes.getCurrentFunctionScope(); else if (MDNode *IA = DV.getInlinedAt()) Scope = LScopes.findInlinedScope(DebugLoc::getFromDILocation(IA)); @@ -1363,7 +1356,7 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF, assert(MInsn->isDebugValue() && "History must begin with debug value"); DbgVariable *AbsVar = findAbstractVariable(DV, MInsn->getDebugLoc()); DbgVariable *RegVar = new DbgVariable(DV, AbsVar, this); - if (!addCurrentFnArgument(MF, RegVar, Scope)) + if (!addCurrentFnArgument(RegVar, Scope)) addScopeVariable(Scope, RegVar); if (AbsVar) AbsVar->setMInsn(MInsn); @@ -1445,6 +1438,8 @@ MCSymbol *DwarfDebug::getLabelAfterInsn(const MachineInstr *MI) { // Process beginning of an instruction. void DwarfDebug::beginInstruction(const MachineInstr *MI) { + assert(CurMI == 0); + CurMI = MI; // Check if source location changes, but ignore DBG_VALUE locations. if (!MI->isDebugValue()) { DebugLoc DL = MI->getDebugLoc(); @@ -1486,14 +1481,16 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) { } // Process end of an instruction. -void DwarfDebug::endInstruction(const MachineInstr *MI) { +void DwarfDebug::endInstruction() { + assert(CurMI != 0); // Don't create a new label after DBG_VALUE instructions. // They don't generate code. - if (!MI->isDebugValue()) + if (!CurMI->isDebugValue()) PrevLabel = 0; DenseMap::iterator I = - LabelsAfterInsn.find(MI); + LabelsAfterInsn.find(CurMI); + CurMI = 0; // No label needed. if (I == LabelsAfterInsn.end()) @@ -1573,6 +1570,7 @@ static DebugLoc getFnDebugLoc(DebugLoc DL, const LLVMContext &Ctx) { // Gather pre-function debug information. Assumes being called immediately // after the function entry point has been emitted. void DwarfDebug::beginFunction(const MachineFunction *MF) { + CurFn = MF; // If there's no debug info for the function we're not going to do anything. if (!MMI->hasDebugInfo()) @@ -1800,8 +1798,19 @@ void DwarfDebug::addScopeVariable(LexicalScope *LS, DbgVariable *Var) { // Gather and emit post-function debug information. void DwarfDebug::endFunction(const MachineFunction *MF) { - if (!MMI->hasDebugInfo() || LScopes.empty()) + // 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 == 0) + CurFn = MF; + else + assert(CurFn == MF); + assert(CurFn != 0); + + if (!MMI->hasDebugInfo() || LScopes.empty()) { + CurFn = 0; return; + } // Define end label for subprogram. FunctionEndSym = Asm->GetTempSymbol("func_end", Asm->getFunctionNumber()); @@ -1811,7 +1820,7 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { Asm->OutStreamer.getContext().setDwarfCompileUnitID(0); SmallPtrSet ProcessedVars; - collectVariableInfo(MF, ProcessedVars); + collectVariableInfo(ProcessedVars); LexicalScope *FnScope = LScopes.getCurrentFunctionScope(); CompileUnit *TheCU = SPMap.lookup(FnScope->getScopeNode()); @@ -1845,7 +1854,7 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { DIE *CurFnDIE = constructScopeDIE(TheCU, FnScope); - if (!MF->getTarget().Options.DisableFramePointerElim(*MF)) + if (!CurFn->getTarget().Options.DisableFramePointerElim(*CurFn)) TheCU->addFlag(CurFnDIE, dwarf::DW_AT_APPLE_omit_frame_ptr); // Clear debug info @@ -1861,6 +1870,7 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { LabelsBeforeInsn.clear(); LabelsAfterInsn.clear(); PrevLabel = NULL; + CurFn = 0; } // Register a source line with debug info. Returns the unique label that was @@ -1956,7 +1966,7 @@ void DwarfUnits::computeSizeAndOffsets() { // Iterate over each compile unit and set the size and offsets for each // DIE within each compile unit. All offsets are CU relative. - for (SmallVectorImpl::iterator I = CUs.begin(), E = CUs.end(); + for (SmallVectorImpl::const_iterator I = CUs.begin(), E = CUs.end(); I != E; ++I) { (*I)->setDebugInfoOffset(SecOffset); @@ -1966,7 +1976,7 @@ void DwarfUnits::computeSizeAndOffsets() { // EndOffset here is CU-relative, after laying out // all of the CU DIE. - unsigned EndOffset = computeSizeAndOffset((*I)->getCUDie(), Offset); + unsigned EndOffset = computeSizeAndOffset((*I)->getUnitDie(), Offset); SecOffset += EndOffset; } } @@ -2133,24 +2143,24 @@ void DwarfUnits::emitUnits(DwarfDebug *DD, const MCSection *USection, const MCSection *ASection, const MCSymbol *ASectionSym) { Asm->OutStreamer.SwitchSection(USection); - for (SmallVectorImpl::iterator I = CUs.begin(), E = CUs.end(); - I != E; ++I) { - CompileUnit *TheCU = *I; - DIE *Die = TheCU->getCUDie(); + for (SmallVectorImpl::iterator I = CUs.begin(), E = CUs.end(); I != E; + ++I) { + Unit *TheU = *I; + DIE *Die = TheU->getUnitDie(); // Emit the compile units header. - Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol(USection->getLabelBeginName(), - TheCU->getUniqueID())); + Asm->OutStreamer.EmitLabel( + Asm->GetTempSymbol(USection->getLabelBeginName(), TheU->getUniqueID())); // Emit size of content not including length itself Asm->OutStreamer.AddComment("Length of Unit"); - Asm->EmitInt32(TheCU->getHeaderSize() + Die->getSize()); + Asm->EmitInt32(TheU->getHeaderSize() + Die->getSize()); - TheCU->emitHeader(ASection, ASectionSym); + TheU->emitHeader(ASection, ASectionSym); DD->emitDIE(Die, Abbreviations); Asm->OutStreamer.EmitLabel( - Asm->GetTempSymbol(USection->getLabelEndName(), TheCU->getUniqueID())); + Asm->GetTempSymbol(USection->getLabelEndName(), TheU->getUniqueID())); } } @@ -2230,11 +2240,11 @@ void DwarfDebug::emitEndOfLineMatrix(unsigned SectionEnd) { void DwarfDebug::emitAccelNames() { DwarfAccelTable AT( DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4)); - for (DenseMap::iterator I = CUMap.begin(), - E = CUMap.end(); + for (SmallVectorImpl::const_iterator I = getUnits().begin(), + E = getUnits().end(); I != E; ++I) { - CompileUnit *TheCU = I->second; - const StringMap > &Names = TheCU->getAccelNames(); + Unit *TheU = *I; + const StringMap > &Names = TheU->getAccelNames(); for (StringMap >::const_iterator GI = Names.begin(), GE = Names.end(); @@ -2263,11 +2273,11 @@ void DwarfDebug::emitAccelNames() { void DwarfDebug::emitAccelObjC() { DwarfAccelTable AT( DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4)); - for (DenseMap::iterator I = CUMap.begin(), - E = CUMap.end(); + for (SmallVectorImpl::const_iterator I = getUnits().begin(), + E = getUnits().end(); I != E; ++I) { - CompileUnit *TheCU = I->second; - const StringMap > &Names = TheCU->getAccelObjC(); + Unit *TheU = *I; + const StringMap > &Names = TheU->getAccelObjC(); for (StringMap >::const_iterator GI = Names.begin(), GE = Names.end(); @@ -2295,12 +2305,12 @@ void DwarfDebug::emitAccelObjC() { void DwarfDebug::emitAccelNamespaces() { DwarfAccelTable AT( DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4)); - for (DenseMap::iterator I = CUMap.begin(), - E = CUMap.end(); + for (SmallVectorImpl::const_iterator I = getUnits().begin(), + E = getUnits().end(); I != E; ++I) { - CompileUnit *TheCU = I->second; + Unit *TheU = *I; const StringMap > &Names = - TheCU->getAccelNamespace(); + TheU->getAccelNamespace(); for (StringMap >::const_iterator GI = Names.begin(), GE = Names.end(); @@ -2334,12 +2344,12 @@ void DwarfDebug::emitAccelTypes() { Atoms.push_back( DwarfAccelTable::Atom(dwarf::DW_ATOM_type_flags, dwarf::DW_FORM_data1)); DwarfAccelTable AT(Atoms); - for (DenseMap::iterator I = CUMap.begin(), - E = CUMap.end(); + for (SmallVectorImpl::const_iterator I = getUnits().begin(), + E = getUnits().end(); I != E; ++I) { - CompileUnit *TheCU = I->second; + Unit *TheU = *I; const StringMap > > &Names = - TheCU->getAccelTypes(); + TheU->getAccelTypes(); for (StringMap< std::vector > >::const_iterator GI = Names.begin(), @@ -2381,7 +2391,7 @@ void DwarfDebug::emitAccelTypes() { // reference in the pubname header doesn't change. /// computeIndexValue - Compute the gdb index value for the DIE and CU. -static dwarf::PubIndexEntryDescriptor computeIndexValue(CompileUnit *CU, +static dwarf::PubIndexEntryDescriptor computeIndexValue(Unit *CU, const DIE *Die) { dwarf::GDBIndexEntryLinkage Linkage = dwarf::GIEL_STATIC; @@ -2431,10 +2441,11 @@ void DwarfDebug::emitDebugPubNames(bool GnuStyle) { GnuStyle ? Asm->getObjFileLowering().getDwarfGnuPubNamesSection() : Asm->getObjFileLowering().getDwarfPubNamesSection(); - typedef DenseMap CUMapType; - for (CUMapType::iterator I = CUMap.begin(), E = CUMap.end(); I != E; ++I) { - CompileUnit *TheCU = I->second; - unsigned ID = TheCU->getUniqueID(); + for (SmallVectorImpl::const_iterator I = getUnits().begin(), + E = getUnits().end(); + I != E; ++I) { + Unit *TheU = *I; + unsigned ID = TheU->getUniqueID(); // Start the dwarf pubnames section. Asm->OutStreamer.SwitchSection(PSec); @@ -2442,7 +2453,7 @@ void DwarfDebug::emitDebugPubNames(bool GnuStyle) { // Emit a label so we can reference the beginning of this pubname section. if (GnuStyle) Asm->OutStreamer.EmitLabel( - Asm->GetTempSymbol("gnu_pubnames", TheCU->getUniqueID())); + Asm->GetTempSymbol("gnu_pubnames", TheU->getUniqueID())); // Emit the header. Asm->OutStreamer.AddComment("Length of Public Names Info"); @@ -2464,7 +2475,7 @@ void DwarfDebug::emitDebugPubNames(bool GnuStyle) { 4); // Emit the pubnames for this compilation unit. - const StringMap &Globals = TheCU->getGlobalNames(); + const StringMap &Globals = TheU->getGlobalNames(); for (StringMap::const_iterator GI = Globals.begin(), GE = Globals.end(); GI != GE; ++GI) { @@ -2475,7 +2486,7 @@ void DwarfDebug::emitDebugPubNames(bool GnuStyle) { Asm->EmitInt32(Entity->getOffset()); if (GnuStyle) { - dwarf::PubIndexEntryDescriptor Desc = computeIndexValue(TheCU, Entity); + dwarf::PubIndexEntryDescriptor Desc = computeIndexValue(TheU, Entity); Asm->OutStreamer.AddComment( Twine("Kind: ") + dwarf::GDBIndexEntryKindString(Desc.Kind) + ", " + dwarf::GDBIndexEntryLinkageString(Desc.Linkage)); @@ -2499,26 +2510,26 @@ void DwarfDebug::emitDebugPubTypes(bool GnuStyle) { GnuStyle ? Asm->getObjFileLowering().getDwarfGnuPubTypesSection() : Asm->getObjFileLowering().getDwarfPubTypesSection(); - for (DenseMap::iterator I = CUMap.begin(), - E = CUMap.end(); + for (SmallVectorImpl::const_iterator I = getUnits().begin(), + E = getUnits().end(); I != E; ++I) { - CompileUnit *TheCU = I->second; + Unit *TheU = *I; // Start the dwarf pubtypes section. Asm->OutStreamer.SwitchSection(PSec); // Emit a label so we can reference the beginning of this pubtype section. if (GnuStyle) Asm->OutStreamer.EmitLabel( - Asm->GetTempSymbol("gnu_pubtypes", TheCU->getUniqueID())); + Asm->GetTempSymbol("gnu_pubtypes", TheU->getUniqueID())); // Emit the header. Asm->OutStreamer.AddComment("Length of Public Types Info"); Asm->EmitLabelDifference( - Asm->GetTempSymbol("pubtypes_end", TheCU->getUniqueID()), - Asm->GetTempSymbol("pubtypes_begin", TheCU->getUniqueID()), 4); + Asm->GetTempSymbol("pubtypes_end", TheU->getUniqueID()), + Asm->GetTempSymbol("pubtypes_begin", TheU->getUniqueID()), 4); Asm->OutStreamer.EmitLabel( - Asm->GetTempSymbol("pubtypes_begin", TheCU->getUniqueID())); + Asm->GetTempSymbol("pubtypes_begin", TheU->getUniqueID())); if (Asm->isVerbose()) Asm->OutStreamer.AddComment("DWARF Version"); @@ -2526,16 +2537,16 @@ void DwarfDebug::emitDebugPubTypes(bool GnuStyle) { Asm->OutStreamer.AddComment("Offset of Compilation Unit Info"); Asm->EmitSectionOffset( - Asm->GetTempSymbol(ISec->getLabelBeginName(), TheCU->getUniqueID()), + Asm->GetTempSymbol(ISec->getLabelBeginName(), TheU->getUniqueID()), DwarfInfoSectionSym); Asm->OutStreamer.AddComment("Compilation Unit Length"); Asm->EmitLabelDifference( - Asm->GetTempSymbol(ISec->getLabelEndName(), TheCU->getUniqueID()), - Asm->GetTempSymbol(ISec->getLabelBeginName(), TheCU->getUniqueID()), 4); + Asm->GetTempSymbol(ISec->getLabelEndName(), TheU->getUniqueID()), + Asm->GetTempSymbol(ISec->getLabelBeginName(), TheU->getUniqueID()), 4); // Emit the pubtypes. - const StringMap &Globals = TheCU->getGlobalTypes(); + const StringMap &Globals = TheU->getGlobalTypes(); for (StringMap::const_iterator GI = Globals.begin(), GE = Globals.end(); GI != GE; ++GI) { @@ -2547,7 +2558,7 @@ void DwarfDebug::emitDebugPubTypes(bool GnuStyle) { Asm->EmitInt32(Entity->getOffset()); if (GnuStyle) { - dwarf::PubIndexEntryDescriptor Desc = computeIndexValue(TheCU, Entity); + dwarf::PubIndexEntryDescriptor Desc = computeIndexValue(TheU, Entity); Asm->OutStreamer.AddComment( Twine("Kind: ") + dwarf::GDBIndexEntryKindString(Desc.Kind) + ", " + dwarf::GDBIndexEntryLinkageString(Desc.Linkage)); @@ -2564,7 +2575,7 @@ void DwarfDebug::emitDebugPubTypes(bool GnuStyle) { Asm->OutStreamer.AddComment("End Mark"); Asm->EmitInt32(0); Asm->OutStreamer.EmitLabel( - Asm->GetTempSymbol("pubtypes_end", TheCU->getUniqueID())); + Asm->GetTempSymbol("pubtypes_end", TheU->getUniqueID())); } } @@ -2768,7 +2779,7 @@ struct SymbolCUSorter { } }; -static bool CUSort(const CompileUnit *A, const CompileUnit *B) { +static bool CUSort(const Unit *A, const Unit *B) { return (A->getUniqueID() < B->getUniqueID()); } @@ -2922,18 +2933,51 @@ void DwarfDebug::emitDebugRanges() { // Start the dwarf ranges section. Asm->OutStreamer.SwitchSection( Asm->getObjFileLowering().getDwarfRangesSection()); + + // Size for our labels. unsigned char Size = Asm->getDataLayout().getPointerSize(); - for (uint32_t i = 0, e = DebugRangeSymbols.size(); i < e; ++i) { - // Only emit a symbol for every range pair for now. - // FIXME: Make this per range list. - if ((i % 2) == 0) - Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_ranges", i)); - - const MCSymbol *I = DebugRangeSymbols[i]; - if (I) - Asm->OutStreamer.EmitSymbolValue(I, Size); - else + + // Grab the specific ranges for the compile units in the module. + for (DenseMap::iterator I = CUMap.begin(), + E = CUMap.end(); + I != E; ++I) { + CompileUnit *TheCU = I->second; + unsigned ID = TheCU->getUniqueID(); + + // Emit a symbol so we can find the beginning of our ranges. + Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("gnu_ranges", ID)); + + // Iterate over the misc ranges for the compile units in the module. + const SmallVectorImpl &RangeLists = TheCU->getRangeLists(); + for (SmallVectorImpl::const_iterator + I = RangeLists.begin(), + E = RangeLists.end(); + I != E; ++I) { + RangeSpanList *List = *I; + + // Emit a symbol so we can find the beginning of the range. + Asm->OutStreamer.EmitLabel( + Asm->GetTempSymbol("debug_ranges", List->getIndex())); + + for (SmallVectorImpl::const_iterator + I = List->getRanges().begin(), + E = List->getRanges().end(); + I != E; ++I) { + RangeSpan Range = *I; + // We occasionally have ranges without begin/end labels. + // FIXME: Verify and fix. + const MCSymbol *Begin = Range.getStart(); + const MCSymbol *End = Range.getEnd(); + Begin ? Asm->OutStreamer.EmitSymbolValue(Begin, Size) + : Asm->OutStreamer.EmitIntValue(0, Size); + End ? Asm->OutStreamer.EmitSymbolValue(End, Size) + : Asm->OutStreamer.EmitIntValue(0, Size); + } + + // And terminate the list with two 0 values. + Asm->OutStreamer.EmitIntValue(0, Size); Asm->OutStreamer.EmitIntValue(0, Size); + } } } @@ -3007,14 +3051,17 @@ CompileUnit *DwarfDebug::constructSkeletonCU(const CompileUnit *CU) { DwarfGnuPubTypesSectionSym); } - // Flag if we've emitted any ranges and their location for the compile unit. - if (DebugRangeSymbols.size()) { + // Attribute if we've emitted any ranges and their location for the compile unit. + if (CU->getRangeLists().size()) { if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) - NewCU->addSectionLabel(Die, dwarf::DW_AT_GNU_ranges_base, - DwarfDebugRangeSectionSym); + NewCU->addSectionLabel( + Die, dwarf::DW_AT_GNU_ranges_base, + Asm->GetTempSymbol("gnu_ranges", NewCU->getUniqueID())); else - NewCU->addUInt(Die, dwarf::DW_AT_GNU_ranges_base, dwarf::DW_FORM_data4, - 0); + NewCU->addSectionDelta( + Die, dwarf::DW_AT_GNU_ranges_base, + Asm->GetTempSymbol("gnu_ranges", NewCU->getUniqueID()), + DwarfDebugRangeSectionSym); } SkeletonHolder.addUnit(NewCU); @@ -3056,8 +3103,11 @@ void DwarfDebug::emitDebugStrDWO() { OffSec, StrSym); } -void DwarfDebug::addTypeUnitType(DIE *RefDie, DICompositeType CTy) { - DenseMap* > >::iterator I = TypeUnits.find(CTy); +void DwarfDebug::addTypeUnitType(uint16_t Language, DIE *RefDie, + DICompositeType CTy) { + DenseMap *> >::iterator I = + TypeUnits.find(CTy); SmallVector References; References.push_back(RefDie); if (I != TypeUnits.end()) { @@ -3067,12 +3117,10 @@ void DwarfDebug::addTypeUnitType(DIE *RefDie, DICompositeType CTy) { } } else { DIE *UnitDie = new DIE(dwarf::DW_TAG_type_unit); - CompileUnit *NewCU = - new CompileUnit(GlobalCUIndexCount++, UnitDie, - dwarf::DW_LANG_C_plus_plus, Asm, this, &InfoHolder); - CUDieMap.insert(std::make_pair(UnitDie, NewCU)); - NewCU->addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2, - dwarf::DW_LANG_C_plus_plus); + 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. @@ -3082,10 +3130,10 @@ void DwarfDebug::addTypeUnitType(DIE *RefDie, DICompositeType CTy) { // 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 = NewCU->createTypeDIE(CTy); + DIE *Die = NewTU->createTypeDIE(CTy); - if (GenerateODRHash && shouldAddODRHash(NewCU, Die)) - NewCU->addUInt(UnitDie, dwarf::DW_AT_GNU_odr_signature, + 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 @@ -3099,8 +3147,7 @@ void DwarfDebug::addTypeUnitType(DIE *RefDie, DICompositeType CTy) { I->second.first = Signature; I->second.second = NULL; - - InfoHolder.addUnit(NewCU); + InfoHolder.addUnit(NewTU); } // Populate all the signatures.