Index: lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
===================================================================
--- lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -638,6 +638,7 @@
   auto *SP = cast<DISubprogram>(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,98 @@
+; RUN: llc %s -filetype=obj -o %t
+; RUN: llvm-dwarfdump -debug-info %t | FileCheck %s
+
+; Reduced test case from PR35212. Two DISubprogram belong to a different CU but
+; share a scope. Both are declarations and end up in the scope's CU. We want to
+; check that the CU from the context DIE is used (rather than from the IR).
+; This manifests itself by the DW_base_type ending up in the second CU, rather
+; than in the first one as specified in the IR.
+
+; 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<alloc::string::String>", linkageName: "_ZN5alloc3vec8{{impl}}28clone<alloc::string::String>E", 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<alloc::string::String,alloc::heap::Heap>", linkageName: "_ZN5alloc7raw_vec8{{impl}}52allocate_in<alloc::string::String,alloc::heap::Heap>E", 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<alloc::string::String, alloc::heap::Heap>", 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<alloc::string::String>", linkageName: "_ZN5alloc7raw_vec8{{impl}}36with_capacity<alloc::string::String>E", 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<alloc::string::String>", linkageName: "_ZN5alloc3vec8{{impl}}36with_capacity<alloc::string::String>E", 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<alloc::string::String>", 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<alloc::string::String>", linkageName: "_ZN5alloc5slice4hack29to_vec<alloc::string::String>E", 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<alloc::string::String>", linkageName: "_ZN5alloc5slice8{{impl}}29to_vec<alloc::string::String>E", 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)