Skip to content

Commit d243b8d

Browse files
authored
Merge pull request #84974 from DougGregor/extern-c-foreign
[SILGen] Switch `@_extern(c)` over to a foreign entrypoint
2 parents 75f8041 + 79fc0f1 commit d243b8d

File tree

5 files changed

+31
-10
lines changed

5 files changed

+31
-10
lines changed

lib/SIL/IR/SILDeclRef.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ bool swift::requiresForeignEntryPoint(ValueDecl *vd) {
111111
if (vd->hasClangNode())
112112
return true;
113113

114+
if (ExternAttr::find(vd->getAttrs(), ExternKind::C))
115+
return true;
116+
114117
if (auto *accessor = dyn_cast<AccessorDecl>(vd)) {
115118
// Property accessors should be generated alongside the property.
116119
if (accessor->isGetterOrSetter()) {

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4474,8 +4474,6 @@ TypeConverter::getDeclRefRepresentation(SILDeclRef c) {
44744474
case SILDeclRef::Kind::Func:
44754475
if (c.getDecl()->getDeclContext()->isTypeContext())
44764476
return SILFunctionTypeRepresentation::Method;
4477-
if (ExternAttr::find(c.getDecl()->getAttrs(), ExternKind::C))
4478-
return SILFunctionTypeRepresentation::CFunctionPointer;
44794477
return SILFunctionTypeRepresentation::Thin;
44804478

44814479
case SILDeclRef::Kind::Destroyer:

lib/SILGen/SILGenExpr.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -996,6 +996,9 @@ emitRValueForDecl(SILLocation loc, ConcreteDeclRef declRef, Type ncRefType,
996996
// If the referenced decl isn't a VarDecl, it should be a constant of some
997997
// sort.
998998
SILDeclRef silDeclRef(decl);
999+
if (ExternAttr::find(decl->getAttrs(), ExternKind::C))
1000+
silDeclRef = silDeclRef.asForeign();
1001+
9991002
assert(silDeclRef.getParameterListCount() == 1);
10001003
auto substType = cast<AnyFunctionType>(refType);
10011004
auto typeContext = getFunctionTypeInfo(substType);

lib/Sema/TypeCheckDecl.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2565,6 +2565,11 @@ InterfaceTypeRequest::evaluate(Evaluator &eval, ValueDecl *D) const {
25652565
infoBuilder = infoBuilder.withSendingResult();
25662566
}
25672567

2568+
if (ExternAttr::find(D->getAttrs(), ExternKind::C)) {
2569+
infoBuilder = infoBuilder.withRepresentation(
2570+
FunctionTypeRepresentation::CFunctionPointer);
2571+
}
2572+
25682573
// Lifetime dependencies only apply to the outer function type.
25692574
if (!hasSelf && lifetimeDependenceInfo.has_value()) {
25702575
infoBuilder =

test/SILGen/extern_c.swift

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,46 +6,58 @@
66
@_extern(c, "my_c_name")
77
func withCName(_ x: Int) -> Int
88

9-
// CHECK-DAG: sil hidden_external [asmname "take_c_func_ptr"] @$s8extern_c12takeCFuncPtryyS2iXCF : $@convention(c) (@convention(c) (Int) -> Int) -> ()
9+
// CHECK-DAG: sil hidden_external [asmname "take_c_func_ptr"] @$s8extern_c12takeCFuncPtryyS2iXCFTo : $@convention(c) (@convention(c) (Int) -> Int) -> ()
1010
@_extern(c, "take_c_func_ptr")
1111
func takeCFuncPtr(_ f: @convention(c) (Int) -> Int)
1212

13-
// CHECK-DAG: sil [asmname "public_visible"] @$s8extern_c16publicVisibilityyS2iF : $@convention(c) (Int) -> Int
13+
// CHECK-DAG: sil [serialized] [asmname "public_visible"] @$s8extern_c16publicVisibilityyS2iFTo : $@convention(c) (Int) -> Int
1414
@_extern(c, "public_visible")
1515
public func publicVisibility(_ x: Int) -> Int
1616

1717
// CHECK-DAG: sil [asmname "private_visible"] @$s8extern_c17privateVisibility{{.*}} : $@convention(c) (Int) -> Int
1818
@_extern(c, "private_visible")
1919
private func privateVisibility(_ x: Int) -> Int
2020

21-
// CHECK-DAG: sil hidden_external [asmname "withoutCName"] @$s8extern_c12withoutCNameSiyF : $@convention(c) () -> Int
21+
// CHECK-DAG: sil hidden_external [asmname "withoutCName"] @$s8extern_c12withoutCNameSiyFTo : $@convention(c) () -> Int
2222
@_extern(c)
2323
func withoutCName() -> Int
2424

2525
// CHECK-DAG: sil hidden [ossa] @$s8extern_c10defaultArgyySiFfA_ : $@convention(thin) () -> Int {
26-
// CHECK-DAG: sil hidden_external [asmname "default_arg"] @$s8extern_c10defaultArgyySiF : $@convention(c) (Int) -> ()
26+
// CHECK-DAG: sil hidden_external [asmname "default_arg"] @$s8extern_c10defaultArgyySiFTo : $@convention(c) (Int) -> ()
2727
@_extern(c, "default_arg")
2828
func defaultArg(_ x: Int = 42)
2929

30+
func callMe(body: (Int) -> Int) -> Int {
31+
return body(17)
32+
}
33+
3034
func main() {
3135
// CHECK-DAG: [[F1:%.+]] = function_ref @$s8extern_c9withCNameyS2iFTo : $@convention(c) (Int) -> Int
32-
// CHECK-DAG: [[F2:%.+]] = function_ref @$s8extern_c12takeCFuncPtryyS2iXCF : $@convention(c) (@convention(c) (Int) -> Int) -> ()
36+
// CHECK-DAG: [[F2:%.+]] = function_ref @$s8extern_c12takeCFuncPtryyS2iXCFTo : $@convention(c) (@convention(c) (Int) -> Int) -> ()
3337
// CHECK-DAG: apply [[F2]]([[F1]]) : $@convention(c) (@convention(c) (Int) -> Int) -> ()
3438
takeCFuncPtr(withCName)
35-
// CHECK-DAG: [[F3:%.+]] = function_ref @$s8extern_c16publicVisibilityyS2iF : $@convention(c) (Int) -> Int
39+
// CHECK-DAG: [[F3:%.+]] = function_ref @$s8extern_c16publicVisibilityyS2iFTo : $@convention(c) (Int) -> Int
3640
// CHECK-DAG: apply [[F3]]({{.*}}) : $@convention(c) (Int) -> Int
3741
_ = publicVisibility(42)
3842
// CHECK-DAG: [[F4:%.+]] = function_ref @$s8extern_c17privateVisibility{{.*}} : $@convention(c) (Int) -> Int
3943
// CHECK-DAG: apply [[F4]]({{.*}}) : $@convention(c) (Int) -> Int
4044
_ = privateVisibility(24)
41-
// CHECK-DAG: [[F5:%.+]] = function_ref @$s8extern_c12withoutCNameSiyF : $@convention(c) () -> Int
45+
// CHECK-DAG: [[F5:%.+]] = function_ref @$s8extern_c12withoutCNameSiyFTo : $@convention(c) () -> Int
4246
// CHECK-DAG: apply [[F5]]() : $@convention(c) () -> Int
4347
_ = withoutCName()
4448
// CHECK-DAG: [[F6:%.+]] = function_ref @$s8extern_c10defaultArgyySiFfA_ : $@convention(thin) () -> Int
4549
// CHECK-DAG: [[DEFAULT_V:%.+]] = apply [[F6]]() : $@convention(thin) () -> Int
46-
// CHECK-DAG: [[F7:%.+]] = function_ref @$s8extern_c10defaultArgyySiF : $@convention(c) (Int) -> ()
50+
// CHECK-DAG: [[F7:%.+]] = function_ref @$s8extern_c10defaultArgyySiFTo : $@convention(c) (Int) -> ()
4751
// CHECK-DAG: apply [[F7]]([[DEFAULT_V]]) : $@convention(c) (Int) -> ()
4852
defaultArg()
53+
54+
// CHECK-DAG: [[CREF:%[0-9]+]] = function_ref @$s8extern_c16publicVisibilityyS2iFTo : $@convention(c) (Int) -> Int
55+
// CHECK-DAG: [[THUNK:%[0-9]+]] = function_ref @$sS2iIetCyd_S2iIegyd_TR : $@convention(thin) (Int, @convention(c) (Int) -> Int) -> Int
56+
// CHECK-DAG: [[APPLIED:%[0-9]+]] = partial_apply [callee_guaranteed] [[THUNK]]([[CREF]]) : $@convention(thin) (Int, @convention(c) (Int) -> Int) -> Int
57+
// CHECK-DAG: [[NOESCAPE_APPLIED:%[0-9]+]] = convert_escape_to_noescape [not_guaranteed] [[APPLIED]] to $@noescape @callee_guaranteed (Int) -> Int
58+
// CHECK-DAG: [[CALL_ME:%[0-9]+]] = function_ref @$s8extern_c6callMe4bodyS3iXE_tF
59+
// CHECK-DAG: apply [[CALL_ME]]([[NOESCAPE_APPLIED]]) : $@convention(thin) (@guaranteed @noescape @callee_guaranteed (Int) -> Int) -> Int
60+
_ = callMe(body: publicVisibility)
4961
}
5062

5163
main()

0 commit comments

Comments
 (0)