@@ -247,11 +247,6 @@ SILLinkage SILDeclRef::getLinkage(ForDefinition_t forDefinition) const {
247
247
if (isForeignToNativeThunk ())
248
248
return SILLinkage::Shared;
249
249
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
-
255
250
// Declarations imported from Clang modules have shared linkage.
256
251
if (isClangImported ())
257
252
return SILLinkage::Shared;
@@ -327,12 +322,20 @@ SILLinkage SILDeclRef::getLinkage(ForDefinition_t forDefinition) const {
327
322
}
328
323
}
329
324
330
- // Forced-static-dispatch functions are created on-demand and have
331
- // at best shared linkage.
332
325
if (auto fn = dyn_cast<FuncDecl>(d)) {
326
+ // Forced-static-dispatch functions are created on-demand and have
327
+ // at best shared linkage.
333
328
if (fn->hasForcedStaticDispatch ()) {
334
329
limit = Limit::OnDemand;
335
330
}
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
+ }
336
339
}
337
340
338
341
if (isEnumElement ()) {
@@ -632,17 +635,21 @@ bool SILDeclRef::isForeignToNativeThunk() const {
632
635
}
633
636
634
637
bool 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
+
635
642
// We can have native-to-foreign thunks over closures.
636
643
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 ;
646
653
}
647
654
648
655
// / Use the Clang importer to mangle a Clang declaration.
0 commit comments