Skip to content

Commit 1ba18a0

Browse files
authored
Merge pull request #74250 from apple/gaborh/enum-element-method-name-clash
[cxx-interop] Avoid emitting methods that cause name clash
2 parents 0351ecd + 064a7dd commit 1ba18a0

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

lib/PrintAsClang/PrintClangFunction.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,17 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
713713
if (kind == FunctionSignatureKind::CxxInlineThunk)
714714
ClangSyntaxPrinter(os).printGenericSignature(Signature);
715715
}
716+
if (const auto *enumDecl = FD->getDeclContext()->getSelfEnumDecl()) {
717+
// We cannot emit functions with the same name as an enum case yet, the resulting header
718+
// does not compiler.
719+
// FIXME: either do not emit cases as inline members, or rename the cases or the
720+
// colliding functions.
721+
for (const auto *enumElement : enumDecl->getAllElements()) {
722+
auto elementName = enumElement->getName();
723+
if (!elementName.isSpecial() && elementName.getBaseIdentifier().is(name))
724+
return ClangRepresentation::unsupported;
725+
}
726+
}
716727
auto emittedModule = FD->getModuleContext();
717728
OutputLanguageMode outputLang = kind == FunctionSignatureKind::CFunctionProto
718729
? OutputLanguageMode::ObjC
@@ -1521,7 +1532,8 @@ void DeclAndTypeClangFunctionPrinter::printCxxMethod(
15211532
auto result = printFunctionSignature(
15221533
FD, signature, cxx_translation::getNameForCxx(FD), resultTy,
15231534
FunctionSignatureKind::CxxInlineThunk, modifiers);
1524-
assert(!result.isUnsupported() && "C signature should be unsupported too");
1535+
if (result.isUnsupported())
1536+
return;
15251537

15261538
declAndTypePrinter.printAvailability(os, FD);
15271539
if (!isDefinition) {
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend %s -typecheck -module-name Enums -clang-header-expose-decls=all-public -emit-clang-header-path %t/enums.h
3+
// RUN: %FileCheck %s < %t/enums.h
4+
5+
public enum Foo: Hashable, Sendable {
6+
case bar(Parameters)
7+
8+
// We do not want to generate C++ wrappers for this function yet
9+
// because its name clashes with the enum element above preventing
10+
// the generated header from compilation.
11+
public static func bar(version: Int) -> Self {
12+
Self.bar(Parameters(version: version))
13+
}
14+
}
15+
16+
extension Foo {
17+
public struct Parameters: Hashable, Sendable {
18+
public var version: Int
19+
20+
public init(version: Int) {
21+
self.version = version
22+
}
23+
}
24+
}
25+
26+
// CHECK-NOT: Foo bar(swift::Int version)
27+
28+
// CHECK: switch (_getEnumTag()) {
29+
// CHECK-NEXT: case 0: return cases::bar;
30+
// CHECK-NEXT: default: abort();
31+
// CHECK-NEXT: }
32+
// CHECK-NEXT: }
33+
// CHECK-EMPTY:
34+
// Before the fix, we had the static method's thunk here.
35+
// CHECK-NEXT: swift::Int getHashValue() const

0 commit comments

Comments
 (0)