@@ -233,13 +233,11 @@ SILLinkage SILDeclRef::getLinkage(ForDefinition_t forDefinition) const {
233233 return forDefinition ? linkage : addExternalToLinkage (linkage);
234234 };
235235
236- // Native function-local declarations have shared linkage.
237- // FIXME: @objc declarations should be too, but we currently have no way
238- // of marking them "used" other than making them external.
236+ // Function-local declarations have private linkage, unless serialized.
239237 ValueDecl *d = getDecl ();
240238 DeclContext *moduleContext = d->getDeclContext ();
241239 while (!moduleContext->isModuleScopeContext ()) {
242- if (!isForeign && moduleContext->isLocalContext ()) {
240+ if (moduleContext->isLocalContext ()) {
243241 return isSerialized () ? SILLinkage::Shared : SILLinkage::Private;
244242 }
245243 moduleContext = moduleContext->getParent ();
@@ -249,11 +247,6 @@ SILLinkage SILDeclRef::getLinkage(ForDefinition_t forDefinition) const {
249247 if (isForeignToNativeThunk ())
250248 return SILLinkage::Shared;
251249
252- // If a function declares a @_cdecl name, its native-to-foreign thunk
253- // is exported with the visibility of the function.
254- if (isNativeToForeignThunk () && !d->getAttrs ().hasAttribute <CDeclAttr>())
255- return SILLinkage::Shared;
256-
257250 // Declarations imported from Clang modules have shared linkage.
258251 if (isClangImported ())
259252 return SILLinkage::Shared;
@@ -329,12 +322,20 @@ SILLinkage SILDeclRef::getLinkage(ForDefinition_t forDefinition) const {
329322 }
330323 }
331324
332- // Forced-static-dispatch functions are created on-demand and have
333- // at best shared linkage.
334325 if (auto fn = dyn_cast<FuncDecl>(d)) {
326+ // Forced-static-dispatch functions are created on-demand and have
327+ // at best shared linkage.
335328 if (fn->hasForcedStaticDispatch ()) {
336329 limit = Limit::OnDemand;
337330 }
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+ }
338339 }
339340
340341 if (isEnumElement ()) {
@@ -613,34 +614,42 @@ EffectsKind SILDeclRef::getEffectsAttribute() const {
613614}
614615
615616bool SILDeclRef::isForeignToNativeThunk () const {
617+ // If this isn't a native entry-point, it's not a foreign-to-native thunk.
618+ if (isForeign)
619+ return false ;
620+
616621 // Non-decl entry points are never natively foreign, so they would never
617622 // have a foreign-to-native thunk.
618623 if (!hasDecl ())
619624 return false ;
620625 if (requiresForeignToNativeThunk (getDecl ()))
621- return !isForeign ;
626+ return true ;
622627 // ObjC initializing constructors and factories are foreign.
623628 // We emit a special native allocating constructor though.
624629 if (isa<ConstructorDecl>(getDecl ())
625630 && (kind == Kind::Initializer
626631 || cast<ConstructorDecl>(getDecl ())->isFactoryInit ())
627632 && getDecl ()->hasClangNode ())
628- return !isForeign ;
633+ return true ;
629634 return false ;
630635}
631636
632637bool 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+
633642 // We can have native-to-foreign thunks over closures.
634643 if (!hasDecl ())
635- return isForeign ;
636- // We can have native-to-foreign thunks over global or local native functions.
637- // TODO: Static functions too .
638- if (auto func = dyn_cast<FuncDecl>( getDecl ())) {
639- if (!func-> getDeclContext ()-> isTypeContext ()
640- && !func-> hasClangNode ())
641- return isForeign;
642- }
643- 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 ;
644653}
645654
646655// / Use the Clang importer to mangle a Clang declaration.
0 commit comments