Skip to content

Commit 7a75f5d

Browse files
[c-interop] Use Swift base name for @_extern(c) without explicit name
1 parent 8f6491e commit 7a75f5d

File tree

5 files changed

+36
-9
lines changed

5 files changed

+36
-9
lines changed

docs/ReferenceGuides/UnderscoredAttributes.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,9 @@ It's the equivalent of clang's `__attribute__((import_module("module"), import_n
453453

454454
Indicates that a particular declaration should refer to a
455455
C declaration with the given name. If the optional "cName"
456-
string is not specified, the mangled Swift name will be used.
456+
string is not specified, the Swift function name is used
457+
without Swift name mangling. Platform-specific mangling
458+
rules (leading underscore on Darwin) are still applied.
457459

458460
Similar to `@_cdecl`, but this attribute is used to reference
459461
C declarations from Swift, while `@_cdecl` is used to define

lib/SIL/IR/SILDeclRef.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1151,6 +1151,10 @@ std::string SILDeclRef::mangle(ManglingKind MKind) const {
11511151
if (auto *ExternA = ExternAttr::find(getDecl()->getAttrs(), ExternKind::C)) {
11521152
if (auto cName = ExternA->Name)
11531153
return cName->str();
1154+
// If no name was specified, fall back on the Swift base name without mangling.
1155+
assert(isa<FuncDecl>(getDecl()) && "non-FuncDecl with @_extern should be rejected by typechecker");
1156+
// Base name is always available and non-empty for FuncDecl.
1157+
return getDecl()->getBaseIdentifier().str().str();
11541158
}
11551159

11561160
// Use a given cdecl name for native-to-foreign thunks.

test/IRGen/extern_c.swift

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,37 @@
1-
// RUN: %target-swift-frontend -emit-ir %s | %FileCheck %s
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
// RUN: %target-swift-frontend -emit-ir %t/extern_c.swift -I%t | %FileCheck %s
4+
5+
//--- c_types.h
6+
struct c_struct {
7+
int field;
8+
};
9+
10+
//--- module.modulemap
11+
module c_types {
12+
header "c_types.h"
13+
}
14+
15+
//--- extern_c.swift
16+
import c_types
217

318
func test() {
419
// CHECK: call void @explicit_extern_c()
520
explicit_extern_c()
6-
// CHECK: call void @"$s8extern_c09implicit_A2_cyyF"()
21+
// CHECK: call void @implicit_extern_c()
722
implicit_extern_c()
23+
24+
// CHECK: call i32 @"+"({{.*}})
25+
_ = c_struct(field: 1) + c_struct(field: 2)
826
}
927

1028
test()
1129

1230
// CHECK: declare void @explicit_extern_c()
1331
@_extern(c, "explicit_extern_c") func explicit_extern_c()
1432

15-
// CHECK: declare void @"$s8extern_c09implicit_A2_cyyF"()
33+
// CHECK: declare void @implicit_extern_c()
1634
@_extern(c) func implicit_extern_c()
35+
36+
// CHECK: declare i32 @"+"({{.*}})
37+
@_extern(c) func +(a: c_struct, b: c_struct) -> c_struct

test/Interop/WebAssembly/extern-wasm-cdecls.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
// RUN: %empty-directory(%t)
22
// RUN: %target-swift-frontend %s -emit-ir -module-name Extern | %FileCheck %s
33

4-
// CHECK: declare void @"$s6Extern7import1yyF"() [[EA1:#[0-9]+]]
4+
// CHECK: declare void @import1() [[EA1:#[0-9]+]]
55
@_extern(c)
66
@_extern(wasm, module: "m0", name: "import1")
77
func import1()
88

9-
// CHECK: declare i32 @"$s6Extern20import2WithReturnInts5Int32VyF"() [[EA2:#[0-9]+]]
9+
// CHECK: declare i32 @import2WithReturnInt() [[EA2:#[0-9]+]]
1010
@_extern(c)
1111
@_extern(wasm, module: "m0", name: "import2")
1212
func import2WithReturnInt() -> Int32
1313

14-
// CHECK: declare void @"$s6Extern16import3TakingIntyys5Int32VF"(i32) [[EA3:#[0-9]+]]
14+
// CHECK: declare void @import3TakingInt(i32) [[EA3:#[0-9]+]]
1515
@_extern(c)
1616
@_extern(wasm, module: "m0", name: "import3")
1717
func import3TakingInt(_: Int32)

test/SILGen/extern_c.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public func publicVisibility(_ x: Int) -> Int
1616
@_extern(c, "private_visible")
1717
private func privateVisiblity(_ x: Int) -> Int
1818

19-
// CHECK-DAG: sil hidden_external @$s8extern_c12withoutCNameSiyF : $@convention(c) () -> Int
19+
// CHECK-DAG: sil hidden_external @withoutCName : $@convention(c) () -> Int
2020
@_extern(c)
2121
func withoutCName() -> Int
2222

@@ -36,7 +36,7 @@ func main() {
3636
// CHECK-DAG: [[F4:%.+]] = function_ref @private_visible : $@convention(c) (Int) -> Int
3737
// CHECK-DAG: apply [[F4]]({{.*}}) : $@convention(c) (Int) -> Int
3838
_ = privateVisiblity(24)
39-
// CHECK-DAG: [[F5:%.+]] = function_ref @$s8extern_c12withoutCNameSiyF : $@convention(c) () -> Int
39+
// CHECK-DAG: [[F5:%.+]] = function_ref @withoutCName : $@convention(c) () -> Int
4040
// CHECK-DAG: apply [[F5]]() : $@convention(c) () -> Int
4141
_ = withoutCName()
4242
// CHECK-DAG: [[F6:%.+]] = function_ref @$s8extern_c10defaultArgyySiFfA_ : $@convention(thin) () -> Int

0 commit comments

Comments
 (0)