X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FAsmPrinter%2FDwarfUnit.cpp;h=ccecb5be50bb90207fce0ce7739de7da1680547d;hb=9c9ef05445e4ebaf56e70f61e3fdcabc0ddcffc0;hp=c743cbbb45d43ebd072e1a50851f173701c83d45;hpb=365f0455a6b202d349619ad9be3f2bccabc76d92;p=oota-llvm.git diff --git a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index c743cbbb45d..ccecb5be50b 100644 --- a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -56,8 +56,13 @@ DwarfCompileUnit::DwarfCompileUnit(unsigned UID, DIE *D, DICompileUnit Node, } DwarfTypeUnit::DwarfTypeUnit(unsigned UID, DIE *D, DwarfCompileUnit &CU, - AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU) - : DwarfUnit(UID, D, CU.getCUNode(), A, DW, DWU), CU(CU) {} + AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU, + MCDwarfDwoLineTable *SplitLineTable) + : DwarfUnit(UID, D, CU.getCUNode(), A, DW, DWU), CU(CU), + SplitLineTable(SplitLineTable) { + if (SplitLineTable) + addSectionOffset(UnitDie.get(), dwarf::DW_AT_stmt_list, 0); +} /// ~Unit - Destructor for compile unit. DwarfUnit::~DwarfUnit() { @@ -277,25 +282,50 @@ void DwarfUnit::addSectionOffset(DIE *Die, dwarf::Attribute Attribute, /// DW_FORM_addr or DW_FORM_GNU_addr_index. /// void DwarfCompileUnit::addLabelAddress(DIE *Die, dwarf::Attribute Attribute, - MCSymbol *Label) { + const MCSymbol *Label) { + + if (!DD->useSplitDwarf()) + return addLocalLabelAddress(Die, Attribute, Label); + if (Label) DD->addArangeLabel(SymbolCU(this, Label)); - if (!DD->useSplitDwarf()) { - if (Label) { - DIEValue *Value = new (DIEValueAllocator) DIELabel(Label); - Die->addValue(Attribute, dwarf::DW_FORM_addr, Value); - } else { - DIEValue *Value = new (DIEValueAllocator) DIEInteger(0); - Die->addValue(Attribute, dwarf::DW_FORM_addr, Value); - } + unsigned idx = DU->getAddrPoolIndex(Label); + DIEValue *Value = new (DIEValueAllocator) DIEInteger(idx); + Die->addValue(Attribute, dwarf::DW_FORM_GNU_addr_index, Value); +} + +void DwarfCompileUnit::addLocalLabelAddress(DIE *Die, + dwarf::Attribute Attribute, + const MCSymbol *Label) { + if (Label) + DD->addArangeLabel(SymbolCU(this, Label)); + + if (Label) { + DIEValue *Value = new (DIEValueAllocator) DIELabel(Label); + Die->addValue(Attribute, dwarf::DW_FORM_addr, Value); } else { - unsigned idx = DU->getAddrPoolIndex(Label); - DIEValue *Value = new (DIEValueAllocator) DIEInteger(idx); - Die->addValue(Attribute, dwarf::DW_FORM_GNU_addr_index, Value); + DIEValue *Value = new (DIEValueAllocator) DIEInteger(0); + Die->addValue(Attribute, dwarf::DW_FORM_addr, Value); } } +unsigned DwarfCompileUnit::getOrCreateSourceID(StringRef FileName, StringRef DirName) { + // If we print assembly, we can't separate .file entries according to + // compile units. Thus all files will belong to the default compile unit. + + // FIXME: add a better feature test than hasRawTextSupport. Even better, + // extend .file to support this. + return Asm->OutStreamer.EmitDwarfFileDirective( + 0, DirName, FileName, + Asm->OutStreamer.hasRawTextSupport() ? 0 : getUniqueID()); +} + +unsigned DwarfTypeUnit::getOrCreateSourceID(StringRef FileName, StringRef DirName) { + return SplitLineTable ? SplitLineTable->getFile(DirName, FileName) + : getCU().getOrCreateSourceID(FileName, DirName); +} + /// addOpAddress - Add a dwarf op address data and value using the /// form given and an op of either DW_FORM_addr or DW_FORM_GNU_addr_index. /// @@ -354,7 +384,9 @@ void DwarfUnit::addDIEEntry(DIE *Die, dwarf::Attribute Attribute, /// Create a DIE with the given Tag, add the DIE to its parent, and /// call insertDIE if MD is not null. DIE *DwarfUnit::createAndAddDIE(unsigned Tag, DIE &Parent, DIDescriptor N) { - DIE *Die = new DIE(Tag); + assert(Tag != dwarf::DW_TAG_auto_variable && + Tag != dwarf::DW_TAG_arg_variable); + DIE *Die = new DIE((dwarf::Tag)Tag); Parent.addChild(Die); if (N) insertDIE(N, Die); @@ -383,8 +415,7 @@ void DwarfUnit::addSourceLine(DIE *Die, unsigned Line, StringRef File, if (Line == 0) return; - unsigned FileID = - DD->getOrCreateSourceID(File, Directory, getCU().getUniqueID()); + unsigned FileID = getOrCreateSourceID(File, Directory); assert(FileID && "Invalid file id"); addUInt(Die, dwarf::DW_AT_decl_file, None, FileID); addUInt(Die, dwarf::DW_AT_decl_line, None, Line); @@ -951,6 +982,8 @@ DIE *DwarfUnit::getOrCreateTypeDIE(const MDNode *TyNode) { DIType Ty(TyNode); assert(Ty.isType()); + assert(Ty == resolve(Ty.getRef()) && + "type was not uniqued, possible ODR violation."); // Construct the context before querying for the existence of the DIE in case // such construction creates the DIE. @@ -974,7 +1007,7 @@ DIE *DwarfUnit::getOrCreateTypeDIE(const MDNode *TyNode) { if (GenerateDwarfTypeUnits && !Ty.isForwardDecl()) if (MDString *TypeId = CTy.getIdentifier()) { DD->addDwarfTypeUnitType(getCU(), TypeId->getString(), TyDIE, CTy); - // Skip updating the accellerator tables since this is not the full type + // Skip updating the accelerator tables since this is not the full type. return TyDIE; } constructTypeDIE(*TyDIE, CTy); @@ -1410,7 +1443,12 @@ DIE *DwarfUnit::getOrCreateSubprogramDIE(DISubprogram SP) { // Construct the context before querying for the existence of the DIE in case // such construction creates the DIE (as is the case for member function // declarations). - DIE *ContextDIE = getOrCreateContextDIE(resolve(SP.getContext())); + DIScope Context = resolve(SP.getContext()); + DIE *ContextDIE = getOrCreateContextDIE(Context); + + // Unique declarations based on the ODR, where applicable. + SP = DISubprogram(DD->resolve(SP.getRef())); + assert(SP.Verify()); DIE *SPDie = getDIE(SP); if (SPDie) @@ -1431,20 +1469,25 @@ DIE *DwarfUnit::getOrCreateSubprogramDIE(DISubprogram SP) { // Add function template parameters. addTemplateParams(*SPDie, SP.getTemplateParams()); - // If this DIE is going to refer declaration info using AT_specification - // then there is no need to add other attributes. - if (DeclDie) { + if (DeclDie) // Refer function declaration directly. addDIEEntry(SPDie, dwarf::DW_AT_specification, DeclDie); - return SPDie; + // Add the linkage name if we have one and it isn't in the Decl. + StringRef LinkageName = SP.getLinkageName(); + if (!LinkageName.empty()) { + if (SPDecl.isSubprogram() && !SPDecl.getLinkageName().empty()) + assert(SPDecl.getLinkageName() == SP.getLinkageName() && + "decl has a linkage name and it is different"); + else + addString(SPDie, dwarf::DW_AT_MIPS_linkage_name, + GlobalValue::getRealLinkageName(LinkageName)); } - // Add the linkage name if we have one. - StringRef LinkageName = SP.getLinkageName(); - if (!LinkageName.empty()) - addString(SPDie, dwarf::DW_AT_MIPS_linkage_name, - GlobalValue::getRealLinkageName(LinkageName)); + // If this DIE is going to refer declaration info using AT_specification + // then there is no need to add other attributes. + if (DeclDie) + return SPDie; // Constructors and operators for anonymous aggregates do not have names. if (!SP.getName().empty()) @@ -1560,7 +1603,7 @@ void DwarfCompileUnit::createGlobalVariableDIE(DIGlobalVariable GV) { assert(GV.isGlobalVariable()); DIScope GVContext = GV.getContext(); - DIType GTy = GV.getType(); + DIType GTy = DD->resolve(GV.getType()); // If this is a static data member definition, some attributes belong // to the declaration DIE. @@ -1651,7 +1694,8 @@ void DwarfCompileUnit::createGlobalVariableDIE(DIGlobalVariable GV) { // TAG_variable. addString(IsStaticMember && VariableSpecDIE ? VariableSpecDIE : VariableDIE, - dwarf::DW_AT_MIPS_linkage_name, + DD->getDwarfVersion() >= 4 ? dwarf::DW_AT_linkage_name + : dwarf::DW_AT_MIPS_linkage_name, GlobalValue::getRealLinkageName(LinkageName)); } else if (const ConstantInt *CI = dyn_cast_or_null(GV.getConstant())) { @@ -1729,12 +1773,12 @@ void DwarfUnit::constructArrayTypeDIE(DIE &Buffer, DICompositeType CTy) { // as different languages may have different sizes for indexes. DIE *IdxTy = getIndexTyDie(); if (!IdxTy) { - // Construct an anonymous type for index type. + // Construct an integer type to use for indexes. IdxTy = createAndAddDIE(dwarf::DW_TAG_base_type, *UnitDie); - addString(IdxTy, dwarf::DW_AT_name, "int"); - addUInt(IdxTy, dwarf::DW_AT_byte_size, None, sizeof(int32_t)); + addString(IdxTy, dwarf::DW_AT_name, "sizetype"); + addUInt(IdxTy, dwarf::DW_AT_byte_size, None, sizeof(int64_t)); addUInt(IdxTy, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, - dwarf::DW_ATE_signed); + dwarf::DW_ATE_unsigned); setIndexTyDie(IdxTy); } @@ -1993,29 +2037,47 @@ DIE *DwarfUnit::getOrCreateStaticMemberDIE(DIDerivedType DT) { return StaticMemberDIE; } -void DwarfUnit::emitHeader(const MCSection *ASection, - const MCSymbol *ASectionSym) const { +void DwarfUnit::emitHeader(const MCSymbol *ASectionSym) const { Asm->OutStreamer.AddComment("DWARF version number"); Asm->EmitInt16(DD->getDwarfVersion()); Asm->OutStreamer.AddComment("Offset Into Abbrev. Section"); // We share one abbreviations table across all units so it's always at the // start of the section. Use a relocatable offset where needed to ensure // linking doesn't invalidate that offset. - Asm->EmitSectionOffset(ASectionSym, ASectionSym); + if (ASectionSym) + Asm->EmitSectionOffset(ASectionSym, ASectionSym); + else + // Use a constant value when no symbol is provided. + Asm->EmitInt32(0); Asm->OutStreamer.AddComment("Address Size (in bytes)"); Asm->EmitInt8(Asm->getDataLayout().getPointerSize()); } +void DwarfUnit::addRange(RangeSpan Range) { + // Only add a range for this unit if we're emitting full debug. + if (getCUNode().getEmissionKind() == DIBuilder::FullDebug) { + // If we have no current ranges just add the range and return, otherwise, + // check the current section and CU against the previous section and CU we + // emitted into and the subprogram was contained within. If these are the + // same then extend our current range, otherwise add this as a new range. + if (CURanges.size() == 0 || + this != DD->getPrevCU() || + Asm->getCurrentSection() != DD->getPrevSection()) { + CURanges.push_back(Range); + return; + } + + assert(&(CURanges.back().getEnd()->getSection()) == + &(Range.getEnd()->getSection()) && + "We can only append to a range in the same section!"); + CURanges.back().setEnd(Range.getEnd()); + } +} + void DwarfCompileUnit::initStmtList(MCSymbol *DwarfLineSectionSym) { // Define start line table label for each Compile Unit. MCSymbol *LineTableStartSym = - Asm->GetTempSymbol("line_table_start", getUniqueID()); - Asm->OutStreamer.getContext().setMCLineTableSymbol(LineTableStartSym, - getUniqueID()); - - // Use a single line table if we are generating assembly. - bool UseTheFirstCU = - Asm->OutStreamer.hasRawTextSupport() || (getUniqueID() == 0); + Asm->OutStreamer.getDwarfLineTableSymbol(getUniqueID()); stmtListIndex = UnitDie->getValues().size(); @@ -2025,10 +2087,7 @@ void DwarfCompileUnit::initStmtList(MCSymbol *DwarfLineSectionSym) { // 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()) - addSectionLabel(UnitDie.get(), dwarf::DW_AT_stmt_list, - UseTheFirstCU ? DwarfLineSectionSym : LineTableStartSym); - else if (UseTheFirstCU) - addSectionOffset(UnitDie.get(), dwarf::DW_AT_stmt_list, 0); + addSectionLabel(UnitDie.get(), dwarf::DW_AT_stmt_list, LineTableStartSym); else addSectionDelta(UnitDie.get(), dwarf::DW_AT_stmt_list, LineTableStartSym, DwarfLineSectionSym); @@ -2040,9 +2099,8 @@ void DwarfCompileUnit::applyStmtList(DIE &D) { UnitDie->getValues()[stmtListIndex]); } -void DwarfTypeUnit::emitHeader(const MCSection *ASection, - const MCSymbol *ASectionSym) const { - DwarfUnit::emitHeader(ASection, ASectionSym); +void DwarfTypeUnit::emitHeader(const MCSymbol *ASectionSym) const { + DwarfUnit::emitHeader(ASectionSym); Asm->OutStreamer.AddComment("Type Signature"); Asm->OutStreamer.EmitIntValue(TypeSignature, sizeof(TypeSignature)); Asm->OutStreamer.AddComment("Type DIE Offset");