@@ -233,13 +233,11 @@ SILLinkage SILDeclRef::getLinkage(ForDefinition_t forDefinition) const {
233
233
return forDefinition ? linkage : addExternalToLinkage (linkage);
234
234
};
235
235
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.
239
237
ValueDecl *d = getDecl ();
240
238
DeclContext *moduleContext = d->getDeclContext ();
241
239
while (!moduleContext->isModuleScopeContext ()) {
242
- if (!isForeign && moduleContext->isLocalContext ()) {
240
+ if (moduleContext->isLocalContext ()) {
243
241
return isSerialized () ? SILLinkage::Shared : SILLinkage::Private;
244
242
}
245
243
moduleContext = moduleContext->getParent ();
@@ -249,11 +247,6 @@ SILLinkage SILDeclRef::getLinkage(ForDefinition_t forDefinition) const {
249
247
if (isForeignToNativeThunk ())
250
248
return SILLinkage::Shared;
251
249
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
-
257
250
// Declarations imported from Clang modules have shared linkage.
258
251
if (isClangImported ())
259
252
return SILLinkage::Shared;
@@ -329,12 +322,20 @@ SILLinkage SILDeclRef::getLinkage(ForDefinition_t forDefinition) const {
329
322
}
330
323
}
331
324
332
- // Forced-static-dispatch functions are created on-demand and have
333
- // at best shared linkage.
334
325
if (auto fn = dyn_cast<FuncDecl>(d)) {
326
+ // Forced-static-dispatch functions are created on-demand and have
327
+ // at best shared linkage.
335
328
if (fn->hasForcedStaticDispatch ()) {
336
329
limit = Limit::OnDemand;
337
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
+ }
338
339
}
339
340
340
341
if (isEnumElement ()) {
@@ -613,34 +614,42 @@ EffectsKind SILDeclRef::getEffectsAttribute() const {
613
614
}
614
615
615
616
bool 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
+
616
621
// Non-decl entry points are never natively foreign, so they would never
617
622
// have a foreign-to-native thunk.
618
623
if (!hasDecl ())
619
624
return false ;
620
625
if (requiresForeignToNativeThunk (getDecl ()))
621
- return !isForeign ;
626
+ return true ;
622
627
// ObjC initializing constructors and factories are foreign.
623
628
// We emit a special native allocating constructor though.
624
629
if (isa<ConstructorDecl>(getDecl ())
625
630
&& (kind == Kind::Initializer
626
631
|| cast<ConstructorDecl>(getDecl ())->isFactoryInit ())
627
632
&& getDecl ()->hasClangNode ())
628
- return !isForeign ;
633
+ return true ;
629
634
return false ;
630
635
}
631
636
632
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
+
633
642
// We can have native-to-foreign thunks over closures.
634
643
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 ;
644
653
}
645
654
646
655
// / Use the Clang importer to mangle a Clang declaration.
0 commit comments