Merge pull request #85486 from egorzhdan/egorzhdan/wrap-in-objc

[cxx-interop] Wrap methods that take Obj-C params in `#if defined(__OBJC__)`
This commit is contained in:
Egor Zhdan
2025-12-01 22:58:49 +00:00
committed by GitHub
5 changed files with 55 additions and 4 deletions

View File

@@ -266,6 +266,10 @@ bool swift::cxx_translation::isObjCxxOnly(const ValueDecl *VD) {
bool swift::cxx_translation::isObjCxxOnly(const clang::Decl *D,
const ASTContext &ctx) {
// Check if this is decl can only be referred to from Objective-C.
if (isa<clang::ObjCInterfaceDecl>(D))
return true;
// By default, we import all modules in Obj-C++ mode, so there is no robust
// way to tell if something is coming from an Obj-C module. Use the
// requirements and the language options to check if we should actually

View File

@@ -0,0 +1,4 @@
module ObjCTypes {
header "objc-types.h"
export *
}

View File

@@ -0,0 +1,3 @@
@interface ObjCKlass
-(ObjCKlass * _Nonnull) init;
@end

View File

@@ -105,10 +105,19 @@ public class KVOCookieMonster {
// CHECK-NEXT: SWIFT_EXTERN id <ObjCProtocol> _Nullable $s9UseObjCTy03retB17CProtocolNullableSo0bE0_pSgyF(void) SWIFT_NOEXCEPT SWIFT_CALL; // retObjCProtocolNullable()
// CHECK-NEXT: #endif
// CHECK: ObjCKlass *_Nonnull $s9UseObjCTy03retB5ClassSo0B6CKlassCyF(void) SWIFT_NOEXCEPT SWIFT_CALL;
// CHECK-NEXT: #endif // defined(__OBJC__)
// CHECK-NEXT: #if defined(__OBJC__)
// CHECK-NEXT: ObjCKlass *_Nullable $s9UseObjCTy03retB13ClassNullableSo0B6CKlassCSgyF(void) SWIFT_NOEXCEPT SWIFT_CALL;
// CHECK-NEXT: #endif // defined(__OBJC__)
// CHECK-NEXT: #if defined(__OBJC__)
// CHECK-NEXT: void $s9UseObjCTy04takeB6CClassyySo0B6CKlassCF(ObjCKlass *_Nonnull x) SWIFT_NOEXCEPT SWIFT_CALL;
// CHECK-NEXT: #endif // defined(__OBJC__)
// CHECK-NEXT: #if defined(__OBJC__)
// CHECK-NEXT: void $s9UseObjCTy04takeB11CClassInoutyySo0B6CKlassCzF(ObjCKlass *_Nonnull __strong * _Nonnull x) SWIFT_NOEXCEPT SWIFT_CALL;
// CHECK-NEXT: #endif // defined(__OBJC__)
// CHECK-NEXT: #if defined(__OBJC__)
// CHECK-NEXT: void $s9UseObjCTy04takeB14CClassNullableyySo0B6CKlassCSgF(ObjCKlass *_Nullable x) SWIFT_NOEXCEPT SWIFT_CALL;
// CHECK-NEXT: #endif // defined(__OBJC__)
// CHECK-NEXT: #if defined(__OBJC__)
// CHECK-NEXT: SWIFT_EXTERN void $s9UseObjCTy04takeB9CProtocolyySo0bE0_pF(id <ObjCProtocol> _Nonnull x) SWIFT_NOEXCEPT SWIFT_CALL; // takeObjCProtocol(_:)
// CHECK-NEXT: #endif
@@ -124,17 +133,16 @@ public class KVOCookieMonster {
// CHECK-NEXT: }
// CHECK-NEXT: };
// CHECK: #if defined(__OBJC__)
// CHECK-NEXT: SWIFT_INLINE_THUNK id <ObjCProtocol> _Nonnull retObjCProtocol() noexcept SWIFT_SYMBOL("s:9UseObjCTy03retB9CProtocolSo0bE0_pyF") SWIFT_WARN_UNUSED_RESULT {
// CHECK: SWIFT_INLINE_THUNK id <ObjCProtocol> _Nonnull retObjCProtocol() noexcept SWIFT_SYMBOL("s:9UseObjCTy03retB9CProtocolSo0bE0_pyF") SWIFT_WARN_UNUSED_RESULT {
// CHECK-NEXT: return (__bridge_transfer id <ObjCProtocol>)(__bridge void *)UseObjCTy::_impl::$s9UseObjCTy03retB9CProtocolSo0bE0_pyF();
// CHECK-NEXT: }
// CHECK-NEXT: #endif
// CHECK-NEXT: #endif // defined(__OBJC__)
// CHECK: #if defined(__OBJC__)
// CHECK-NEXT: SWIFT_INLINE_THUNK id <ObjCProtocol> _Nullable retObjCProtocolNullable() noexcept SWIFT_SYMBOL("s:9UseObjCTy03retB17CProtocolNullableSo0bE0_pSgyF") SWIFT_WARN_UNUSED_RESULT {
// CHECK-NEXT: return (__bridge_transfer id <ObjCProtocol>)(__bridge void *)UseObjCTy::_impl::$s9UseObjCTy03retB17CProtocolNullableSo0bE0_pSgyF();
// CHECK-NEXT: }
// CHECK-NEXT: #endif
// CHECK-NEXT: #endif // defined(__OBJC__)
// CHECK: SWIFT_INLINE_THUNK ObjCKlass *_Nonnull retObjClass() noexcept SWIFT_SYMBOL({{.*}}) SWIFT_WARN_UNUSED_RESULT {
// CHECK-NEXT: return (__bridge_transfer ObjCKlass *)(__bridge void *)UseObjCTy::_impl::$s9UseObjCTy03retB5ClassSo0B6CKlassCyF();

View File

@@ -0,0 +1,32 @@
// RUN: %target-swift-frontend %s -module-name ObjCInCXX -typecheck -verify -I %S/Inputs -emit-clang-header-path %t/ObjCInCXX.h -I %t -cxx-interoperability-mode=default
// RUN: %FileCheck %s < %t/ObjCInCXX.h
// Make sure the header is valid when parsed in C++ language mode, without Obj-C.
// RUN: %target-interop-build-clang -fobjc-arc -c -x c++-header %t/ObjCInCXX.h -o %t/o.o
// REQUIRES: objc_interop
import ObjCTypes
public struct HasObjCInit {
private let privateField: Int = 0
public init(_ o: ObjCKlass) {}
}
public struct HasObjCMethod {
private let privateField: Int = 0
public func takesObjCKlass(_ o: ObjCKlass) {}
}
// CHECK: SWIFT_INLINE_THUNK HasObjCInit HasObjCInit::init(ObjCKlass *_Nonnull o) {
// CHECK: return {{.*}} {
// CHECK: }
// CHECK-NEXT: }
// CHECK-NEXT: #endif // defined(__OBJC__)
// CHECK: SWIFT_INLINE_THUNK void HasObjCMethod::takesObjCKlass(ObjCKlass *_Nonnull o) const {
// CHECK-NEXT: ObjCInCXX::{{.*}}
// CHECK-NEXT: }
// CHECK-NEXT: #endif // defined(__OBJC__)