Ver Fonte

Mangle class declarations #6617 (#6648)

In some situations we need to mangle class declarations, which then are
not NameScopes (can't scope anything inside a declaration) - so make the
mangler able to cope with that situation by mangling the name of the
class directly rather than relying on generic NameScope mangling to
handle the class case.
David Blaikie há 3 meses atrás
pai
commit
a1efc4be8f

+ 17 - 7
toolchain/lower/mangler.cpp

@@ -83,11 +83,15 @@ auto Mangler::MangleInverseQualifiedNameScope(llvm::raw_ostream& os,
         auto self_inst = insts().Get(self_const_inst_id);
         CARBON_KIND_SWITCH(self_inst) {
           case CARBON_KIND(SemIR::ClassType class_type): {
-            auto next_name_scope_id =
-                sem_ir().classes().Get(class_type.class_id).scope_id;
-            names_to_render.push_back({.name_scope_id = next_name_scope_id,
-                                       .specific_id = class_type.specific_id,
-                                       .prefix = '\0'});
+            const auto& class_info =
+                sem_ir().classes().Get(class_type.class_id);
+
+            names_to_render.push_back(
+                {.name_scope_id = class_info.parent_scope_id,
+                 .specific_id = class_type.specific_id,
+                 .prefix = '.'});
+
+            MangleUnqualifiedClass(os, class_info, class_type.specific_id);
             break;
           }
           case SemIR::AutoType::Kind:
@@ -128,8 +132,8 @@ auto Mangler::MangleInverseQualifiedNameScope(llvm::raw_ostream& os,
         continue;
       }
       case CARBON_KIND(SemIR::ClassDecl class_decl): {
-        MangleNameId(os, sem_ir().classes().Get(class_decl.class_id).name_id);
-        MangleSpecificId(os, specific_id);
+        MangleUnqualifiedClass(os, sem_ir().classes().Get(class_decl.class_id),
+                               specific_id);
         break;
       }
       case CARBON_KIND(SemIR::InterfaceDecl interface_decl): {
@@ -264,4 +268,10 @@ auto Mangler::MangleVTable(const SemIR::Class& class_info,
   return os.TakeStr();
 }
 
+auto Mangler::MangleUnqualifiedClass(llvm::raw_ostream& os,
+                                     const SemIR::Class& class_info,
+                                     SemIR::SpecificId specific_id) -> void {
+  MangleNameId(os, class_info.name_id);
+  MangleSpecificId(os, specific_id);
+}
 }  // namespace Carbon::Lower

+ 5 - 0
toolchain/lower/mangler.h

@@ -58,6 +58,11 @@ class Mangler {
                                        SemIR::NameScopeId name_scope_id)
       -> void;
 
+  // Mangle the unqualified name of the specified `Class`.
+  auto MangleUnqualifiedClass(llvm::raw_ostream& os,
+                              const SemIR::Class& class_info,
+                              SemIR::SpecificId specific_id) -> void;
+
   // Generates a mangled name using Clang mangling for imported C++ functions.
   auto MangleCppClang(const clang::NamedDecl* decl) -> std::string;
 

+ 42 - 0
toolchain/lower/testdata/interface/mangle_declared_class.carbon

@@ -0,0 +1,42 @@
+// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/convert.carbon
+//
+// AUTOUPDATE
+// TIP: To test this file alone, run:
+// TIP:   bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/lower/testdata/interface/mangle_declared_class.carbon
+// TIP: To dump output, run:
+// TIP:   bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/lower/testdata/interface/mangle_declared_class.carbon
+
+interface I {
+  fn F();
+}
+class C;
+impl C as I {
+  fn F() {}
+}
+
+// CHECK:STDOUT: ; ModuleID = 'mangle_declared_class.carbon'
+// CHECK:STDOUT: source_filename = "mangle_declared_class.carbon"
+// CHECK:STDOUT:
+// CHECK:STDOUT: ; Function Attrs: nounwind
+// CHECK:STDOUT: define void @"_CF.C.Main:I.Main"() #0 !dbg !4 {
+// CHECK:STDOUT: entry:
+// CHECK:STDOUT:   ret void, !dbg !7
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: attributes #0 = { nounwind }
+// CHECK:STDOUT:
+// CHECK:STDOUT: !llvm.module.flags = !{!0, !1}
+// CHECK:STDOUT: !llvm.dbg.cu = !{!2}
+// CHECK:STDOUT:
+// CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
+// CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
+// CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
+// CHECK:STDOUT: !3 = !DIFile(filename: "mangle_declared_class.carbon", directory: "")
+// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "F", linkageName: "_CF.C.Main:I.Main", scope: null, file: !3, line: 18, type: !5, spFlags: DISPFlagDefinition, unit: !2)
+// CHECK:STDOUT: !5 = !DISubroutineType(types: !6)
+// CHECK:STDOUT: !6 = !{null}
+// CHECK:STDOUT: !7 = !DILocation(line: 18, column: 3, scope: !4)