Skip to content

Commit cfbdd76

Browse files
committed
[cxx-interop] Avoid ambiguous C++ overloads for functions from Swift extensions
Reverse interop has logic that avoids emitting ambiguous overloads into the generated header. That logic did not apply for functions declared within Swift extensions. This meant that the generated C++ header would sometimes not compile. rdar://158252800
1 parent d8edd86 commit cfbdd76

File tree

3 files changed

+52
-2
lines changed

3 files changed

+52
-2
lines changed

lib/PrintAsClang/DeclAndTypePrinter.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,6 @@ class DeclAndTypePrinter::Implementation
253253
/// Prints the members of a class, extension, or protocol.
254254
template <bool AllowDelayed = false, typename R>
255255
void printMembers(R &&members) {
256-
CxxEmissionScopeRAII cxxScopeRAII(owningPrinter);
257256
// Using statements for nested types.
258257
if (outputLang == OutputLanguageMode::Cxx) {
259258
for (const Decl *member : members) {
@@ -373,7 +372,12 @@ class DeclAndTypePrinter::Implementation
373372
if (outputLang == OutputLanguageMode::Cxx) {
374373
// FIXME: Non objc class.
375374
ClangClassTypePrinter(os).printClassTypeDecl(
376-
CD, [&]() { printMembers(CD->getAllMembers()); }, owningPrinter);
375+
CD,
376+
[&]() {
377+
CxxEmissionScopeRAII cxxScopeRAII(owningPrinter);
378+
printMembers(CD->getAllMembers());
379+
},
380+
owningPrinter);
377381
recordEmittedDeclInCurrentCxxLexicalScope(CD);
378382
return;
379383
}
@@ -426,6 +430,7 @@ class DeclAndTypePrinter::Implementation
426430
printer.printValueTypeDecl(
427431
SD, /*bodyPrinter=*/
428432
[&]() {
433+
CxxEmissionScopeRAII cxxScopeRAII(owningPrinter);
429434
printMembers(SD->getAllMembers());
430435
for (const auto *ed :
431436
owningPrinter.interopContext.getExtensionsForNominalType(SD)) {
@@ -922,6 +927,7 @@ class DeclAndTypePrinter::Implementation
922927
os << " }\n"; // operator cases()'s closing bracket
923928
os << "\n";
924929

930+
CxxEmissionScopeRAII cxxScopeRAII(owningPrinter);
925931
printMembers(ED->getAllMembers());
926932

927933
for (const auto *ext :
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend %s -module-name Init -clang-header-expose-decls=all-public -typecheck -verify -emit-clang-header-path %t/inits.h
3+
// RUN: %FileCheck %s < %t/inits.h
4+
5+
// RUN: %check-interop-cxx-header-in-clang(%t/inits.h -Wno-unused-function -DSWIFT_CXX_INTEROP_HIDE_STL_OVERLAY)
6+
7+
public struct OverloadedInitInExtension {
8+
let x: Int
9+
10+
public init(_ x: Int) {
11+
self.x = x
12+
}
13+
}
14+
extension OverloadedInitInExtension {
15+
public init(viaExtension x: Int) {
16+
self.x = x
17+
}
18+
}
19+
20+
// Make sure we don't emit ambiguous overloads:
21+
// CHECK: static SWIFT_INLINE_THUNK OverloadedInitInExtension init(swift::Int x)
22+
// CHECK-NOT: static SWIFT_INLINE_THUNK OverloadedInitInExtension init(swift::Int x)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend %s -module-name Method -clang-header-expose-decls=all-public -typecheck -verify -emit-clang-header-path %t/methods.h
3+
// RUN: %FileCheck %s < %t/methods.h
4+
5+
// RUN: %check-interop-cxx-header-in-clang(%t/methods.h -Wno-unused-function -DSWIFT_CXX_INTEROP_HIDE_STL_OVERLAY)
6+
7+
public struct OverloadedMethodInExtension {
8+
var x: Int
9+
10+
public mutating func add(_ x: Int) {
11+
self.x += x
12+
}
13+
}
14+
extension OverloadedMethodInExtension {
15+
public mutating func add(viaExtension x: Int) {
16+
self.x += x
17+
}
18+
}
19+
20+
// Make sure we don't emit ambiguous overloads:
21+
// CHECK: SWIFT_INLINE_THUNK void OverloadedMethodInExtension::add(swift::Int x)
22+
// CHECK-NOT: SWIFT_INLINE_THUNK void OverloadedMethodInExtension::add(swift::Int x)

0 commit comments

Comments
 (0)