Explorar o código

Stop name mangling at an imported package name (#4294)

To ensure the outer package name is not mangled into imported names.

With this change I can successfully link/run a two-file example:
```
package Mod;
fn HelloWorld() {
  Core.Print(42);
}
```
```
import Mod;
fn Run() -> i32 {
  Mod.HelloWorld();
  return 0;
}
```
```
$ carbon compile mod.carbon main.carbon
$ carbon link mod.o main.o --output=a.out
$ ./a.out
42
```
\o/

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
David Blaikie hai 1 ano
pai
achega
4631767943

+ 4 - 2
toolchain/lower/mangler.cpp

@@ -89,8 +89,10 @@ auto Mangler::MangleInverseQualifiedNameScope(llvm::raw_ostream& os,
         CARBON_FATAL("Attempting to mangle unsupported SemIR.");
         break;
     }
-    names_to_render.push_back(
-        {.name_scope_id = name_scope.parent_scope_id, .prefix = '.'});
+    if (!name_scope.is_imported_package()) {
+      names_to_render.push_back(
+          {.name_scope_id = name_scope.parent_scope_id, .prefix = '.'});
+    }
   }
 }
 

+ 6 - 6
toolchain/lower/testdata/operators/overloaded.carbon

@@ -31,7 +31,7 @@ fn Calculate(a: Number, b: Number) -> Number {
 // CHECK:STDOUT: ; ModuleID = 'overloaded.carbon'
 // CHECK:STDOUT: source_filename = "overloaded.carbon"
 // CHECK:STDOUT:
-// CHECK:STDOUT: define void @"_COp.Number.Main:Negate.Core.Main"(ptr sret({ i1 }) %return, ptr %self) !dbg !4 {
+// CHECK:STDOUT: define void @"_COp.Number.Main:Negate.Core"(ptr sret({ i1 }) %return, ptr %self) !dbg !4 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %.loc17_36.1.is_positive = getelementptr inbounds nuw { i1 }, ptr %self, i32 0, i32 0, !dbg !7
 // CHECK:STDOUT:   %.loc17_36.2 = load i1, ptr %.loc17_36.1.is_positive, align 1, !dbg !7
@@ -41,7 +41,7 @@ fn Calculate(a: Number, b: Number) -> Number {
 // CHECK:STDOUT:   ret void, !dbg !10
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: define void @"_COp.Number.Main:Mul.Core.Main"(ptr sret({ i1 }) %return, ptr %self, ptr %other) !dbg !11 {
+// CHECK:STDOUT: define void @"_COp.Number.Main:Mul.Core"(ptr sret({ i1 }) %return, ptr %self, ptr %other) !dbg !11 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %.loc22_33.1.is_positive = getelementptr inbounds nuw { i1 }, ptr %self, i32 0, i32 0, !dbg !12
 // CHECK:STDOUT:   %.loc22_33.2 = load i1, ptr %.loc22_33.1.is_positive, align 1, !dbg !12
@@ -83,8 +83,8 @@ fn Calculate(a: Number, b: Number) -> Number {
 // CHECK:STDOUT: define void @_CCalculate.Main(ptr sret({ i1 }) %return, ptr %a, ptr %b) !dbg !21 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %.loc28_10.3.temp = alloca { i1 }, align 8, !dbg !22
-// CHECK:STDOUT:   call void @"_COp.Number.Main:Negate.Core.Main"(ptr %.loc28_10.3.temp, ptr %a), !dbg !22
-// CHECK:STDOUT:   call void @"_COp.Number.Main:Mul.Core.Main"(ptr %return, ptr %.loc28_10.3.temp, ptr %b), !dbg !22
+// CHECK:STDOUT:   call void @"_COp.Number.Main:Negate.Core"(ptr %.loc28_10.3.temp, ptr %a), !dbg !22
+// CHECK:STDOUT:   call void @"_COp.Number.Main:Mul.Core"(ptr %return, ptr %.loc28_10.3.temp, ptr %b), !dbg !22
 // CHECK:STDOUT:   ret void, !dbg !23
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -98,14 +98,14 @@ fn Calculate(a: Number, b: Number) -> Number {
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
 // CHECK:STDOUT: !3 = !DIFile(filename: "overloaded.carbon", directory: "")
-// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "Op", linkageName: "_COp.Number.Main:Negate.Core.Main", scope: null, file: !3, line: 16, type: !5, spFlags: DISPFlagDefinition, unit: !2)
+// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "Op", linkageName: "_COp.Number.Main:Negate.Core", scope: null, file: !3, line: 16, type: !5, spFlags: DISPFlagDefinition, unit: !2)
 // CHECK:STDOUT: !5 = !DISubroutineType(types: !6)
 // CHECK:STDOUT: !6 = !{}
 // CHECK:STDOUT: !7 = !DILocation(line: 17, column: 32, scope: !4)
 // CHECK:STDOUT: !8 = !DILocation(line: 17, column: 28, scope: !4)
 // CHECK:STDOUT: !9 = !DILocation(line: 17, column: 12, scope: !4)
 // CHECK:STDOUT: !10 = !DILocation(line: 17, column: 5, scope: !4)
-// CHECK:STDOUT: !11 = distinct !DISubprogram(name: "Op", linkageName: "_COp.Number.Main:Mul.Core.Main", scope: null, file: !3, line: 21, type: !5, spFlags: DISPFlagDefinition, unit: !2)
+// CHECK:STDOUT: !11 = distinct !DISubprogram(name: "Op", linkageName: "_COp.Number.Main:Mul.Core", scope: null, file: !3, line: 21, type: !5, spFlags: DISPFlagDefinition, unit: !2)
 // CHECK:STDOUT: !12 = !DILocation(line: 22, column: 29, scope: !11)
 // CHECK:STDOUT: !13 = !DILocation(line: 22, column: 50, scope: !11)
 // CHECK:STDOUT: !14 = !DILocation(line: 22, column: 28, scope: !11)

+ 7 - 7
toolchain/lower/testdata/packages/cross_package_call.carbon

@@ -11,19 +11,19 @@
 // --- a.carbon
 
 package A;
-
-fn F() {}
+namespace NS;
+fn NS.F() {}
 
 // --- b.carbon
 
 import A;
 
-fn G() { A.F(); }
+fn G() { A.NS.F(); }
 
 // CHECK:STDOUT: ; ModuleID = 'a.carbon'
 // CHECK:STDOUT: source_filename = "a.carbon"
 // CHECK:STDOUT:
-// CHECK:STDOUT: define void @_CF.A() !dbg !4 {
+// CHECK:STDOUT: define void @_CF.NS.A() !dbg !4 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   ret void, !dbg !7
 // CHECK:STDOUT: }
@@ -35,7 +35,7 @@ fn G() { A.F(); }
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
 // CHECK:STDOUT: !3 = !DIFile(filename: "a.carbon", directory: "")
-// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "F", linkageName: "_CF.A", scope: null, file: !3, line: 4, type: !5, spFlags: DISPFlagDefinition, unit: !2)
+// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "F", linkageName: "_CF.NS.A", scope: null, file: !3, line: 4, type: !5, spFlags: DISPFlagDefinition, unit: !2)
 // CHECK:STDOUT: !5 = !DISubroutineType(types: !6)
 // CHECK:STDOUT: !6 = !{}
 // CHECK:STDOUT: !7 = !DILocation(line: 4, column: 1, scope: !4)
@@ -44,11 +44,11 @@ fn G() { A.F(); }
 // CHECK:STDOUT:
 // CHECK:STDOUT: define void @_CG.Main() !dbg !4 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   call void @_CF.A.Main(), !dbg !7
+// CHECK:STDOUT:   call void @_CF.NS.A(), !dbg !7
 // CHECK:STDOUT:   ret void, !dbg !8
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_CF.A.Main()
+// CHECK:STDOUT: declare void @_CF.NS.A()
 // CHECK:STDOUT:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!2}

+ 5 - 0
toolchain/sem_ir/name_scope.h

@@ -81,6 +81,11 @@ struct NameScope : Printable<NameScope> {
                  name_entry.name_id);
   }
 
+  // Returns true if this name scope describes an imported package.
+  auto is_imported_package() const -> bool {
+    return is_closed_import && parent_scope_id == NameScopeId::Package;
+  }
+
   // Names in the scope. We store both an insertion-ordered vector for iterating
   // and a map from `NameId` to the index of that vector for name lookup.
   //