Skip to content

Commit ae5b385

Browse files
committed
[SILGen] Expand isNativeToForeignThunk
Expand to other cases where we emit a native-to-foreign thunk, but didn't previously return true. Because this now includes @objc entry-points for methods, adjust the linking logic so it can maintain more restrictive linkages for things like private decls.
1 parent c4c14ba commit ae5b385

File tree

1 file changed

+23
-16
lines changed

1 file changed

+23
-16
lines changed

lib/SIL/IR/SILDeclRef.cpp

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -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

634637
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+
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

Comments
 (0)