From e0139bcc0ca8825c1b932e40306ee46daf041ad3 Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Thu, 13 Nov 2025 11:34:01 -0800 Subject: [PATCH 1/2] Retain the Swift calling convention when it's on an imported C declaration Fixes #69264. --- lib/SIL/IR/SILFunctionType.cpp | 27 +++++++++++++++++++++----- test/IRGen/c_calling_conventions.swift | 26 +++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 5 deletions(-) create mode 100644 test/IRGen/c_calling_conventions.swift diff --git a/lib/SIL/IR/SILFunctionType.cpp b/lib/SIL/IR/SILFunctionType.cpp index 7bf39297ee23e..6c8ed0bbeb0c6 100644 --- a/lib/SIL/IR/SILFunctionType.cpp +++ b/lib/SIL/IR/SILFunctionType.cpp @@ -4424,12 +4424,29 @@ TypeConverter::getDeclRefRepresentation(SILDeclRef c) { if (!c.hasDecl()) return SILFunctionTypeRepresentation::CFunctionPointer; - if (auto method = - dyn_cast_or_null(c.getDecl()->getClangDecl())) - return isa(method) || method->isStatic() - ? SILFunctionTypeRepresentation::CFunctionPointer - : SILFunctionTypeRepresentation::CXXMethod; + if (auto clangDecl = c.getDecl()->getClangDecl()) { + if (auto method = dyn_cast(clangDecl)) { + return isa(method) || method->isStatic() + ? SILFunctionTypeRepresentation::CFunctionPointer + : SILFunctionTypeRepresentation::CXXMethod; + } + + if (auto function = dyn_cast(clangDecl)) { + if (auto fnType = function->getType()->getAs()) { + 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()) diff --git a/test/IRGen/c_calling_conventions.swift b/test/IRGen/c_calling_conventions.swift new file mode 100644 index 0000000000000..805cd148ee4cd --- /dev/null +++ b/test/IRGen/c_calling_conventions.swift @@ -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() From 7517425398968924320f026d938eb3d3c1fd2697 Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Thu, 13 Nov 2025 16:35:02 -0800 Subject: [PATCH 2/2] Update test for Windows --- test/IRGen/c_calling_conventions.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/IRGen/c_calling_conventions.swift b/test/IRGen/c_calling_conventions.swift index 805cd148ee4cd..f33580e86f623 100644 --- a/test/IRGen/c_calling_conventions.swift +++ b/test/IRGen/c_calling_conventions.swift @@ -21,6 +21,6 @@ func test() { // CHECK: call swiftcc void @with_swiftcc() with_swiftcc() } -// CHECK: declare swiftcc void @with_swiftcc() +// CHECK: declare {{.*}}swiftcc void @with_swiftcc() test()