Skip to content

🍒[cxx-interop] Fix exporting cdecl Swift functions to Obj-C++ #74615

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/PrintAsClang/DeclAndTypePrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1437,6 +1437,7 @@ class DeclAndTypePrinter::Implementation
os << "SWIFT_EXTERN ";
printFunctionDeclAsCFunctionDecl(FD, FD->getCDeclName(), resultTy);
printFunctionClangAttributes(FD, funcTy);
os << " SWIFT_NOEXCEPT";
printAvailability(FD);
os << ";\n";
}
Expand Down
4 changes: 4 additions & 0 deletions test/Interop/SwiftToCxx/functions/swift-functions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import CxxStdlib

// RUN: %check-interop-cxx-header-in-clang(%t/functions.h)

@_cdecl("cdeclFunction") public func cdeclFunction(_ x: CInt) {}

// CHECK: SWIFT_EXTERN void cdeclFunction(int x) SWIFT_NOEXCEPT;

// CHECK-LABEL: namespace Functions SWIFT_PRIVATE_ATTR SWIFT_SYMBOL_MODULE("Functions") {

// CHECK-LABEL: namespace _impl {
Expand Down
6 changes: 3 additions & 3 deletions test/PrintAsObjC/cdecl-imports.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,19 @@ import Foundation
// CHECK-NOT: @import Foundation;

// CHECK: @class Bee;
// CHECK-LABEL: Bee * _Nonnull fwd_declares_bee(void) SWIFT_WARN_UNUSED_RESULT;
// CHECK-LABEL: Bee * _Nonnull fwd_declares_bee(void) SWIFT_WARN_UNUSED_RESULT SWIFT_NOEXCEPT;

@_cdecl("fwd_declares_bee")
public func fwdDeclaresBee() -> Bee { fatalError() }

// CHECK: @class Hive;
// CHECK-LABEL: void fwd_declares_hive(Hive * _Nonnull (* _Nonnull bzzz)(Bee * _Nonnull));
// CHECK-LABEL: void fwd_declares_hive(Hive * _Nonnull (* _Nonnull bzzz)(Bee * _Nonnull)) SWIFT_NOEXCEPT;

@_cdecl("fwd_declares_hive")
public func fwdDeclaresHive(bzzz: @convention(c) (Bee) -> Hive) { fatalError() }

// CHECK: @protocol NSWobbling;
// CHECK-LABEL: void fwd_declares_wobble(id <NSWobbling> _Nonnull wobbler);
// CHECK-LABEL: void fwd_declares_wobble(id <NSWobbling> _Nonnull wobbler) SWIFT_NOEXCEPT;

@_cdecl("fwd_declares_wobble")
public func fwdDeclaresWobble(wobbler: NSWobbling) { fatalError() }
Expand Down
18 changes: 9 additions & 9 deletions test/PrintAsObjC/cdecl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,51 +8,51 @@
// REQUIRES: objc_interop

// CHECK: /// What a nightmare!
// CHECK-LABEL: SWIFT_EXTERN double (^ _Nonnull block_nightmare(SWIFT_NOESCAPE float (^ _Nonnull x)(NSInteger)))(char) SWIFT_WARN_UNUSED_RESULT;
// CHECK-LABEL: SWIFT_EXTERN double (^ _Nonnull block_nightmare(SWIFT_NOESCAPE float (^ _Nonnull x)(NSInteger)))(char) SWIFT_WARN_UNUSED_RESULT SWIFT_NOEXCEPT;

/// What a nightmare!
@_cdecl("block_nightmare")
public func block_nightmare(x: @convention(block) (Int) -> Float)
-> @convention(block) (CChar) -> Double { return { _ in 0 } }

// CHECK-LABEL: SWIFT_EXTERN double (^ _Nonnull block_recurring_nightmare(float (^ _Nonnull x)(SWIFT_NOESCAPE NSInteger (^ _Nonnull)(double))))(SWIFT_NOESCAPE char (^ _Nonnull)(unsigned char)) SWIFT_WARN_UNUSED_RESULT;
// CHECK-LABEL: SWIFT_EXTERN double (^ _Nonnull block_recurring_nightmare(float (^ _Nonnull x)(SWIFT_NOESCAPE NSInteger (^ _Nonnull)(double))))(SWIFT_NOESCAPE char (^ _Nonnull)(unsigned char)) SWIFT_WARN_UNUSED_RESULT SWIFT_NOEXCEPT;
@_cdecl("block_recurring_nightmare")
public func block_recurring_nightmare(x: @escaping @convention(block) (@convention(block) (Double) -> Int) -> Float)
-> @convention(block) (_ asdfasdf: @convention(block) (CUnsignedChar) -> CChar) -> Double {
fatalError()
}

// CHECK-LABEL: SWIFT_EXTERN void foo_bar(NSInteger x, NSInteger y);
// CHECK-LABEL: SWIFT_EXTERN void foo_bar(NSInteger x, NSInteger y) SWIFT_NOEXCEPT;
@_cdecl("foo_bar")
func foo(x: Int, bar y: Int) {}

// CHECK-LABEL: SWIFT_EXTERN double (* _Nonnull function_pointer_nightmare(float (* _Nonnull x)(NSInteger)))(char) SWIFT_WARN_UNUSED_RESULT;
// CHECK-LABEL: SWIFT_EXTERN double (* _Nonnull function_pointer_nightmare(float (* _Nonnull x)(NSInteger)))(char) SWIFT_WARN_UNUSED_RESULT SWIFT_NOEXCEPT;
@_cdecl("function_pointer_nightmare")
func function_pointer_nightmare(x: @convention(c) (Int) -> Float)
-> @convention(c) (CChar) -> Double { return { _ in 0 } }

// CHECK-LABEL: SWIFT_EXTERN double (* _Nonnull function_pointer_recurring_nightmare(float (* _Nonnull x)(NSInteger (* _Nonnull)(double))))(char (* _Nonnull)(unsigned char)) SWIFT_WARN_UNUSED_RESULT;
// CHECK-LABEL: SWIFT_EXTERN double (* _Nonnull function_pointer_recurring_nightmare(float (* _Nonnull x)(NSInteger (* _Nonnull)(double))))(char (* _Nonnull)(unsigned char)) SWIFT_WARN_UNUSED_RESULT SWIFT_NOEXCEPT;
@_cdecl("function_pointer_recurring_nightmare")
public func function_pointer_recurring_nightmare(x: @escaping @convention(c) (@convention(c) (Double) -> Int) -> Float)
-> @convention(c) (@convention(c) (CUnsignedChar) -> CChar) -> Double {
fatalError()
}

// CHECK-LABEL: SWIFT_EXTERN void has_keyword_arg_names(NSInteger auto_, NSInteger union_);
// CHECK-LABEL: SWIFT_EXTERN void has_keyword_arg_names(NSInteger auto_, NSInteger union_) SWIFT_NOEXCEPT;
@_cdecl("has_keyword_arg_names")
func keywordArgNames(auto: Int, union: Int) {}

@objc
class C {}

// CHECK-LABEL: SWIFT_EXTERN C * _Null_unspecified return_iuo(void) SWIFT_WARN_UNUSED_RESULT;
// CHECK-LABEL: SWIFT_EXTERN C * _Null_unspecified return_iuo(void) SWIFT_WARN_UNUSED_RESULT SWIFT_NOEXCEPT;
@_cdecl("return_iuo")
func returnIUO() -> C! { return C() }

// CHECK-LABEL: SWIFT_EXTERN void return_never(void) SWIFT_NORETURN;
// CHECK-LABEL: SWIFT_EXTERN void return_never(void) SWIFT_NORETURN SWIFT_NOEXCEPT;
@_cdecl("return_never")
func returnNever() -> Never { fatalError() }

// CHECK-LABEL: SWIFT_EXTERN void takes_iuo(C * _Null_unspecified c);
// CHECK-LABEL: SWIFT_EXTERN void takes_iuo(C * _Null_unspecified c) SWIFT_NOEXCEPT;
@_cdecl("takes_iuo")
func takesIUO(c: C!) {}