Skip to content

Commit a1ce6e6

Browse files
authored
Merge pull request #85498 from DougGregor/retain-calling-convention-from-c
Retain the Swift calling convention when it's on an imported C declaration
2 parents 827c30f + 7517425 commit a1ce6e6

File tree

2 files changed

+48
-5
lines changed

2 files changed

+48
-5
lines changed

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4424,12 +4424,29 @@ TypeConverter::getDeclRefRepresentation(SILDeclRef c) {
44244424
if (!c.hasDecl())
44254425
return SILFunctionTypeRepresentation::CFunctionPointer;
44264426

4427-
if (auto method =
4428-
dyn_cast_or_null<clang::CXXMethodDecl>(c.getDecl()->getClangDecl()))
4429-
return isa<clang::CXXConstructorDecl>(method) || method->isStatic()
4430-
? SILFunctionTypeRepresentation::CFunctionPointer
4431-
: SILFunctionTypeRepresentation::CXXMethod;
4427+
if (auto clangDecl = c.getDecl()->getClangDecl()) {
4428+
if (auto method = dyn_cast<clang::CXXMethodDecl>(clangDecl)) {
4429+
return isa<clang::CXXConstructorDecl>(method) || method->isStatic()
4430+
? SILFunctionTypeRepresentation::CFunctionPointer
4431+
: SILFunctionTypeRepresentation::CXXMethod;
4432+
}
4433+
4434+
if (auto function = dyn_cast<clang::FunctionDecl>(clangDecl)) {
4435+
if (auto fnType = function->getType()->getAs<clang::FunctionType>()) {
4436+
switch (fnType->getCallConv()) {
4437+
case clang::CC_Swift:
4438+
return SILFunctionTypeRepresentation::Thin;
44324439

4440+
case clang::CC_C:
4441+
return SILFunctionTypeRepresentation::CFunctionPointer;
4442+
4443+
default:
4444+
// Fall back to heuristics below.
4445+
break;
4446+
}
4447+
}
4448+
}
4449+
}
44334450

44344451
// For example, if we have a function in a namespace:
44354452
if (c.getDecl()->isImportAsMember())
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
// RUN: %target-swift-frontend -I%t %t/caller.swift -emit-ir | %FileCheck %s
4+
5+
//--- c_funcs.h
6+
7+
__attribute__((swiftcall))
8+
extern void with_swiftcc(void);
9+
10+
//--- module.modulemap
11+
12+
module c_funcs {
13+
header "c_funcs.h"
14+
}
15+
16+
//--- caller.swift
17+
18+
import c_funcs
19+
20+
func test() {
21+
// CHECK: call swiftcc void @with_swiftcc()
22+
with_swiftcc()
23+
}
24+
// CHECK: declare {{.*}}swiftcc void @with_swiftcc()
25+
26+
test()

0 commit comments

Comments
 (0)