X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FAsmPrinter%2FDwarfDebug.cpp;h=010dcdf05556a9a687d99055dafefd2f8cfc86a9;hb=ac07cd54ed48cdc160eba7625eefe09c5f484eb2;hp=068bce5f5de7a0fd3a5379d9d9788e10a8bc212a;hpb=08e51e1d97e4dd2e5a0b4539da186869916ae5c3;p=oota-llvm.git diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 068bce5f5de..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" @@ -63,10 +63,9 @@ GenerateODRHash("generate-odr-hash", cl::Hidden, cl::desc("Add an ODR hash to external type DIEs."), cl::init(false)); -static cl::opt -GenerateCUHash("generate-cu-hash", cl::Hidden, - cl::desc("Add the CU hash as the dwo_id."), - cl::init(false)); +static cl::opt GenerateCUHash("generate-cu-hash", cl::Hidden, + cl::desc("Add the CU hash as the dwo_id."), + cl::init(false)); static cl::opt GenerateGnuPubSections("generate-gnu-dwarf-pub-sections", cl::Hidden, @@ -105,6 +104,11 @@ DwarfPubSections("generate-dwarf-pub-sections", cl::Hidden, clEnumVal(Disable, "Disabled"), clEnumValEnd), cl::init(Default)); +static cl::opt +DwarfVersionNumber("dwarf-version", cl::Hidden, + cl::desc("Generate DWARF for dwarf version."), + cl::init(0)); + static const char *const DWARFGroupName = "DWARF Emission"; static const char *const DbgTimerName = "DWARF Debug Writer"; @@ -118,8 +122,7 @@ namespace llvm { /// resolve - Look in the DwarfDebug map for the MDNode that /// corresponds to the reference. -template -T DbgVariable::resolve(DIRef Ref) const { +template T DbgVariable::resolve(DIRef Ref) const { return DD->resolve(Ref); } @@ -160,7 +163,7 @@ DIType DbgVariable::getType() const { DIArray Elements = DICompositeType(subType).getTypeArray(); for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) { - DIDerivedType DT = DIDerivedType(Elements.getElement(i)); + DIDerivedType DT(Elements.getElement(i)); if (getName() == DT.getName()) return (resolve(DT.getTypeDerivedFrom())); } @@ -179,15 +182,14 @@ static unsigned getDwarfVersionFromModule(const Module *M) { } 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), - SkeletonAbbrevSet(InitAbbreviationsSetSize), - SkeletonHolder(A, &SkeletonAbbrevSet, SkeletonAbbrevs, "skel_string", - DIEValueAllocator) { + : Asm(A), MMI(Asm->MMI), FirstCU(0), + AbbreviationsSet(InitAbbreviationsSetSize), + SourceIdMap(DIEValueAllocator), PrevLabel(NULL), GlobalCUIndexCount(0), + GlobalRangeCount(0), InfoHolder(A, &AbbreviationsSet, Abbreviations, + "info_string", DIEValueAllocator), + SkeletonAbbrevSet(InitAbbreviationsSetSize), + SkeletonHolder(A, &SkeletonAbbrevSet, SkeletonAbbrevs, "skel_string", + DIEValueAllocator) { DwarfInfoSectionSym = DwarfAbbrevSectionSym = 0; DwarfStrSectionSym = TextSectionSym = 0; @@ -195,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. @@ -215,7 +218,9 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M) else HasDwarfPubSections = DwarfPubSections == Enable; - DwarfVersion = getDwarfVersionFromModule(MMI->getModule()); + DwarfVersion = DwarfVersionNumber + ? DwarfVersionNumber + : getDwarfVersionFromModule(MMI->getModule()); { NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled); @@ -228,30 +233,39 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M) static MCSymbol *emitSectionSym(AsmPrinter *Asm, const MCSection *Section, const char *SymbolStem = 0) { Asm->OutStreamer.SwitchSection(Section); - if (!SymbolStem) return 0; + if (!SymbolStem) + return 0; MCSymbol *TmpSym = Asm->GetTempSymbol(SymbolStem); Asm->OutStreamer.EmitLabel(TmpSym); return TmpSym; } +DwarfUnits::~DwarfUnits() { + for (SmallVectorImpl::iterator I = CUs.begin(), E = CUs.end(); I != E; + ++I) + delete *I; +} + MCSymbol *DwarfUnits::getStringPoolSym() { return Asm->GetTempSymbol(StringPref); } MCSymbol *DwarfUnits::getStringPoolEntry(StringRef Str) { - std::pair &Entry = - StringPool.GetOrCreateValue(Str).getValue(); - if (Entry.first) return Entry.first; + std::pair &Entry = + StringPool.GetOrCreateValue(Str).getValue(); + if (Entry.first) + return Entry.first; Entry.second = NextStringPoolNumber++; return Entry.first = Asm->GetTempSymbol(StringPref, Entry.second); } unsigned DwarfUnits::getStringPoolIndex(StringRef Str) { - std::pair &Entry = - StringPool.GetOrCreateValue(Str).getValue(); - if (Entry.first) return Entry.second; + std::pair &Entry = + StringPool.GetOrCreateValue(Str).getValue(); + if (Entry.first) + return Entry.second; Entry.second = NextStringPoolNumber++; Entry.first = Asm->GetTempSymbol(StringPref, Entry.second); @@ -294,7 +308,8 @@ static bool isObjCClass(StringRef Name) { } static bool hasObjCCategory(StringRef Name) { - if (!isObjCClass(Name)) return false; + if (!isObjCClass(Name)) + return false; return Name.find(") ") != StringRef::npos; } @@ -318,35 +333,35 @@ static StringRef getObjCMethodName(StringRef In) { // Helper for sorting sections into a stable output order. static bool SectionSort(const MCSection *A, const MCSection *B) { - std::string LA = (A ? A->getLabelBeginName() : ""); - std::string LB = (B ? B->getLabelBeginName() : ""); - return LA < LB; + std::string LA = (A ? A->getLabelBeginName() : ""); + std::string LB = (B ? B->getLabelBeginName() : ""); + return LA < LB; } // Add the various names to the Dwarf accelerator table names. // 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) { - if (!SP.isDefinition()) return; - TheCU->addAccelName(SP.getName(), Die); +static void addSubprogramNames(Unit *TheU, DISubprogram SP, DIE *Die) { + if (!SP.isDefinition()) + return; + 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); } } @@ -376,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(); @@ -388,8 +404,7 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(CompileUnit *SPCU, DISubprogram SP) { // specification DIE for a function defined inside a function. DIScope SPContext = resolve(SP.getContext()); if (SP.isDefinition() && !SPContext.isCompileUnit() && - !SPContext.isFile() && - !isSubprogramContext(SPContext)) { + !SPContext.isFile() && !isSubprogramContext(SPContext)) { SPCU->addFlag(SPDie, dwarf::DW_AT_declaration); // Add arguments. @@ -400,7 +415,7 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(CompileUnit *SPCU, DISubprogram SP) { for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) { DIE *Arg = SPCU->createAndAddDIE(dwarf::DW_TAG_formal_parameter, *SPDie); - DIType ATy = DIType(Args.getElement(i)); + DIType ATy(Args.getElement(i)); SPCU->addType(Arg, ATy); if (ATy.isArtificial()) SPCU->addFlag(Arg, dwarf::DW_AT_artificial); @@ -408,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); @@ -453,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, @@ -464,29 +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 uint, size 4, for now. emitDIE will handle - // DW_AT_ranges appropriately. - TheCU->addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_data4, - DebugRangeSymbols.size() - * Asm->getDataLayout().getPointerSize()); - 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!"); @@ -504,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()) @@ -521,22 +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 uint, size 4, for now. emitDIE will handle - // DW_AT_ranges appropriately. - TheCU->addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_data4, - DebugRangeSymbols.size() - * Asm->getDataLayout().getPointerSize()); - 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); @@ -568,26 +578,29 @@ DIE *DwarfDebug::constructInlinedScopeDIE(CompileUnit *TheCU, } DIE *DwarfDebug::createScopeChildrenDIE(CompileUnit *TheCU, LexicalScope *Scope, - SmallVectorImpl &Children) { - DIE *ObjectPointer = NULL; + SmallVectorImpl &Children) { + DIE *ObjectPointer = NULL; // Collect arguments for current function. if (LScopes.isCurrentFunctionScope(Scope)) for (unsigned i = 0, N = CurrentFnArguments.size(); i < N; ++i) if (DbgVariable *ArgDV = CurrentFnArguments[i]) if (DIE *Arg = - TheCU->constructVariableDIE(*ArgDV, Scope->isAbstractScope())) { + TheCU->constructVariableDIE(*ArgDV, Scope->isAbstractScope())) { Children.push_back(Arg); - if (ArgDV->isObjectPointer()) ObjectPointer = Arg; + if (ArgDV->isObjectPointer()) + ObjectPointer = Arg; } // Collect lexical scope children first. - const SmallVectorImpl &Variables =ScopeVariables.lookup(Scope); + const SmallVectorImpl &Variables = + ScopeVariables.lookup(Scope); for (unsigned i = 0, N = Variables.size(); i < N; ++i) - if (DIE *Variable = - TheCU->constructVariableDIE(*Variables[i], Scope->isAbstractScope())) { + if (DIE *Variable = TheCU->constructVariableDIE(*Variables[i], + Scope->isAbstractScope())) { Children.push_back(Variable); - if (Variables[i]->isObjectPointer()) ObjectPointer = Variable; + if (Variables[i]->isObjectPointer()) + ObjectPointer = Variable; } const SmallVectorImpl &Scopes = Scope->getChildren(); for (unsigned j = 0, M = Scopes.size(); j < M; ++j) @@ -620,11 +633,9 @@ DIE *DwarfDebug::constructScopeDIE(CompileUnit *TheCU, LexicalScope *Scope) { // Note down abstract DIE. if (ScopeDIE) AbstractSPDies.insert(std::make_pair(DS, ScopeDIE)); - } - else + } else ScopeDIE = updateSubprogramScopeDIE(TheCU, DISubprogram(DS)); - } - else { + } else { // Early exit when we know the scope DIE is going to be null. if (isLexicalScopeDIENull(Scope)) return NULL; @@ -636,10 +647,12 @@ DIE *DwarfDebug::constructScopeDIE(CompileUnit *TheCU, LexicalScope *Scope) { // There is no need to emit empty lexical block DIE. std::pair Range = std::equal_range( - ScopesWithImportedEntities.begin(), ScopesWithImportedEntities.end(), - std::pair(DS, (const MDNode*)0), - less_first()); + ImportedEntityMap::const_iterator> Range = + std::equal_range( + ScopesWithImportedEntities.begin(), + ScopesWithImportedEntities.end(), + std::pair(DS, (const MDNode *)0), + less_first()); if (Children.empty() && Range.first == Range.second) return NULL; ScopeDIE = constructLexicalScopeDIE(TheCU, Scope); @@ -660,15 +673,13 @@ DIE *DwarfDebug::constructScopeDIE(CompileUnit *TheCU, LexicalScope *Scope) { // Add children for (SmallVectorImpl::iterator I = Children.begin(), - E = Children.end(); I != E; ++I) + E = Children.end(); + I != E; ++I) ScopeDIE->addChild(*I); if (DS.isSubprogram() && ObjectPointer != NULL) TheCU->addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, ObjectPointer); - if (DS.isSubprogram()) - TheCU->addPubTypes(DISubprogram(DS)); - return ScopeDIE; } @@ -676,8 +687,8 @@ DIE *DwarfDebug::constructScopeDIE(CompileUnit *TheCU, LexicalScope *Scope) { // If none currently exists, create a new id and insert it in the // SourceIds map. This can update DirectoryNames and SourceFileNames maps // as well. -unsigned DwarfDebug::getOrCreateSourceID(StringRef FileName, - StringRef DirName, unsigned CUID) { +unsigned DwarfDebug::getOrCreateSourceID(StringRef FileName, StringRef DirName, + unsigned CUID) { // If we use .loc in assembly, we can't separate .file entries according to // compile units. Thus all files will belong to the default compile unit. @@ -743,8 +754,8 @@ CompileUnit *DwarfDebug::constructCompileUnit(DICompileUnit DIUnit) { NewCU->addLabelAddress(Die, dwarf::DW_AT_low_pc, NULL); // Define start line table label for each Compile Unit. - MCSymbol *LineTableStartSym = Asm->GetTempSymbol("line_table_start", - NewCU->getUniqueID()); + MCSymbol *LineTableStartSym = + Asm->GetTempSymbol("line_table_start", NewCU->getUniqueID()); Asm->OutStreamer.getContext().setMCLineTableSymbol(LineTableStartSym, NewCU->getUniqueID()); @@ -760,14 +771,15 @@ CompileUnit *DwarfDebug::constructCompileUnit(DICompileUnit DIUnit) { // The line table entries are not always emitted in assembly, so it // is not okay to use line_table_start here. if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) - NewCU->addLabel(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_sec_offset, - UseTheFirstCU ? Asm->GetTempSymbol("section_line") - : LineTableStartSym); + NewCU->addSectionLabel( + Die, dwarf::DW_AT_stmt_list, + UseTheFirstCU ? Asm->GetTempSymbol("section_line") + : LineTableStartSym); else if (UseTheFirstCU) - NewCU->addUInt(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4, 0); + NewCU->addSectionOffset(Die, dwarf::DW_AT_stmt_list, 0); else - NewCU->addDelta(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4, - LineTableStartSym, DwarfLineSectionSym); + NewCU->addSectionDelta(Die, dwarf::DW_AT_stmt_list, + LineTableStartSym, DwarfLineSectionSym); // If we're using split dwarf the compilation dir is going to be in the // skeleton CU and so we don't need to duplicate it here. @@ -778,26 +790,24 @@ CompileUnit *DwarfDebug::constructCompileUnit(DICompileUnit DIUnit) { // emit it here if we don't have a skeleton CU for split dwarf. if (GenerateGnuPubSections) { if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) - NewCU->addLabel(Die, dwarf::DW_AT_GNU_pubnames, - dwarf::DW_FORM_sec_offset, - Asm->GetTempSymbol("gnu_pubnames", - NewCU->getUniqueID())); + NewCU->addSectionLabel( + Die, dwarf::DW_AT_GNU_pubnames, + Asm->GetTempSymbol("gnu_pubnames", NewCU->getUniqueID())); else - NewCU->addDelta(Die, dwarf::DW_AT_GNU_pubnames, dwarf::DW_FORM_data4, - Asm->GetTempSymbol("gnu_pubnames", - NewCU->getUniqueID()), - DwarfGnuPubNamesSectionSym); + NewCU->addSectionDelta( + Die, dwarf::DW_AT_GNU_pubnames, + Asm->GetTempSymbol("gnu_pubnames", NewCU->getUniqueID()), + DwarfGnuPubNamesSectionSym); if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) - NewCU->addLabel(Die, dwarf::DW_AT_GNU_pubtypes, - dwarf::DW_FORM_sec_offset, - Asm->GetTempSymbol("gnu_pubtypes", - NewCU->getUniqueID())); + NewCU->addSectionLabel( + Die, dwarf::DW_AT_GNU_pubtypes, + Asm->GetTempSymbol("gnu_pubtypes", NewCU->getUniqueID())); else - NewCU->addDelta(Die, dwarf::DW_AT_GNU_pubtypes, dwarf::DW_FORM_data4, - Asm->GetTempSymbol("gnu_pubtypes", - NewCU->getUniqueID()), - DwarfGnuPubTypesSectionSym); + NewCU->addSectionDelta( + Die, dwarf::DW_AT_GNU_pubtypes, + Asm->GetTempSymbol("gnu_pubtypes", NewCU->getUniqueID()), + DwarfGnuPubTypesSectionSym); } } @@ -810,7 +820,7 @@ CompileUnit *DwarfDebug::constructCompileUnit(DICompileUnit DIUnit) { if (unsigned RVer = DIUnit.getRunTimeVersion()) NewCU->addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers, - dwarf::DW_FORM_data1, RVer); + dwarf::DW_FORM_data1, RVer); if (!FirstCU) FirstCU = NewCU; @@ -950,12 +960,14 @@ void DwarfDebug::beginModule() { void DwarfDebug::computeInlinedDIEs() { // Attach DW_AT_inline attribute with inlined subprogram DIEs. for (SmallPtrSet::iterator AI = InlinedSubprogramDIEs.begin(), - AE = InlinedSubprogramDIEs.end(); AI != AE; ++AI) { + AE = InlinedSubprogramDIEs.end(); + AI != AE; ++AI) { DIE *ISP = *AI; FirstCU->addUInt(ISP, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined); } for (DenseMap::iterator AI = AbstractSPDies.begin(), - AE = AbstractSPDies.end(); AI != AE; ++AI) { + AE = AbstractSPDies.end(); + AI != AE; ++AI) { DIE *ISP = AI->second; if (InlinedSubprogramDIEs.count(ISP)) continue; @@ -984,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. @@ -995,8 +1007,7 @@ void DwarfDebug::collectDeadVariables() { if (!DV.isVariable()) continue; DbgVariable NewVar(DV, NULL, this); - if (DIE *VariableDIE = - SPCU->constructVariableDIE(NewVar, false)) + if (DIE *VariableDIE = SPCU->constructVariableDIE(NewVar, false)) SPDIE->addChild(VariableDIE); } } @@ -1033,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); @@ -1046,46 +1057,31 @@ void DwarfDebug::finalizeModuleInfo() { // Attach DW_AT_inline attribute with inlined subprogram DIEs. computeInlinedDIEs(); - // Split out type units and conditionally add an ODR tag to the split - // out type. - // FIXME: Do type splitting. - for (unsigned i = 0, e = TypeUnits.size(); i != e; ++i) { - DIE *Die = TypeUnits[i]; - DIEHash Hash; - // If we've requested ODR hashes and it's applicable for an ODR hash then - // add the ODR signature now. - // FIXME: This should be added onto the type unit, not the type, but this - // works as an intermediate stage. - if (GenerateODRHash && shouldAddODRHash(CUMap.begin()->second, Die)) - CUMap.begin()->second->addUInt(Die, dwarf::DW_AT_GNU_odr_signature, - dwarf::DW_FORM_data8, - Hash.computeDIEODRSignature(*Die)); - } - // 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); } } @@ -1097,7 +1093,7 @@ void DwarfDebug::finalizeModuleInfo() { } void DwarfDebug::endSections() { - // Filter labels by section. + // Filter labels by section. for (size_t n = 0; n < ArangeLabels.size(); n++) { const SymbolCU &SCU = ArangeLabels[n]; if (SCU.Sym->isInSection()) { @@ -1126,14 +1122,16 @@ void DwarfDebug::endSections() { std::sort(Sections.begin(), Sections.end(), SectionSort); // Add terminating symbols for each section. - for (unsigned ID=0;IDGetTempSymbol("debug_end", ID); Asm->OutStreamer.SwitchSection(Section); @@ -1147,8 +1145,11 @@ 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; + if (!FirstCU) + return; // End any existing sections. // TODO: Does this need to happen? @@ -1157,57 +1158,32 @@ void DwarfDebug::endModule() { // Finalize the debug info for the module. finalizeModuleInfo(); - if (!useSplitDwarf()) { - emitDebugStr(); + emitDebugStr(); - // Emit all the DIEs into a debug info section. - emitDebugInfo(); + // Emit all the DIEs into a debug info section. + emitDebugInfo(); - // Corresponding abbreviations into a abbrev section. - emitAbbreviations(); + // Corresponding abbreviations into a abbrev section. + emitAbbreviations(); - // Emit info into a debug loc section. - emitDebugLoc(); + // Emit info into a debug loc section. + emitDebugLoc(); - // Emit info into a debug aranges section. - emitDebugARanges(); + // Emit info into a debug aranges section. + emitDebugARanges(); - // Emit info into a debug ranges section. - emitDebugRanges(); + // Emit info into a debug ranges section. + emitDebugRanges(); - // Emit info into a debug macinfo section. - emitDebugMacInfo(); + // Emit info into a debug macinfo section. + emitDebugMacInfo(); - } else { - // TODO: Fill this in for separated debug sections and separate - // out information into new sections. - emitDebugStr(); - if (useSplitDwarf()) - emitDebugStrDWO(); - - // Emit the debug info section and compile units. - emitDebugInfo(); + if (useSplitDwarf()) { + emitDebugStrDWO(); emitDebugInfoDWO(); - - // Corresponding abbreviations into a abbrev section. - emitAbbreviations(); emitDebugAbbrevDWO(); - - // Emit info into a debug loc section. - emitDebugLoc(); - - // Emit info into a debug aranges section. - emitDebugARanges(); - - // Emit info into a debug ranges section. - emitDebugRanges(); - - // Emit info into a debug macinfo section. - emitDebugMacInfo(); - // Emit DWO addresses. InfoHolder.emitAddresses(Asm->getObjFileLowering().getDwarfAddrSection()); - } // Emit info into the dwarf accelerator table sections. @@ -1226,13 +1202,6 @@ void DwarfDebug::endModule() { // clean up. SPMap.clear(); - for (DenseMap::iterator I = CUMap.begin(), - E = CUMap.end(); I != E; ++I) - delete I->second; - - for (SmallVectorImpl::iterator I = SkeletonCUs.begin(), - E = SkeletonCUs.end(); I != E; ++I) - delete *I; // Reset these for the next Module if we have one. FirstCU = NULL; @@ -1259,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(); @@ -1272,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) @@ -1282,14 +1250,15 @@ bool DwarfDebug::addCurrentFnArgument(const MachineFunction *MF, } // Collect variable information from side table maintained by MMI. -void -DwarfDebug::collectVariableInfoFromMMITable(const MachineFunction *MF, - SmallPtrSet &Processed) { +void DwarfDebug::collectVariableInfoFromMMITable( + SmallPtrSet &Processed) { MachineModuleInfo::VariableDbgInfoMapTy &VMap = MMI->getVariableDbgInfo(); for (MachineModuleInfo::VariableDbgInfoMapTy::iterator VI = VMap.begin(), - VE = VMap.end(); VI != VE; ++VI) { + VE = VMap.end(); + VI != VE; ++VI) { const MDNode *Var = VI->first; - if (!Var) continue; + if (!Var) + continue; Processed.insert(Var); DIVariable DV(Var); const std::pair &VP = VI->second; @@ -1303,7 +1272,7 @@ DwarfDebug::collectVariableInfoFromMMITable(const MachineFunction *MF, 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); @@ -1314,8 +1283,8 @@ DwarfDebug::collectVariableInfoFromMMITable(const MachineFunction *MF, // defined reg. static bool isDbgValueInDefinedReg(const MachineInstr *MI) { assert(MI->isDebugValue() && "Invalid DBG_VALUE machine instruction!"); - return MI->getNumOperands() == 3 && - MI->getOperand(0).isReg() && MI->getOperand(0).getReg() && + return MI->getNumOperands() == 3 && MI->getOperand(0).isReg() && + MI->getOperand(0).getReg() && (MI->getOperand(1).isImm() || (MI->getOperand(1).isReg() && MI->getOperand(1).getReg() == 0U)); } @@ -1325,7 +1294,7 @@ static DotDebugLocEntry getDebugLocEntry(AsmPrinter *Asm, const MCSymbol *FLabel, const MCSymbol *SLabel, const MachineInstr *MI) { - const MDNode *Var = MI->getOperand(MI->getNumOperands() - 1).getMetadata(); + const MDNode *Var = MI->getOperand(MI->getNumOperands() - 1).getMetadata(); assert(MI->getNumOperands() == 3); if (MI->getOperand(0).isReg()) { @@ -1350,22 +1319,22 @@ 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(), UVE = UserVariables.end(); UVI != UVE; - ++UVI) { + for (SmallVectorImpl::const_iterator + UVI = UserVariables.begin(), + UVE = UserVariables.end(); + UVI != UVE; ++UVI) { const MDNode *Var = *UVI; if (Processed.count(Var)) continue; // History contains relevant DBG_VALUE instructions for Var and instructions // clobbering it. - SmallVectorImpl &History = DbgValues[Var]; + SmallVectorImpl &History = DbgValues[Var]; if (History.empty()) continue; const MachineInstr *MInsn = History.front(); @@ -1373,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)); @@ -1387,14 +1356,14 @@ 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); // Simplify ranges that are fully coalesced. - if (History.size() <= 1 || (History.size() == 2 && - MInsn->isIdenticalTo(History.back()))) { + if (History.size() <= 1 || + (History.size() == 2 && MInsn->isIdenticalTo(History.back()))) { RegVar->setMInsn(MInsn); continue; } @@ -1402,14 +1371,16 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF, // Handle multiple DBG_VALUE instructions describing one variable. RegVar->setDotDebugLocOffset(DotDebugLocEntries.size()); - for (SmallVectorImpl::const_iterator - HI = History.begin(), HE = History.end(); HI != HE; ++HI) { + for (SmallVectorImpl::const_iterator + HI = History.begin(), + HE = History.end(); + HI != HE; ++HI) { const MachineInstr *Begin = *HI; assert(Begin->isDebugValue() && "Invalid History entry"); // Check if DBG_VALUE is truncating a range. - if (Begin->getNumOperands() > 1 && Begin->getOperand(0).isReg() - && !Begin->getOperand(0).getReg()) + if (Begin->getNumOperands() > 1 && Begin->getOperand(0).isReg() && + !Begin->getOperand(0).getReg()) continue; // Compute the range for a register location. @@ -1423,7 +1394,7 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF, else { const MachineInstr *End = HI[1]; DEBUG(dbgs() << "DotDebugLoc Pair:\n" - << "\t" << *Begin << "\t" << *End << "\n"); + << "\t" << *Begin << "\t" << *End << "\n"); if (End->isDebugValue()) SLabel = getLabelBeforeInsn(End); else { @@ -1435,8 +1406,8 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF, } // The value is valid until the next DBG_VALUE or clobber. - DotDebugLocEntries.push_back(getDebugLocEntry(Asm, FLabel, SLabel, - Begin)); + DotDebugLocEntries.push_back( + getDebugLocEntry(Asm, FLabel, SLabel, Begin)); } DotDebugLocEntries.push_back(DotDebugLocEntry()); } @@ -1467,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(); @@ -1489,8 +1462,8 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) { } // Insert labels where requested. - DenseMap::iterator I = - LabelsBeforeInsn.find(MI); + DenseMap::iterator I = + LabelsBeforeInsn.find(MI); // No label needed. if (I == LabelsBeforeInsn.end()) @@ -1508,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); + DenseMap::iterator I = + LabelsAfterInsn.find(CurMI); + CurMI = 0; // No label needed. if (I == LabelsAfterInsn.end()) @@ -1545,8 +1520,10 @@ void DwarfDebug::identifyScopeMarkers() { const SmallVectorImpl &Children = S->getChildren(); if (!Children.empty()) - for (SmallVectorImpl::const_iterator SI = Children.begin(), - SE = Children.end(); SI != SE; ++SI) + for (SmallVectorImpl::const_iterator + SI = Children.begin(), + SE = Children.end(); + SI != SE; ++SI) WorkList.push_back(*SI); if (S->isAbstractScope()) @@ -1556,7 +1533,8 @@ void DwarfDebug::identifyScopeMarkers() { if (Ranges.empty()) continue; for (SmallVectorImpl::const_iterator RI = Ranges.begin(), - RE = Ranges.end(); RI != RE; ++RI) { + RE = Ranges.end(); + RI != RE; ++RI) { assert(RI->first && "InsnRange does not have first instruction!"); assert(RI->second && "InsnRange does not have second instruction!"); requestLabelBeforeInsn(RI->first); @@ -1592,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()) @@ -1655,8 +1634,7 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) { // label, so arguments are visible when breaking at function entry. DIVariable DV(Var); if (DV.isVariable() && DV.getTag() == dwarf::DW_TAG_arg_variable && - DISubprogram(getDISubprogram(DV.getContext())) - .describes(MF->getFunction())) + getDISubprogram(DV.getContext()).describes(MF->getFunction())) LabelsBeforeInsn[MI] = FunctionBeginSym; } else { // We have seen this variable before. Try to coalesce DBG_VALUEs. @@ -1820,18 +1798,29 @@ 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()) return; + // 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()); + FunctionEndSym = Asm->GetTempSymbol("func_end", Asm->getFunctionNumber()); // Assumes in correct section after the entry point. Asm->OutStreamer.EmitLabel(FunctionEndSym); // Set DwarfCompileUnitID in MCContext to default value. Asm->OutStreamer.getContext().setDwarfCompileUnitID(0); SmallPtrSet ProcessedVars; - collectVariableInfo(MF, ProcessedVars); + collectVariableInfo(ProcessedVars); LexicalScope *FnScope = LScopes.getCurrentFunctionScope(); CompileUnit *TheCU = SPMap.lookup(FnScope->getScopeNode()); @@ -1865,12 +1854,13 @@ 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 - for (ScopeVariablesMap::iterator - I = ScopeVariables.begin(), E = ScopeVariables.end(); I != E; ++I) + for (ScopeVariablesMap::iterator I = ScopeVariables.begin(), + E = ScopeVariables.end(); + I != E; ++I) DeleteContainerPointers(I->second); ScopeVariables.clear(); DeleteContainerPointers(CurrentFnArguments); @@ -1880,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 @@ -1915,8 +1906,8 @@ void DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, const MDNode *S, } else llvm_unreachable("Unexpected scope info"); - Src = getOrCreateSourceID(Fn, Dir, - Asm->OutStreamer.getContext().getDwarfCompileUnitID()); + Src = getOrCreateSourceID( + Fn, Dir, Asm->OutStreamer.getContext().getDwarfCompileUnitID()); } Asm->OutStreamer.EmitDwarfLocDirective(Src, Line, Col, Flags, 0, 0, Fn); } @@ -1927,8 +1918,7 @@ void DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, const MDNode *S, // Compute the size and offset of a DIE. The offset is relative to start of the // CU. It returns the offset after laying out the DIE. -unsigned -DwarfUnits::computeSizeAndOffset(DIE *Die, unsigned Offset) { +unsigned DwarfUnits::computeSizeAndOffset(DIE *Die, unsigned Offset) { // Get the children. const std::vector &Children = Die->getChildren(); @@ -1945,7 +1935,7 @@ DwarfUnits::computeSizeAndOffset(DIE *Die, unsigned Offset) { // Start the size with the size of abbreviation code. Offset += MCAsmInfo::getULEB128Size(AbbrevNumber); - const SmallVectorImpl &Values = Die->getValues(); + const SmallVectorImpl &Values = Die->getValues(); const SmallVectorImpl &AbbrevData = Abbrev->getData(); // Size the DIE attribute values. @@ -1976,17 +1966,17 @@ 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(); I != E; ++I) { + for (SmallVectorImpl::const_iterator I = CUs.begin(), E = CUs.end(); + I != E; ++I) { (*I)->setDebugInfoOffset(SecOffset); // CU-relative offset is reset to 0 here. - unsigned Offset = sizeof(int32_t) + // Length of Unit Info + unsigned Offset = sizeof(int32_t) + // Length of Unit Info (*I)->getHeaderSize(); // Unit-specific headers // 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; } } @@ -1997,20 +1987,19 @@ void DwarfDebug::emitSectionLabels() { // Dwarf sections base addresses. DwarfInfoSectionSym = - emitSectionSym(Asm, TLOF.getDwarfInfoSection(), "section_info"); + emitSectionSym(Asm, TLOF.getDwarfInfoSection(), "section_info"); DwarfAbbrevSectionSym = - emitSectionSym(Asm, TLOF.getDwarfAbbrevSection(), "section_abbrev"); + emitSectionSym(Asm, TLOF.getDwarfAbbrevSection(), "section_abbrev"); if (useSplitDwarf()) - DwarfAbbrevDWOSectionSym = - emitSectionSym(Asm, TLOF.getDwarfAbbrevDWOSection(), - "section_abbrev_dwo"); + DwarfAbbrevDWOSectionSym = emitSectionSym( + Asm, TLOF.getDwarfAbbrevDWOSection(), "section_abbrev_dwo"); emitSectionSym(Asm, TLOF.getDwarfARangesSection()); if (const MCSection *MacroInfo = TLOF.getDwarfMacroInfoSection()) emitSectionSym(Asm, MacroInfo); DwarfLineSectionSym = - emitSectionSym(Asm, TLOF.getDwarfLineSection(), "section_line"); + emitSectionSym(Asm, TLOF.getDwarfLineSection(), "section_line"); emitSectionSym(Asm, TLOF.getDwarfLocSection()); if (GenerateGnuPubSections) { DwarfGnuPubNamesSectionSym = @@ -2023,18 +2012,18 @@ void DwarfDebug::emitSectionLabels() { } DwarfStrSectionSym = - emitSectionSym(Asm, TLOF.getDwarfStrSection(), "info_string"); + emitSectionSym(Asm, TLOF.getDwarfStrSection(), "info_string"); if (useSplitDwarf()) { DwarfStrDWOSectionSym = - emitSectionSym(Asm, TLOF.getDwarfStrDWOSection(), "skel_string"); + emitSectionSym(Asm, TLOF.getDwarfStrDWOSection(), "skel_string"); DwarfAddrSectionSym = - emitSectionSym(Asm, TLOF.getDwarfAddrSection(), "addr_sec"); + emitSectionSym(Asm, TLOF.getDwarfAddrSection(), "addr_sec"); } - DwarfDebugRangeSectionSym = emitSectionSym(Asm, TLOF.getDwarfRangesSection(), - "debug_range"); + DwarfDebugRangeSectionSym = + emitSectionSym(Asm, TLOF.getDwarfRangesSection(), "debug_range"); - DwarfDebugLocSectionSym = emitSectionSym(Asm, TLOF.getDwarfLocSection(), - "section_debug_loc"); + DwarfDebugLocSectionSym = + emitSectionSym(Asm, TLOF.getDwarfLocSection(), "section_debug_loc"); TextSectionSym = emitSectionSym(Asm, TLOF.getTextSection(), "text_begin"); emitSectionSym(Asm, TLOF.getDataSection()); @@ -2054,7 +2043,7 @@ void DwarfDebug::emitDIE(DIE *Die, ArrayRef Abbrevs) { dwarf::TagString(Abbrev->getTag())); Asm->EmitULEB128(AbbrevNumber); - const SmallVectorImpl &Values = Die->getValues(); + const SmallVectorImpl &Values = Die->getValues(); const SmallVectorImpl &AbbrevData = Abbrev->getData(); // Emit the DIE attribute values. @@ -2081,7 +2070,7 @@ void DwarfDebug::emitDIE(DIE *Die, ArrayRef Abbrevs) { // For DW_FORM_ref_addr, output the offset from beginning of debug info // section. Origin->getOffset() returns the offset from start of the // compile unit. - CompileUnit *CU = CUDieMap.lookup(Origin->getCompileUnit()); + CompileUnit *CU = CUDieMap.lookup(Origin->getUnit()); assert(CU && "CUDie should belong to a CU."); Addr += CU->getDebugInfoOffset(); if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) @@ -2093,7 +2082,7 @@ void DwarfDebug::emitDIE(DIE *Die, ArrayRef Abbrevs) { DIEEntry::getRefAddrSize(Asm)); } else { // Make sure Origin belong to the same CU. - assert(Die->getCompileUnit() == Origin->getCompileUnit() && + assert(Die->getUnit() == Origin->getUnit() && "The referenced DIE should belong to the same CU in ref4"); Asm->EmitInt32(Addr); } @@ -2101,18 +2090,12 @@ void DwarfDebug::emitDIE(DIE *Die, ArrayRef Abbrevs) { } case dwarf::DW_AT_ranges: { // DW_AT_range Value encodes offset in debug_range section. - DIEInteger *V = cast(Values[i]); + DIELabel *V = cast(Values[i]); - if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) { - Asm->EmitLabelPlusOffset(DwarfDebugRangeSectionSym, - V->getValue(), - 4); - } else { - Asm->EmitLabelOffsetDifference(DwarfDebugRangeSectionSym, - V->getValue(), - DwarfDebugRangeSectionSym, - 4); - } + if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) + Asm->EmitSectionOffset(V->getValue(), DwarfDebugRangeSectionSym); + else + Asm->EmitLabelDifference(V->getValue(), DwarfDebugRangeSectionSym, 4); break; } case dwarf::DW_AT_location: { @@ -2156,30 +2139,28 @@ void DwarfDebug::emitDIE(DIE *Die, ArrayRef Abbrevs) { // Emit the various dwarf units to the unit section USection with // the abbreviations going into ASection. -void DwarfUnits::emitUnits(DwarfDebug *DD, - const MCSection *USection, +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->OutStreamer.EmitLabel( + Asm->GetTempSymbol(USection->getLabelEndName(), TheU->getUniqueID())); } } @@ -2244,8 +2225,9 @@ void DwarfDebug::emitEndOfLineMatrix(unsigned SectionEnd) { Asm->OutStreamer.AddComment("Section end label"); - Asm->OutStreamer.EmitSymbolValue(Asm->GetTempSymbol("section_end",SectionEnd), - Asm->getDataLayout().getPointerSize()); + Asm->OutStreamer.EmitSymbolValue( + Asm->GetTempSymbol("section_end", SectionEnd), + Asm->getDataLayout().getPointerSize()); // Mark end of matrix. Asm->OutStreamer.AddComment("DW_LNE_end_sequence"); @@ -2256,25 +2238,29 @@ void DwarfDebug::emitEndOfLineMatrix(unsigned SectionEnd) { // Emit visible names into a hashed accelerator table section. 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(); I != E; ++I) { - CompileUnit *TheCU = I->second; - const StringMap > &Names = TheCU->getAccelNames(); - for (StringMap >::const_iterator - GI = Names.begin(), GE = Names.end(); GI != GE; ++GI) { + DwarfAccelTable AT( + DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4)); + for (SmallVectorImpl::const_iterator I = getUnits().begin(), + E = getUnits().end(); + I != E; ++I) { + Unit *TheU = *I; + const StringMap > &Names = TheU->getAccelNames(); + for (StringMap >::const_iterator + GI = Names.begin(), + GE = Names.end(); + GI != GE; ++GI) { StringRef Name = GI->getKey(); - const std::vector &Entities = GI->second; - for (std::vector::const_iterator DI = Entities.begin(), - DE = Entities.end(); DI != DE; ++DI) - AT.AddName(Name, (*DI)); + const std::vector &Entities = GI->second; + for (std::vector::const_iterator DI = Entities.begin(), + DE = Entities.end(); + DI != DE; ++DI) + AT.AddName(Name, *DI); } } AT.FinalizeTable(Asm, "Names"); Asm->OutStreamer.SwitchSection( - Asm->getObjFileLowering().getDwarfAccelNamesSection()); + Asm->getObjFileLowering().getDwarfAccelNamesSection()); MCSymbol *SectionBegin = Asm->GetTempSymbol("names_begin"); Asm->OutStreamer.EmitLabel(SectionBegin); @@ -2285,25 +2271,29 @@ void DwarfDebug::emitAccelNames() { // Emit objective C classes and categories into a hashed accelerator table // section. 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(); I != E; ++I) { - CompileUnit *TheCU = I->second; - const StringMap > &Names = TheCU->getAccelObjC(); - for (StringMap >::const_iterator - GI = Names.begin(), GE = Names.end(); GI != GE; ++GI) { + DwarfAccelTable AT( + DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4)); + for (SmallVectorImpl::const_iterator I = getUnits().begin(), + E = getUnits().end(); + I != E; ++I) { + Unit *TheU = *I; + const StringMap > &Names = TheU->getAccelObjC(); + for (StringMap >::const_iterator + GI = Names.begin(), + GE = Names.end(); + GI != GE; ++GI) { StringRef Name = GI->getKey(); - const std::vector &Entities = GI->second; - for (std::vector::const_iterator DI = Entities.begin(), - DE = Entities.end(); DI != DE; ++DI) - AT.AddName(Name, (*DI)); + const std::vector &Entities = GI->second; + for (std::vector::const_iterator DI = Entities.begin(), + DE = Entities.end(); + DI != DE; ++DI) + AT.AddName(Name, *DI); } } AT.FinalizeTable(Asm, "ObjC"); - Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering() - .getDwarfAccelObjCSection()); + Asm->OutStreamer.SwitchSection( + Asm->getObjFileLowering().getDwarfAccelObjCSection()); MCSymbol *SectionBegin = Asm->GetTempSymbol("objc_begin"); Asm->OutStreamer.EmitLabel(SectionBegin); @@ -2313,25 +2303,30 @@ void DwarfDebug::emitAccelObjC() { // Emit namespace dies into a hashed accelerator table. 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(); I != E; ++I) { - CompileUnit *TheCU = I->second; - const StringMap > &Names = TheCU->getAccelNamespace(); - for (StringMap >::const_iterator - GI = Names.begin(), GE = Names.end(); GI != GE; ++GI) { + DwarfAccelTable AT( + DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4)); + for (SmallVectorImpl::const_iterator I = getUnits().begin(), + E = getUnits().end(); + I != E; ++I) { + Unit *TheU = *I; + const StringMap > &Names = + TheU->getAccelNamespace(); + for (StringMap >::const_iterator + GI = Names.begin(), + GE = Names.end(); + GI != GE; ++GI) { StringRef Name = GI->getKey(); - const std::vector &Entities = GI->second; - for (std::vector::const_iterator DI = Entities.begin(), - DE = Entities.end(); DI != DE; ++DI) - AT.AddName(Name, (*DI)); + const std::vector &Entities = GI->second; + for (std::vector::const_iterator DI = Entities.begin(), + DE = Entities.end(); + DI != DE; ++DI) + AT.AddName(Name, *DI); } } AT.FinalizeTable(Asm, "namespac"); - Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering() - .getDwarfAccelNamespaceSection()); + Asm->OutStreamer.SwitchSection( + Asm->getObjFileLowering().getDwarfAccelNamespaceSection()); MCSymbol *SectionBegin = Asm->GetTempSymbol("namespac_begin"); Asm->OutStreamer.EmitLabel(SectionBegin); @@ -2342,31 +2337,38 @@ void DwarfDebug::emitAccelNamespaces() { // Emit type dies into a hashed accelerator table. void DwarfDebug::emitAccelTypes() { std::vector Atoms; - Atoms.push_back(DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, - dwarf::DW_FORM_data4)); - Atoms.push_back(DwarfAccelTable::Atom(dwarf::DW_ATOM_die_tag, - dwarf::DW_FORM_data2)); - Atoms.push_back(DwarfAccelTable::Atom(dwarf::DW_ATOM_type_flags, - dwarf::DW_FORM_data1)); + Atoms.push_back( + DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4)); + Atoms.push_back( + DwarfAccelTable::Atom(dwarf::DW_ATOM_die_tag, dwarf::DW_FORM_data2)); + 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(); I != E; ++I) { - CompileUnit *TheCU = I->second; - const StringMap > > &Names - = TheCU->getAccelTypes(); - for (StringMap > >::const_iterator - GI = Names.begin(), GE = Names.end(); GI != GE; ++GI) { + for (SmallVectorImpl::const_iterator I = getUnits().begin(), + E = getUnits().end(); + I != E; ++I) { + Unit *TheU = *I; + const StringMap > > &Names = + TheU->getAccelTypes(); + for (StringMap< + std::vector > >::const_iterator + GI = Names.begin(), + GE = Names.end(); + GI != GE; ++GI) { StringRef Name = GI->getKey(); - const std::vector > &Entities = GI->second; - for (std::vector >::const_iterator DI - = Entities.begin(), DE = Entities.end(); DI !=DE; ++DI) - AT.AddName(Name, (*DI).first, (*DI).second); + const std::vector > &Entities = + GI->second; + for (std::vector >::const_iterator + DI = Entities.begin(), + DE = Entities.end(); + DI != DE; ++DI) + AT.AddName(Name, DI->first, DI->second); } } AT.FinalizeTable(Asm, "types"); - Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering() - .getDwarfAccelTypesSection()); + Asm->OutStreamer.SwitchSection( + Asm->getObjFileLowering().getDwarfAccelTypesSection()); MCSymbol *SectionBegin = Asm->GetTempSymbol("types_begin"); Asm->OutStreamer.EmitLabel(SectionBegin); @@ -2389,8 +2391,8 @@ 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, - DIE *Die) { +static dwarf::PubIndexEntryDescriptor computeIndexValue(Unit *CU, + const DIE *Die) { dwarf::GDBIndexEntryLinkage Linkage = dwarf::GIEL_STATIC; // We could have a specification DIE that has our most of our knowledge, @@ -2439,18 +2441,19 @@ 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); // 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->OutStreamer.EmitLabel( + Asm->GetTempSymbol("gnu_pubnames", TheU->getUniqueID())); // Emit the header. Asm->OutStreamer.AddComment("Length of Public Names Info"); @@ -2472,17 +2475,18 @@ void DwarfDebug::emitDebugPubNames(bool GnuStyle) { 4); // Emit the pubnames for this compilation unit. - const StringMap &Globals = TheCU->getGlobalNames(); - for (StringMap::const_iterator - GI = Globals.begin(), GE = Globals.end(); GI != GE; ++GI) { + const StringMap &Globals = TheU->getGlobalNames(); + for (StringMap::const_iterator GI = Globals.begin(), + GE = Globals.end(); + GI != GE; ++GI) { const char *Name = GI->getKeyData(); - DIE *Entity = GI->second; + const DIE *Entity = GI->second; Asm->OutStreamer.AddComment("DIE offset"); 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)); @@ -2491,7 +2495,7 @@ void DwarfDebug::emitDebugPubNames(bool GnuStyle) { if (Asm->isVerbose()) Asm->OutStreamer.AddComment("External Name"); - Asm->OutStreamer.EmitBytes(StringRef(Name, GI->getKeyLength()+1)); + Asm->OutStreamer.EmitBytes(StringRef(Name, GI->getKeyLength() + 1)); } Asm->OutStreamer.AddComment("End Mark"); @@ -2506,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->OutStreamer.EmitLabel( + 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"); @@ -2533,28 +2537,28 @@ 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(); - for (StringMap::const_iterator GI = Globals.begin(), - GE = Globals.end(); + const StringMap &Globals = TheU->getGlobalTypes(); + for (StringMap::const_iterator GI = Globals.begin(), + GE = Globals.end(); GI != GE; ++GI) { const char *Name = GI->getKeyData(); - DIE *Entity = GI->second; + const DIE *Entity = GI->second; if (Asm->isVerbose()) Asm->OutStreamer.AddComment("DIE offset"); 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)); @@ -2571,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())); } } @@ -2580,18 +2584,21 @@ void DwarfUnits::emitStrings(const MCSection *StrSection, const MCSection *OffsetSection = NULL, const MCSymbol *StrSecSym = NULL) { - if (StringPool.empty()) return; + if (StringPool.empty()) + return; // Start the dwarf str section. Asm->OutStreamer.SwitchSection(StrSection); // Get all of the string pool entries and put them in an array by their ID so // we can sort them. - SmallVector >*>, 64> Entries; + SmallVector< + std::pair > *>, + 64> Entries; - for (StringMap >::iterator - I = StringPool.begin(), E = StringPool.end(); + for (StringMap >::iterator + I = StringPool.begin(), + E = StringPool.end(); I != E; ++I) Entries.push_back(std::make_pair(I->second.second, &*I)); @@ -2602,8 +2609,9 @@ void DwarfUnits::emitStrings(const MCSection *StrSection, Asm->OutStreamer.EmitLabel(Entries[i].second->getValue().first); // Emit the string itself with a terminating null byte. - Asm->OutStreamer.EmitBytes(StringRef(Entries[i].second->getKeyData(), - Entries[i].second->getKeyLength()+1)); + Asm->OutStreamer.EmitBytes( + StringRef(Entries[i].second->getKeyData(), + Entries[i].second->getKeyLength() + 1)); } // If we've got an offset section go ahead and emit that now as well. @@ -2618,10 +2626,12 @@ void DwarfUnits::emitStrings(const MCSection *StrSection, } } -// Emit strings into a string section. + +// Emit addresses into the section given. void DwarfUnits::emitAddresses(const MCSection *AddrSection) { - if (AddressPool.empty()) return; + if (AddressPool.empty()) + return; // Start the dwarf addr section. Asm->OutStreamer.SwitchSection(AddrSection); @@ -2641,7 +2651,6 @@ void DwarfUnits::emitAddresses(const MCSection *AddrSection) { else Asm->OutStreamer.EmitIntValue(0, Asm->getDataLayout().getPointerSize()); } - } // Emit visible names into a debug str section. @@ -2656,24 +2665,27 @@ void DwarfDebug::emitDebugLoc() { return; for (SmallVectorImpl::iterator - I = DotDebugLocEntries.begin(), E = DotDebugLocEntries.end(); + I = DotDebugLocEntries.begin(), + E = DotDebugLocEntries.end(); I != E; ++I) { DotDebugLocEntry &Entry = *I; if (I + 1 != DotDebugLocEntries.end()) - Entry.Merge(I+1); + Entry.Merge(I + 1); } // Start the dwarf loc section. Asm->OutStreamer.SwitchSection( - Asm->getObjFileLowering().getDwarfLocSection()); + Asm->getObjFileLowering().getDwarfLocSection()); unsigned char Size = Asm->getDataLayout().getPointerSize(); Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_loc", 0)); unsigned index = 1; for (SmallVectorImpl::iterator - I = DotDebugLocEntries.begin(), E = DotDebugLocEntries.end(); + I = DotDebugLocEntries.begin(), + E = DotDebugLocEntries.end(); I != E; ++I, ++index) { DotDebugLocEntry &Entry = *I; - if (Entry.isMerged()) continue; + if (Entry.isMerged()) + continue; if (Entry.isEmpty()) { Asm->OutStreamer.EmitIntValue(0, Size); Asm->OutStreamer.EmitIntValue(0, Size); @@ -2689,9 +2701,8 @@ void DwarfDebug::emitDebugLoc() { Asm->OutStreamer.EmitLabel(begin); if (Entry.isInt()) { DIBasicType BTy(DV.getType()); - if (BTy.Verify() && - (BTy.getEncoding() == dwarf::DW_ATE_signed - || BTy.getEncoding() == dwarf::DW_ATE_signed_char)) { + if (BTy.Verify() && (BTy.getEncoding() == dwarf::DW_ATE_signed || + BTy.getEncoding() == dwarf::DW_ATE_signed_char)) { Asm->OutStreamer.AddComment("DW_OP_consts"); Asm->EmitInt8(dwarf::DW_OP_consts); Asm->EmitSLEB128(Entry.getInt()); @@ -2754,7 +2765,7 @@ struct SymbolCUSorter { SymbolCUSorter(const MCStreamer &s) : Streamer(s) {} const MCStreamer &Streamer; - bool operator() (const SymbolCU &A, const SymbolCU &B) { + bool operator()(const SymbolCU &A, const SymbolCU &B) { unsigned IA = A.Sym ? Streamer.GetSymbolOrder(A.Sym) : 0; unsigned IB = B.Sym ? Streamer.GetSymbolOrder(B.Sym) : 0; @@ -2768,8 +2779,8 @@ struct SymbolCUSorter { } }; -static bool CUSort(const CompileUnit *A, const CompileUnit *B) { - return (A->getUniqueID() < B->getUniqueID()); +static bool CUSort(const Unit *A, const Unit *B) { + return (A->getUniqueID() < B->getUniqueID()); } struct ArangeSpan { @@ -2780,8 +2791,8 @@ struct ArangeSpan { // address we can tie back to a CU. void DwarfDebug::emitDebugARanges() { // Start the dwarf aranges section. - Asm->OutStreamer - .SwitchSection(Asm->getObjFileLowering().getDwarfARangesSection()); + Asm->OutStreamer.SwitchSection( + Asm->getObjFileLowering().getDwarfARangesSection()); typedef DenseMap > SpansType; @@ -2800,7 +2811,7 @@ void DwarfDebug::emitDebugARanges() { std::sort(Sections.begin(), Sections.end(), SectionSort); // Build a set of address spans, sorted by CU. - for (size_t SecIdx=0;SecIdx &List = SectionMap[Section]; if (List.size() < 2) @@ -2855,16 +2866,16 @@ void DwarfDebug::emitDebugARanges() { std::sort(CUs.begin(), CUs.end(), CUSort); // Emit an arange table for each CU we used. - for (size_t CUIdx=0;CUIdx &List = Spans[CU]; // Emit size of content not including length itself. - unsigned ContentSize - = sizeof(int16_t) // DWARF ARange version number - + sizeof(int32_t) // Offset of CU in the .debug_info section - + sizeof(int8_t) // Pointer Size (in bytes) - + sizeof(int8_t); // Segment Size (in bytes) + unsigned ContentSize = + sizeof(int16_t) + // DWARF ARange version number + sizeof(int32_t) + // Offset of CU in the .debug_info section + sizeof(int8_t) + // Pointer Size (in bytes) + sizeof(int8_t); // Segment Size (in bytes) unsigned TupleSize = PtrSize * 2; @@ -2920,23 +2931,60 @@ void DwarfDebug::emitDebugARanges() { // Emit visible names into a debug ranges section. void DwarfDebug::emitDebugRanges() { // Start the dwarf ranges section. - Asm->OutStreamer - .SwitchSection(Asm->getObjFileLowering().getDwarfRangesSection()); + Asm->OutStreamer.SwitchSection( + Asm->getObjFileLowering().getDwarfRangesSection()); + + // Size for our labels. unsigned char Size = Asm->getDataLayout().getPointerSize(); - for (SmallVectorImpl::iterator - I = DebugRangeSymbols.begin(), E = DebugRangeSymbols.end(); + + // Grab the specific ranges for the compile units in the module. + for (DenseMap::iterator I = CUMap.begin(), + E = CUMap.end(); I != E; ++I) { - if (*I) - Asm->OutStreamer.EmitSymbolValue(const_cast(*I), Size); - else + 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); + } } } // Emit visible names into a debug macinfo section. void DwarfDebug::emitDebugMacInfo() { if (const MCSection *LineInfo = - Asm->getObjFileLowering().getDwarfMacroInfoSection()) { + Asm->getObjFileLowering().getDwarfMacroInfoSection()) { // Start the dwarf macinfo section. Asm->OutStreamer.SwitchSection(LineInfo); } @@ -2959,11 +3007,10 @@ CompileUnit *DwarfDebug::constructSkeletonCU(const CompileUnit *CU) { // Relocate to the beginning of the addr_base section, else 0 for the // beginning of the one for this compile unit. if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) - NewCU->addLabel(Die, dwarf::DW_AT_GNU_addr_base, dwarf::DW_FORM_sec_offset, - DwarfAddrSectionSym); + NewCU->addSectionLabel(Die, dwarf::DW_AT_GNU_addr_base, + DwarfAddrSectionSym); else - NewCU->addUInt(Die, dwarf::DW_AT_GNU_addr_base, - dwarf::DW_FORM_sec_offset, 0); + NewCU->addSectionOffset(Die, dwarf::DW_AT_GNU_addr_base, 0); // 2.17.1 requires that we use DW_AT_low_pc for a single entry point // into an entity. We're using 0, or a NULL label for this. @@ -2973,10 +3020,10 @@ CompileUnit *DwarfDebug::constructSkeletonCU(const CompileUnit *CU) { // compile unit in debug_line section. // FIXME: Should handle multiple compile units. if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) - NewCU->addLabel(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_sec_offset, - DwarfLineSectionSym); + NewCU->addSectionLabel(Die, dwarf::DW_AT_stmt_list, + DwarfLineSectionSym); else - NewCU->addUInt(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_sec_offset, 0); + NewCU->addSectionOffset(Die, dwarf::DW_AT_stmt_list, 0); if (!CompilationDir.empty()) NewCU->addLocalString(Die, dwarf::DW_AT_comp_dir, CompilationDir); @@ -2984,34 +3031,40 @@ CompileUnit *DwarfDebug::constructSkeletonCU(const CompileUnit *CU) { // Flags to let the linker know we have emitted new style pubnames. if (GenerateGnuPubSections) { if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) - NewCU->addLabel(Die, dwarf::DW_AT_GNU_pubnames, dwarf::DW_FORM_sec_offset, - Asm->GetTempSymbol("gnu_pubnames", NewCU->getUniqueID())); + NewCU->addSectionLabel( + Die, dwarf::DW_AT_GNU_pubnames, + Asm->GetTempSymbol("gnu_pubnames", NewCU->getUniqueID())); else - NewCU->addDelta(Die, dwarf::DW_AT_GNU_pubnames, dwarf::DW_FORM_data4, - Asm->GetTempSymbol("gnu_pubnames", NewCU->getUniqueID()), - DwarfGnuPubNamesSectionSym); + NewCU->addSectionDelta( + Die, dwarf::DW_AT_GNU_pubnames, + Asm->GetTempSymbol("gnu_pubnames", NewCU->getUniqueID()), + DwarfGnuPubNamesSectionSym); if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) - NewCU->addLabel(Die, dwarf::DW_AT_GNU_pubtypes, dwarf::DW_FORM_sec_offset, - Asm->GetTempSymbol("gnu_pubtypes", NewCU->getUniqueID())); + NewCU->addSectionLabel( + Die, dwarf::DW_AT_GNU_pubtypes, + Asm->GetTempSymbol("gnu_pubtypes", NewCU->getUniqueID())); else - NewCU->addDelta(Die, dwarf::DW_AT_GNU_pubtypes, dwarf::DW_FORM_data4, - Asm->GetTempSymbol("gnu_pubtypes", NewCU->getUniqueID()), - DwarfGnuPubTypesSectionSym); + NewCU->addSectionDelta( + Die, dwarf::DW_AT_GNU_pubtypes, + Asm->GetTempSymbol("gnu_pubtypes", NewCU->getUniqueID()), + 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->addLabel(Die, dwarf::DW_AT_GNU_ranges_base, - dwarf::DW_FORM_sec_offset, 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); - SkeletonCUs.push_back(NewCU); return NewCU; } @@ -3043,9 +3096,63 @@ void DwarfDebug::emitDebugAbbrevDWO() { // sections. void DwarfDebug::emitDebugStrDWO() { assert(useSplitDwarf() && "No split dwarf?"); - const MCSection *OffSec = Asm->getObjFileLowering() - .getDwarfStrOffDWOSection(); + const MCSection *OffSec = + Asm->getObjFileLowering().getDwarfStrOffDWOSection(); const MCSymbol *StrSym = DwarfStrSectionSym; InfoHolder.emitStrings(Asm->getObjFileLowering().getDwarfStrDWOSection(), OffSec, StrSym); } + +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()) { + if (I->second.second) { + I->second.second->push_back(RefDie); + return; + } + } else { + DIE *UnitDie = new DIE(dwarf::DW_TAG_type_unit); + 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. + I = TypeUnits.insert(std::make_pair(CTy, std::make_pair(0, &References))) + .first; + + // 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 = NewTU->createTypeDIE(CTy); + + 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 + // may have references to other DIEs still under construction and missing + // their signature. Hashing should walk through the signatures to their + // referenced type, or possibly walk the precomputed hashes of related types + // at the end. + uint64_t Signature = DIEHash().computeTypeSignature(*Die); + + // Remove the References vector and add the type hash. + I->second.first = Signature; + I->second.second = NULL; + + InfoHolder.addUnit(NewTU); + } + + // Populate all the signatures. + for (unsigned i = 0, e = References.size(); i != e; ++i) { + CUMap.begin()->second->addUInt(References[i], dwarf::DW_AT_signature, + dwarf::DW_FORM_ref_sig8, I->second.first); + } +}