Index: lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -638,6 +638,7 @@ auto *SP = cast(Scope->getScopeNode()); DIE *ContextDIE; + DwarfCompileUnit *ContextCU = this; if (includeMinimalInlineScopes()) ContextDIE = &getUnitDie(); @@ -648,18 +649,23 @@ else if (auto *SPDecl = SP->getDeclaration()) { ContextDIE = &getUnitDie(); getOrCreateSubprogramDIE(SPDecl); - } else + } else { ContextDIE = getOrCreateContextDIE(resolve(SP->getScope())); + // The scope may be shared with a subprogram that has already been + // constructed in another CU, in which case we need to construct this + // subprogram in the same CU. + ContextCU = DD->lookupCU(ContextDIE->getUnitDie()); + } // Passing null as the associated node because the abstract definition // shouldn't be found by lookup. - AbsDef = &createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, nullptr); - applySubprogramAttributesToDefinition(SP, *AbsDef); + AbsDef = &ContextCU->createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, nullptr); + ContextCU->applySubprogramAttributesToDefinition(SP, *AbsDef); - if (!includeMinimalInlineScopes()) - addUInt(*AbsDef, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined); - if (DIE *ObjectPointer = createAndAddScopeChildren(Scope, *AbsDef)) - addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer); + if (!ContextCU->includeMinimalInlineScopes()) + ContextCU->addUInt(*AbsDef, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined); + if (DIE *ObjectPointer = ContextCU->createAndAddScopeChildren(Scope, *AbsDef)) + ContextCU->addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer); } DIE *DwarfCompileUnit::constructImportedEntityDIE( Index: lib/CodeGen/AsmPrinter/DwarfDebug.h =================================================================== --- lib/CodeGen/AsmPrinter/DwarfDebug.h +++ lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -276,7 +276,7 @@ // 0, referencing the comp_dir of all the type units that use it. MCDwarfDwoLineTable SplitTypeUnitFileTable; /// @} - + /// True iff there are multiple CUs in this module. bool SingleCU; bool IsDarwin; @@ -535,6 +535,9 @@ /// going to be null. bool isLexicalScopeDIENull(LexicalScope *Scope); + /// Find the matching DwarfCompileUnit for the given CU DIE. + DwarfCompileUnit *lookupCU(const DIE *Die) { return CUDieMap.lookup(Die); } + /// \defgroup DebuggerTuning Predicates to tune DWARF for a given debugger. /// /// Returns whether we are "tuning" for a given debugger. Index: test/DebugInfo/cross-cu-scope.ll =================================================================== --- /dev/null +++ test/DebugInfo/cross-cu-scope.ll @@ -0,0 +1,92 @@ +; RUN: llc %s -filetype=obj -o %t +; RUN: llvm-dwarfdump -debug-info %t | FileCheck %s + +; CHECK: DW_TAG_compile_unit +; CHECK: DW_TAG_compile_unit +; CHECK-NOT: NULL +; CHECK: DW_TAG_namespace +; CHECK: DW_TAG_namespace +; CHECK: DW_TAG_subprogram +; CHECK-NOT: NULL +; CHECK: DW_TAG_formal_parameter +; CHECK-NOT: NULL +; CHECK: DW_AT_type{{.*}}"usize" +; CHECK: NULL +; CHECK: DW_TAG_base_type +; CHECK-NOT: NULL +; CHECK: DW_AT_name{{.*}}"usize" + +define hidden fastcc void @foo() unnamed_addr { +start: + store i64 undef, i64* undef, align 8 + ret void +} + +define hidden void @bar() personality i32 ()* @rust_eh_personality !dbg !9 { +start: + br i1 undef, label %bb1.i.i, label %next, !dbg !12 + +bb1.i.i: ; preds = %start + unreachable + +next: ; preds = %start + invoke void @baz() + to label %done unwind label %cleanup + +done: ; preds = %next + ret void + +cleanup: ; preds = %next + %0 = landingpad { i8*, i32 } + cleanup + resume { i8*, i32 } undef +} + +declare i32 @rust_eh_personality() + +declare hidden void @baz() + +!llvm.dbg.cu = !{!0, !7} +!llvm.module.flags = !{!8} + +!0 = distinct !DICompileUnit(language: DW_LANG_Rust, file: !1, producer: "clang LLVM (rustc version 1.23.0-nightly (f0fe716db 2017-10-30))", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) +!1 = !DIFile(filename: "../lib.rs", directory: "/home/alex/code/rust4/lol") +!2 = !{!3} +!3 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "Option", scope: !4, file: !1, baseType: !5, size: 64, align: 64, elements: !6) +!4 = !DINamespace(name: "option", scope: null) +!5 = !DIBasicType(name: "u64", size: 64, encoding: DW_ATE_unsigned) +!6 = !{} +!7 = distinct !DICompileUnit(language: DW_LANG_Rust, file: !1, producer: "clang LLVM (rustc version 1.23.0-nightly (f0fe716db 2017-10-30))", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug) +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = distinct !DISubprogram(name: "clone", linkageName: "_ZN5alloc3vec8{{impl}}28cloneE", scope: !10, file: !1, line: 1519, type: !11, isLocal: false, isDefinition: true, scopeLine: 1519, flags: DIFlagPrototyped, isOptimized: true, unit: !0, templateParams: !6, variables: !6) +!10 = !DINamespace(name: "{{impl}}", scope: null) +!11 = !DISubroutineType(types: !6) +!12 = !DILocation(line: 1612, scope: !13, inlinedAt: !15) +!13 = distinct !DILexicalBlock(scope: !14, file: !1, line: 1611, column: 12) +!14 = distinct !DISubprogram(name: "checked_mul", linkageName: "_ZN4core3num8{{impl}}11checked_mulE", scope: !10, file: !1, line: 1610, type: !11, isLocal: false, isDefinition: true, scopeLine: 1610, flags: DIFlagPrototyped, isOptimized: true, unit: !7, templateParams: !6, variables: !6) +!15 = distinct !DILocation(line: 86, scope: !16, inlinedAt: !23) +!16 = distinct !DILexicalBlock(scope: !17, file: !1, line: 86, column: 12) +!17 = distinct !DILexicalBlock(scope: !18, file: !1, line: 84, column: 12) +!18 = distinct !DILexicalBlock(scope: !19, file: !1, line: 83, column: 8) +!19 = distinct !DISubprogram(name: "allocate_in", linkageName: "_ZN5alloc7raw_vec8{{impl}}52allocate_inE", scope: !20, file: !1, line: 82, type: !11, isLocal: false, isDefinition: true, scopeLine: 82, flags: DIFlagPrototyped, isOptimized: true, unit: !7, templateParams: !6, variables: !6) +!20 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "RawVec", scope: !21, file: !1, size: 128, align: 64, elements: !6, identifier: "5c6e4db16d2c64555e40661d70c4d81e") +!21 = !DINamespace(name: "raw_vec", scope: !22) +!22 = !DINamespace(name: "alloc", scope: null) +!23 = distinct !DILocation(line: 141, scope: !24, inlinedAt: !28) +!24 = distinct !DISubprogram(name: "with_capacity", linkageName: "_ZN5alloc7raw_vec8{{impl}}36with_capacityE", scope: !20, file: !1, line: 140, type: !11, isLocal: false, isDefinition: true, scopeLine: 140, flags: DIFlagPrototyped, isOptimized: true, unit: !0, templateParams: !6, variables: !25) +!25 = !{!26} +!26 = !DILocalVariable(name: "cap", arg: 1, scope: !24, file: !1, line: 1, type: !27) +!27 = !DIBasicType(name: "usize", size: 64, encoding: DW_ATE_unsigned) +!28 = distinct !DILocation(line: 359, scope: !29, inlinedAt: !32) +!29 = distinct !DISubprogram(name: "with_capacity", linkageName: "_ZN5alloc3vec8{{impl}}36with_capacityE", scope: !30, file: !1, line: 357, type: !11, isLocal: false, isDefinition: true, scopeLine: 357, flags: DIFlagPrototyped, isOptimized: true, unit: !0, templateParams: !6, variables: !6) +!30 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Vec", scope: !31, file: !1, size: 192, align: 64, elements: !6, identifier: "12876be70cb310f0d5acdae3fcb03942") +!31 = !DINamespace(name: "vec", scope: null) +!32 = distinct !DILocation(line: 163, scope: !33, inlinedAt: !37) +!33 = distinct !DILexicalBlock(scope: !34, file: !1, line: 163, column: 8) +!34 = distinct !DISubprogram(name: "to_vec", linkageName: "_ZN5alloc5slice4hack29to_vecE", scope: !35, file: !1, line: 160, type: !11, isLocal: false, isDefinition: true, scopeLine: 160, flags: DIFlagPrototyped, isOptimized: true, unit: !0, templateParams: !6, variables: !6) +!35 = !DINamespace(name: "hack", scope: !36) +!36 = !DINamespace(name: "slice", scope: !22) +!37 = distinct !DILocation(line: 1509, scope: !38, inlinedAt: !40) +!38 = distinct !DISubprogram(name: "to_vec", linkageName: "_ZN5alloc5slice8{{impl}}29to_vecE", scope: !39, file: !1, line: 1505, type: !11, isLocal: false, isDefinition: true, scopeLine: 1505, flags: DIFlagPrototyped, isOptimized: true, unit: !0, templateParams: !6, variables: !6) +!39 = !DINamespace(name: "{{impl}}", scope: !36) +!40 = !DILocation(line: 1521, scope: !9)