@@ -247,11 +247,6 @@ SILLinkage SILDeclRef::getLinkage(ForDefinition_t forDefinition) const {
247247 if (isForeignToNativeThunk ())
248248 return SILLinkage::Shared;
249249
250- // If a function declares a @_cdecl name, its native-to-foreign thunk
251- // is exported with the visibility of the function.
252- if (isNativeToForeignThunk () && !d->getAttrs ().hasAttribute <CDeclAttr>())
253- return SILLinkage::Shared;
254-
255250 // Declarations imported from Clang modules have shared linkage.
256251 if (isClangImported ())
257252 return SILLinkage::Shared;
@@ -327,12 +322,20 @@ SILLinkage SILDeclRef::getLinkage(ForDefinition_t forDefinition) const {
327322 }
328323 }
329324
330- // Forced-static-dispatch functions are created on-demand and have
331- // at best shared linkage.
332325 if (auto fn = dyn_cast<FuncDecl>(d)) {
326+ // Forced-static-dispatch functions are created on-demand and have
327+ // at best shared linkage.
333328 if (fn->hasForcedStaticDispatch ()) {
334329 limit = Limit::OnDemand;
335330 }
331+
332+ // Native-to-foreign thunks for top-level decls are created on-demand,
333+ // unless they are marked @_cdecl, in which case they expose a dedicated
334+ // entry-point with the visibility of the function.
335+ if (isNativeToForeignThunk () && !fn->getAttrs ().hasAttribute <CDeclAttr>()) {
336+ if (fn->getDeclContext ()->isModuleScopeContext ())
337+ limit = Limit::OnDemand;
338+ }
336339 }
337340
338341 if (isEnumElement ()) {
@@ -632,17 +635,21 @@ bool SILDeclRef::isForeignToNativeThunk() const {
632635}
633636
634637bool SILDeclRef::isNativeToForeignThunk () const {
638+ // If this isn't a foreign entry-point, it's not a native-to-foreign thunk.
639+ if (!isForeign)
640+ return false ;
641+
635642 // We can have native-to-foreign thunks over closures.
636643 if (!hasDecl ())
637- return isForeign ;
638- // We can have native-to-foreign thunks over global or local native functions.
639- // TODO: Static functions too .
640- if (auto func = dyn_cast<FuncDecl>( getDecl ())) {
641- if (!func-> getDeclContext ()-> isTypeContext ()
642- && !func-> hasClangNode ())
643- return isForeign;
644- }
645- return false ;
644+ return true ;
645+
646+ // A decl with a clang node doesn't have a native entry-point to forward onto .
647+ if (getDecl ()-> hasClangNode ())
648+ return false ;
649+
650+ // Only certain kinds of SILDeclRef can expose native-to-foreign thunks.
651+ return kind == Kind::Func || kind == Kind::Initializer ||
652+ kind == Kind::Deallocator ;
646653}
647654
648655// / Use the Clang importer to mangle a Clang declaration.
0 commit comments