@@ -89,6 +89,11 @@ bool swift::requiresForeignToNativeThunk(ValueDecl *vd) {
8989 if (proto->isObjC ())
9090 return true ;
9191
92+ // If there is only a C entrypoint from a Swift function, we will need
93+ // foreign-to-native thunks to deal with them.
94+ if (vd->hasOnlyCEntryPoint ())
95+ return true ;
96+
9297 if (auto fd = dyn_cast<FuncDecl>(vd))
9398 return fd->hasClangNode ();
9499
@@ -111,7 +116,7 @@ bool swift::requiresForeignEntryPoint(ValueDecl *vd) {
111116 if (vd->hasClangNode ())
112117 return true ;
113118
114- if (ExternAttr::find ( vd->getAttrs (), ExternKind::C ))
119+ if (vd->hasOnlyCEntryPoint ( ))
115120 return true ;
116121
117122 if (auto *accessor = dyn_cast<AccessorDecl>(vd)) {
@@ -131,7 +136,9 @@ SILDeclRef::SILDeclRef(ValueDecl *vd, SILDeclRef::Kind kind, bool isForeign,
131136 bool isRuntimeAccessible,
132137 SILDeclRef::BackDeploymentKind backDeploymentKind,
133138 AutoDiffDerivativeFunctionIdentifier *derivativeId)
134- : loc(vd), kind(kind), isForeign(isForeign), distributedThunk(isDistributedThunk),
139+ : loc(vd), kind(kind),
140+ isForeign(isForeign),
141+ distributedThunk(isDistributedThunk),
135142 isKnownToBeLocal(isKnownToBeLocal),
136143 isRuntimeAccessible(isRuntimeAccessible),
137144 backDeploymentKind(backDeploymentKind), defaultArgIndex(0 ),
@@ -470,7 +477,8 @@ static LinkageLimit getLinkageLimit(SILDeclRef constant) {
470477 // Native-to-foreign thunks for methods are always just private, since
471478 // they're anchored by Objective-C metadata.
472479 auto &attrs = fn->getAttrs ();
473- if (constant.isNativeToForeignThunk () && !attrs.hasAttribute <CDeclAttr>()) {
480+ if (constant.isNativeToForeignThunk () &&
481+ !(attrs.hasAttribute <CDeclAttr>() && !fn->hasOnlyCEntryPoint ())) {
474482 auto isTopLevel = fn->getDeclContext ()->isModuleScopeContext ();
475483 return isTopLevel ? Limit::OnDemand : Limit::Private;
476484 }
@@ -1268,6 +1276,10 @@ bool SILDeclRef::isNativeToForeignThunk() const {
12681276 if (getDecl ()->getAttrs ().hasAttribute <ExternAttr>())
12691277 return false ;
12701278
1279+ // No thunk is required if the decl directly exposes a C entry point.
1280+ if (getDecl ()->hasOnlyCEntryPoint ())
1281+ return false ;
1282+
12711283 // Only certain kinds of SILDeclRef can expose native-to-foreign thunks.
12721284 return kind == Kind::Func || kind == Kind::Initializer ||
12731285 kind == Kind::Deallocator;
@@ -1433,7 +1445,7 @@ std::string SILDeclRef::mangle(ManglingKind MKind) const {
14331445
14341446 // Use a given cdecl name for native-to-foreign thunks.
14351447 if (getDecl ()->getAttrs ().hasAttribute <CDeclAttr>())
1436- if (isNativeToForeignThunk ()) {
1448+ if (isNativeToForeignThunk () || isForeign ) {
14371449 // If this is an @implementation @_cdecl, mangle it like the clang
14381450 // function it implements.
14391451 if (auto objcInterface = getDecl ()->getImplementedObjCDecl ()) {
0 commit comments