Skip to content

Commit 39a36d9

Browse files
authored
Merge pull request #84948 from DougGregor/extern-c-asmname
[SILGen] Map the @_extern(c) C function name over to the asmname of a SIL function
2 parents bb9ab0d + 1ca9235 commit 39a36d9

File tree

9 files changed

+57
-21
lines changed

9 files changed

+57
-21
lines changed

lib/SIL/IR/SILDeclRef.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1428,11 +1428,6 @@ std::string SILDeclRef::mangle(ManglingKind MKind) const {
14281428
return NameA->Name.str();
14291429
}
14301430

1431-
if (auto *ExternA = ExternAttr::find(getDecl()->getAttrs(), ExternKind::C)) {
1432-
assert(isa<FuncDecl>(getDecl()) && "non-FuncDecl with @_extern should be rejected by typechecker");
1433-
return ExternA->getCName(cast<FuncDecl>(getDecl())).str();
1434-
}
1435-
14361431
// Use a given cdecl name for native-to-foreign thunks.
14371432
if (getDecl()->getAttrs().hasAttribute<CDeclAttr>())
14381433
if (isNativeToForeignThunk()) {

lib/SIL/IR/SILFunctionBuilder.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,12 @@ void SILFunctionBuilder::addFunctionAttributes(
126126
F->setEffectsKind(effectsAttr->getKind());
127127
}
128128
}
129+
130+
if (constant.isFunc() && constant.hasFuncDecl()) {
131+
auto func = constant.getFuncDecl();
132+
if (auto *EA = ExternAttr::find(Attrs, ExternKind::C))
133+
F->setAsmName(EA->getCName(func));
134+
}
129135
}
130136

131137
if (!customEffects.empty()) {

lib/Serialization/Serialization.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -975,7 +975,7 @@ void Serializer::writeBlockInfoBlock() {
975975
BLOCK_RECORD(sil_block, SIL_SOURCE_LOC_REF);
976976
BLOCK_RECORD(sil_block, SIL_DEBUG_VALUE);
977977
BLOCK_RECORD(sil_block, SIL_DEBUG_VALUE_DELIMITER);
978-
978+
BLOCK_RECORD(sil_block, SIL_EXTRA_STRING);
979979

980980
BLOCK(SIL_INDEX_BLOCK);
981981
BLOCK_RECORD(sil_index_block, SIL_FUNC_NAMES);
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
@_extern(c, "takes_a_void_pointer")
2+
public func takes_a_void_pointer(_ pointer: UnsafeRawPointer)
3+
4+
@_alwaysEmitIntoClient
5+
public func callWithNonNull() {
6+
let pointer = UnsafeMutablePointer<Int>.allocate(capacity: 1)
7+
takes_a_void_pointer(UnsafeRawPointer(pointer))
8+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
@_extern(c, "takes_a_void_pointer")
2+
public func takes_a_void_pointer(_ pointer: UnsafeRawPointer?)
3+
4+
@_alwaysEmitIntoClient
5+
public func callWithNullable() {
6+
takes_a_void_pointer(nil)
7+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -emit-module -enable-experimental-feature Extern -o %t %S/Inputs/extern_with_nullable.swift
3+
// RUN: %target-swift-frontend -emit-module -enable-experimental-feature Extern -o %t %S/Inputs/extern_with_nonnull.swift
4+
// RUN: %target-swift-frontend -emit-sil -o %t -I %t -primary-file %s -module-name main -O
5+
6+
// REQUIRES: swift_feature_Extern
7+
8+
// Don't crash or otherwise fail when inlining multiple functions that reference
9+
// @_extern(c) declarations of the same name but different types at the SIL
10+
// level.
11+
12+
import extern_with_nullable
13+
import extern_with_nonnull
14+
15+
public func main() {
16+
callWithNullable()
17+
callWithNonNull()
18+
}

test/SILGen/extern_c.swift

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,48 +2,48 @@
22

33
// REQUIRES: swift_feature_Extern
44

5-
// CHECK-DAG: sil hidden_external @my_c_name : $@convention(c) (Int) -> Int
5+
// CHECK-DAG: sil hidden_external [asmname "my_c_name"] @$s8extern_c9withCNameyS2iFTo : $@convention(c) (Int) -> Int
66
@_extern(c, "my_c_name")
77
func withCName(_ x: Int) -> Int
88

9-
// CHECK-DAG: sil hidden_external @take_c_func_ptr : $@convention(c) (@convention(c) (Int) -> Int) -> ()
9+
// CHECK-DAG: sil hidden_external [asmname "take_c_func_ptr"] @$s8extern_c12takeCFuncPtryyS2iXCF : $@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 @public_visible : $@convention(c) (Int) -> Int
13+
// CHECK-DAG: sil [asmname "public_visible"] @$s8extern_c16publicVisibilityyS2iF : $@convention(c) (Int) -> Int
1414
@_extern(c, "public_visible")
1515
public func publicVisibility(_ x: Int) -> Int
1616

17-
// CHECK-DAG: sil @private_visible : $@convention(c) (Int) -> Int
17+
// 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 @withoutCName : $@convention(c) () -> Int
21+
// CHECK-DAG: sil hidden_external [asmname "withoutCName"] @$s8extern_c12withoutCNameSiyF : $@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 @default_arg : $@convention(c) (Int) -> ()
26+
// CHECK-DAG: sil hidden_external [asmname "default_arg"] @$s8extern_c10defaultArgyySiF : $@convention(c) (Int) -> ()
2727
@_extern(c, "default_arg")
2828
func defaultArg(_ x: Int = 42)
2929

3030
func main() {
31-
// CHECK-DAG: [[F1:%.+]] = function_ref @my_c_name : $@convention(c) (Int) -> Int
32-
// CHECK-DAG: [[F2:%.+]] = function_ref @take_c_func_ptr : $@convention(c) (@convention(c) (Int) -> Int) -> ()
31+
// 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) -> ()
3333
// CHECK-DAG: apply [[F2]]([[F1]]) : $@convention(c) (@convention(c) (Int) -> Int) -> ()
3434
takeCFuncPtr(withCName)
35-
// CHECK-DAG: [[F3:%.+]] = function_ref @public_visible : $@convention(c) (Int) -> Int
35+
// CHECK-DAG: [[F3:%.+]] = function_ref @$s8extern_c16publicVisibilityyS2iF : $@convention(c) (Int) -> Int
3636
// CHECK-DAG: apply [[F3]]({{.*}}) : $@convention(c) (Int) -> Int
3737
_ = publicVisibility(42)
38-
// CHECK-DAG: [[F4:%.+]] = function_ref @private_visible : $@convention(c) (Int) -> Int
38+
// CHECK-DAG: [[F4:%.+]] = function_ref @$s8extern_c17privateVisibility{{.*}} : $@convention(c) (Int) -> Int
3939
// CHECK-DAG: apply [[F4]]({{.*}}) : $@convention(c) (Int) -> Int
4040
_ = privateVisibility(24)
41-
// CHECK-DAG: [[F5:%.+]] = function_ref @withoutCName : $@convention(c) () -> Int
41+
// CHECK-DAG: [[F5:%.+]] = function_ref @$s8extern_c12withoutCNameSiyF : $@convention(c) () -> Int
4242
// CHECK-DAG: apply [[F5]]() : $@convention(c) () -> Int
4343
_ = withoutCName()
4444
// CHECK-DAG: [[F6:%.+]] = function_ref @$s8extern_c10defaultArgyySiFfA_ : $@convention(thin) () -> Int
4545
// CHECK-DAG: [[DEFAULT_V:%.+]] = apply [[F6]]() : $@convention(thin) () -> Int
46-
// CHECK-DAG: [[F7:%.+]] = function_ref @default_arg : $@convention(c) (Int) -> ()
46+
// CHECK-DAG: [[F7:%.+]] = function_ref @$s8extern_c10defaultArgyySiF : $@convention(c) (Int) -> ()
4747
// CHECK-DAG: apply [[F7]]([[DEFAULT_V]]) : $@convention(c) (Int) -> ()
4848
defaultArg()
4949
}

test/SILGen/silgen_name_conflict.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ func my_extern_func1() // expected-note {{function declared here}}
99
func my_extern_func2(x: Int)
1010

1111
@_extern(c, "my_other_extern_func")
12-
func my_other_extern_func1() // expected-note {{function declared here}}
12+
func my_other_extern_func1()
1313

1414
@_extern(c, "my_other_extern_func")
1515
func my_other_extern_func2(x: Int)
@@ -18,6 +18,8 @@ public func foo() {
1818
my_extern_func1()
1919
my_extern_func2(x: 42) // expected-error {{function type mismatch, declared as '@convention(thin) () -> ()' but used as '@convention(thin) (Int) -> ()'}}
2020

21+
// @_extern(c, ...) keeps declarations separate at the SIL level, so we do
22+
// not detect a mismatch here.
2123
my_other_extern_func1()
22-
my_other_extern_func2(x: 42) // expected-error {{function type mismatch, declared as '@convention(c) () -> ()' but used as '@convention(c) (Int) -> ()'}}
24+
my_other_extern_func2(x: 42)
2325
}

test/embedded/wrong-linkage.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44
// REQUIRES: OS=macosx
55

66
@_cdecl("posix_memalign")
7-
func posix_memalign(_ resultPtr:UnsafeMutablePointer<UnsafeMutableRawPointer?>, _ :Int, _ :Int) -> Int32 { // expected-error {{function has wrong linkage to be called from}}
7+
func posix_memalign(_ resultPtr:UnsafeMutablePointer<UnsafeMutableRawPointer?>, _ :Int, _ :Int) -> Int32 { // okay: @_extern(c) declaration is separate
88
return 0
99
}

0 commit comments

Comments
 (0)