Skip to content

[cxx-interop] Use qualified name in import info of clang declarations #79791

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions lib/IRGen/GenMeta.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<ClangImporterSynthesizedTypeAttr>()) {
Expand All @@ -1455,7 +1455,7 @@ namespace {
if (auto spec = dyn_cast<clang::ClassTemplateSpecializationDecl>(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.
Expand All @@ -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;
}
}

Expand Down
38 changes: 38 additions & 0 deletions test/Interop/Cxx/enum/Inputs/nested-enums.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
4 changes: 4 additions & 0 deletions test/Interop/Cxx/enum/nested-enums-module-interface.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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:}
42 changes: 42 additions & 0 deletions test/Interop/Cxx/enum/nested-enums.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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()