From 18ee0ee6f1238793963e9e69b0ace4cd27336a92 Mon Sep 17 00:00:00 2001 From: susmonteiro Date: Mon, 10 Mar 2025 12:38:57 +0000 Subject: [PATCH] [cxx-interop] Use qualified name in import info of clang declarations --- lib/IRGen/GenMeta.cpp | 6 +-- test/Interop/Cxx/enum/Inputs/nested-enums.h | 38 +++++++++++++++++ .../enum/nested-enums-module-interface.swift | 4 ++ test/Interop/Cxx/enum/nested-enums.swift | 42 +++++++++++++++++++ 4 files changed, 87 insertions(+), 3 deletions(-) diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp index b125d5a4649e7..13fc696ce5345 100644 --- a/lib/IRGen/GenMeta.cpp +++ b/lib/IRGen/GenMeta.cpp @@ -1435,7 +1435,7 @@ namespace { // For related entities, set the original type name as the ABI name // and remember the related entity tag. - StringRef abiName; + std::string abiName; if (auto *synthesizedTypeAttr = Type->getAttrs() .template getAttribute()) { @@ -1455,7 +1455,7 @@ namespace { if (auto spec = dyn_cast(clangDecl)) abiName = Type->getName().str(); else - abiName = clangDecl->getName(); + abiName = clangDecl->getQualifiedNameAsString(); // Typedefs and compatibility aliases that have been promoted to // their own nominal types need to be marked specially. @@ -1469,7 +1469,7 @@ namespace { // If the ABI name differs from the user-facing name, add it as // an override. if (!abiName.empty() && abiName != UserFacingName) { - getMutableImportInfo().ABIName = std::string(abiName); + getMutableImportInfo().ABIName = abiName; } } diff --git a/test/Interop/Cxx/enum/Inputs/nested-enums.h b/test/Interop/Cxx/enum/Inputs/nested-enums.h index d7c9ef6bec552..520f52de9c911 100644 --- a/test/Interop/Cxx/enum/Inputs/nested-enums.h +++ b/test/Interop/Cxx/enum/Inputs/nested-enums.h @@ -20,8 +20,46 @@ enum EnumInNestedNS { kNestedB }; +enum EnumInNS { + kA = 0, + kB +}; + } } +namespace nsB { + +enum EnumInNS { + kA = 0, + kB +}; + +enum class ScopedEnumInNS { + scopeA, + scopeB +}; + +namespace nestedNS { + +enum EnumInNS { + kA = 0, + kB +}; + +} + +} + +class ClassA { +public: + enum class EnumInClass { scopeA, scopeB }; +}; + +class ClassB { +public: + enum class EnumInClass { scopeA, scopeB }; +}; + #endif // TEST_INTEROP_CXX_ENUM_INPUTS_NESTED_ENUMS_H diff --git a/test/Interop/Cxx/enum/nested-enums-module-interface.swift b/test/Interop/Cxx/enum/nested-enums-module-interface.swift index 4f317dfe91572..52ed5d088609c 100644 --- a/test/Interop/Cxx/enum/nested-enums-module-interface.swift +++ b/test/Interop/Cxx/enum/nested-enums-module-interface.swift @@ -14,5 +14,9 @@ // CHECK: } // CHECK-NEXT: static var kNestedA: ns.nestedNS.EnumInNestedNS { get } // CHECK-NEXT: static var kNestedB: ns.nestedNS.EnumInNestedNS { get } +// CHECK-NEXT: struct EnumInNS : Hashable, Equatable, RawRepresentable { +// CHECK: } +// CHECK-NEXT: static var kA: ns.nestedNS.EnumInNS { get } +// CHECK-NEXT: static var kB: ns.nestedNS.EnumInNS { get } // CHECK-NEXT: } // CHECK-NEXT:} diff --git a/test/Interop/Cxx/enum/nested-enums.swift b/test/Interop/Cxx/enum/nested-enums.swift index c127c582ab5de..34448a5c24df3 100644 --- a/test/Interop/Cxx/enum/nested-enums.swift +++ b/test/Interop/Cxx/enum/nested-enums.swift @@ -14,4 +14,46 @@ NestedEnumsTestSuite.test("Make and compare") { expectNotEqual(valNested, ns.nestedNS.kNestedB) } +NestedEnumsTestSuite.test("Same enum, different namespaces") { + let nsEnum1 : ns.EnumInNS = ns.kA + let nsEnum2 : ns.EnumInNS = ns.kA + + let nsBEnum1 : nsB.EnumInNS = nsB.kA + let nsBEnum2 : nsB.EnumInNS = nsB.kA + + expectEqual(nsEnum1, nsEnum2) + expectEqual(nsBEnum1, nsBEnum2) + + let nsNestedEnum1 : ns.nestedNS.EnumInNS = ns.nestedNS.kA + let nsNestedEnum2 : ns.nestedNS.EnumInNS = ns.nestedNS.kA + + let nsBNestedEnum1 : nsB.nestedNS.EnumInNS = nsB.nestedNS.kA + let nsBNestedEnum2 : nsB.nestedNS.EnumInNS = nsB.nestedNS.kA + + expectEqual(nsNestedEnum1, nsNestedEnum2) + expectEqual(nsBNestedEnum1, nsBNestedEnum2) +} + +NestedEnumsTestSuite.test("Same enum class, different namespaces") { + let nsEnumClass1 : ns.ScopedEnumInNS = ns.ScopedEnumInNS.scopeA + let nsEnumClass2 : ns.ScopedEnumInNS = ns.ScopedEnumInNS.scopeA + + let nsBEnumClass1 : nsB.ScopedEnumInNS = nsB.ScopedEnumInNS.scopeA + let nsBEnumClass2 : nsB.ScopedEnumInNS = nsB.ScopedEnumInNS.scopeA + + expectEqual(nsEnumClass1, nsEnumClass2) + expectEqual(nsBEnumClass1, nsBEnumClass2) +} + +NestedEnumsTestSuite.test("Same enum class, different classes") { + let classAEnum1 : ClassA.EnumInClass = .scopeA + let classAEnum2 : ClassA.EnumInClass = .scopeA + + let classBEnum1 : ClassB.EnumInClass = .scopeA + let classBEnum2 : ClassB.EnumInClass = .scopeA + + expectEqual(classAEnum1, classAEnum2) + expectEqual(classBEnum1, classBEnum2) +} + runAllTests()