diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index dc6b998db8a..06782423fe3 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1384,6 +1384,11 @@ DIE *DwarfDebug::constructLexicalScopeDIE(DbgScope *Scope) { if (Ranges.empty()) return 0; + bool MarkFunctionBegin = false; + if (FunctionBeginSym && + Asm->MF->getFunction()->isWeakForLinker()) + MarkFunctionBegin = true; + SmallVector::const_iterator RI = Ranges.begin(); if (Ranges.size() > 1) { // .debug_range section has not been laid out yet. Emit offset in @@ -1393,8 +1398,15 @@ DIE *DwarfDebug::constructLexicalScopeDIE(DbgScope *Scope) { DebugRangeSymbols.size() * Asm->getTargetData().getPointerSize()); for (SmallVector::const_iterator RI = Ranges.begin(), RE = Ranges.end(); RI != RE; ++RI) { - DebugRangeSymbols.push_back(LabelsBeforeInsn.lookup(RI->first)); - DebugRangeSymbols.push_back(LabelsAfterInsn.lookup(RI->second)); + MCSymbol *Sym = LabelsBeforeInsn.lookup(RI->first); + if (MarkFunctionBegin) + WeakDebugRangeSymbols.insert(std::make_pair(Sym, FunctionBeginSym)); + DebugRangeSymbols.push_back(Sym); + + Sym = LabelsAfterInsn.lookup(RI->second); + if (MarkFunctionBegin) + WeakDebugRangeSymbols.insert(std::make_pair(Sym, FunctionBeginSym)); + DebugRangeSymbols.push_back(Sym); } DebugRangeSymbols.push_back(NULL); DebugRangeSymbols.push_back(NULL); @@ -3228,11 +3240,21 @@ void DwarfDebug::emitDebugRanges() { // Start the dwarf ranges section. Asm->OutStreamer.SwitchSection( Asm->getObjFileLowering().getDwarfRangesSection()); - for (SmallVector::const_iterator I = DebugRangeSymbols.begin(), - E = DebugRangeSymbols.end(); I != E; ++I) { - if (*I) - Asm->EmitLabelDifference(*I, TextSectionSym, + for (SmallVector::const_iterator + I = DebugRangeSymbols.begin(), E = DebugRangeSymbols.end(); + I != E; ++I) { + if (*I) { + const MCSymbol *Begin = TextSectionSym; + // If this symbol is inside linkonce section then use appropriate begin + // marker; + DenseMap::iterator WI + = WeakDebugRangeSymbols.find(*I); + if (WI != WeakDebugRangeSymbols.end()) + Begin = WI->second; + + Asm->EmitLabelDifference(*I, Begin, Asm->getTargetData().getPointerSize()); + } else Asm->OutStreamer.EmitIntValue(0, Asm->getTargetData().getPointerSize(), /*addrspace*/0); diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h index 698f7106019..b3f97458081 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -197,6 +197,7 @@ class DwarfDebug { DenseMap LabelsAfterInsn; SmallVector DebugRangeSymbols; + DenseMap WeakDebugRangeSymbols; /// Previous instruction's location information. This is used to determine /// label location to indicate scope boundries in dwarf debug info. diff --git a/test/DebugInfo/2010-04-22-range.ll b/test/DebugInfo/2010-04-22-range.ll new file mode 100644 index 00000000000..9b3b5e2a0d7 --- /dev/null +++ b/test/DebugInfo/2010-04-22-range.ll @@ -0,0 +1,38 @@ +; RUN: llc < %s | grep "Ltmp3-Lfunc_begin" +; PR 6894 + +declare void @_Z7examplev() ssp + +define linkonce_odr void @_bar(i64, i64, i64 %__depth_limit) ssp { +entry: + br i1 undef, label %while.body, label %while.end, !dbg !0 + +while.body: ; preds = %entry + br i1 undef, label %if.then, label %if.end, !dbg !8 + +if.then: ; preds = %while.body + call void @_Z7examplev(), !dbg !10 + ret void, !dbg !12 + +if.end: ; preds = %while.body + call void @_Z7examplev(), !dbg !13 + unreachable + +while.end: ; preds = %entry + ret void, !dbg !12 +} + +!0 = metadata !{i32 2742, i32 7, metadata !1, null} +!1 = metadata !{i32 524299, metadata !2, i32 2738, i32 5} ; [ DW_TAG_lexical_block ] +!2 = metadata !{i32 524334, i32 0, metadata !3, metadata !"__introsort_loop", metadata !"__introsort_loop", metadata !"_bar", metadata !3, i32 2738, metadata !5, i1 false, i1 true, i32 0, i32 0, null, i1 false} ; [ DW_TAG_subprogram ] +!3 = metadata !{i32 524329, metadata !"stl_algo.h", metadata !"/usr/include/c++/4.2.1/bits", metadata !4} ; [ DW_TAG_file_type ] +!4 = metadata !{i32 524305, i32 0, i32 4, metadata !"example.cc", metadata !"/tmp", metadata !"clang 1.5", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] +!5 = metadata !{i32 524309, metadata !6, metadata !"", metadata !6, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !7, i32 0, null} ; [ DW_TAG_subroutine_type ] +!6 = metadata !{i32 524329, metadata !"example.cc", metadata !"/tmp", metadata !4} ; [ DW_TAG_file_type ] +!7 = metadata !{null} +!8 = metadata !{i32 2744, i32 4, metadata !9, null} +!9 = metadata !{i32 524299, metadata !1, i32 2743, i32 2} ; [ DW_TAG_lexical_block ] +!10 = metadata !{i32 2746, i32 8, metadata !11, null} +!11 = metadata !{i32 524299, metadata !9, i32 2745, i32 6} ; [ DW_TAG_lexical_block ] +!12 = metadata !{i32 2762, i32 5, metadata !1, null} +!13 = metadata !{i32 2750, i32 4, metadata !9, null}