Files
swift-mirror/test/attr/attr_extern_objc.swift
Xi Ge b1ee9e7456 c-interop: teach @c to handle ObjC type metatype Class. rdar://179401427
ClangImporter imports C 'Class' as AnyClass, but declaring a C-interop
function that takes/returns it via @c or @_extern(c) was rejected. Support it
across three layers:

Sema: make AnyClass (an ExistentialMetatypeType of AnyObject) representable in
ForeignLanguage::C, gated on ObjC interop since 'Class' is an ObjC runtime
type. Reuse getObjCObjectRepresentable so C and ObjC agree on the kind.

SILGen: a @c/@_extern(c) function is emitted directly as its C entry point
(no separate native thunk), so bridge the metatype at that boundary in place:
objc_to_thick_metatype on a 'Class' parameter in the prolog, and
thick_to_objc_metatype on an AnyClass result in the epilog. Both are no-ops
unless the native and foreign SIL types differ.

PrintAsClang: keep the @c declaration in the plain-C section and emit
'#include <objc/objc.h>' there when a @c decl uses 'Class', so the generated
header stays usable from plain C.
2026-07-12 08:25:22 -07:00

20 lines
658 B
Swift

// RUN: %target-typecheck-verify-swift -enable-experimental-feature Extern -disable-availability-checking
// REQUIRES: swift_feature_Extern
// REQUIRES: objc_interop
// AnyClass is representable in C: it maps to the Objective-C runtime type
// 'Class', matching how ClangImporter imports C 'Class' back into Swift.
@_extern(c)
func externAnyClassParam(_: AnyClass)
@_extern(c)
func externAnyClassReturn() -> AnyClass
// Protocol-qualified class metatypes (P.Type, i.e. C's 'Class<P>') are not
// representable: only bare AnyClass is.
@objc protocol EP {}
@_extern(c)
func externProtoMetatype(_: EP.Type) // expected-error {{cannot be represented in C}}