Merge pull request #85498 from DougGregor/retain-calling-convention-from-c

Retain the Swift calling convention when it's on an imported C declaration
This commit is contained in:
Doug Gregor
2025-11-13 21:40:03 -08:00
committed by GitHub
2 changed files with 48 additions and 5 deletions

View File

@@ -4424,12 +4424,29 @@ TypeConverter::getDeclRefRepresentation(SILDeclRef c) {
if (!c.hasDecl())
return SILFunctionTypeRepresentation::CFunctionPointer;
if (auto method =
dyn_cast_or_null<clang::CXXMethodDecl>(c.getDecl()->getClangDecl()))
return isa<clang::CXXConstructorDecl>(method) || method->isStatic()
? SILFunctionTypeRepresentation::CFunctionPointer
: SILFunctionTypeRepresentation::CXXMethod;
if (auto clangDecl = c.getDecl()->getClangDecl()) {
if (auto method = dyn_cast<clang::CXXMethodDecl>(clangDecl)) {
return isa<clang::CXXConstructorDecl>(method) || method->isStatic()
? SILFunctionTypeRepresentation::CFunctionPointer
: SILFunctionTypeRepresentation::CXXMethod;
}
if (auto function = dyn_cast<clang::FunctionDecl>(clangDecl)) {
if (auto fnType = function->getType()->getAs<clang::FunctionType>()) {
switch (fnType->getCallConv()) {
case clang::CC_Swift:
return SILFunctionTypeRepresentation::Thin;
case clang::CC_C:
return SILFunctionTypeRepresentation::CFunctionPointer;
default:
// Fall back to heuristics below.
break;
}
}
}
}
// For example, if we have a function in a namespace:
if (c.getDecl()->isImportAsMember())

View File

@@ -0,0 +1,26 @@
// RUN: %empty-directory(%t)
// RUN: split-file %s %t
// RUN: %target-swift-frontend -I%t %t/caller.swift -emit-ir | %FileCheck %s
//--- c_funcs.h
__attribute__((swiftcall))
extern void with_swiftcc(void);
//--- module.modulemap
module c_funcs {
header "c_funcs.h"
}
//--- caller.swift
import c_funcs
func test() {
// CHECK: call swiftcc void @with_swiftcc()
with_swiftcc()
}
// CHECK: declare {{.*}}swiftcc void @with_swiftcc()
test()