Skip to content

Commit f02c155

Browse files
committed
[PrintAsObjC] Add return type related attributes to '_cdecl' global functions
Additionally, Print '(void)' instead '()' for functions that takes no arguments.
1 parent 4f51f75 commit f02c155

File tree

2 files changed

+27
-14
lines changed

2 files changed

+27
-14
lines changed

lib/PrintAsObjC/PrintAsObjC.cpp

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -649,10 +649,8 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
649649
= FD->getForeignErrorConvention();
650650
assert(!FD->getGenericSignature() &&
651651
"top-level generic functions not supported here");
652-
auto resultTy = getForeignResultType(
653-
FD,
654-
FD->getInterfaceType()->castTo<FunctionType>(),
655-
errorConvention);
652+
auto funcTy = FD->getInterfaceType()->castTo<FunctionType>();
653+
auto resultTy = getForeignResultType(FD, funcTy, errorConvention);
656654

657655
// The result type may be a partial function type we need to close
658656
// up later.
@@ -666,18 +664,29 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
666664

667665
assert(FD->getParameterLists().size() == 1 && "not a C-compatible func");
668666
auto params = FD->getParameterLists().back();
669-
interleave(*params,
670-
[&](const ParamDecl *param) {
671-
print(param->getInterfaceType(), OTK_None, param->getName(),
672-
IsFunctionParam);
673-
},
674-
[&]{ os << ", "; });
667+
if (params->size()) {
668+
interleave(*params,
669+
[&](const ParamDecl *param) {
670+
print(param->getInterfaceType(), OTK_None, param->getName(),
671+
IsFunctionParam);
672+
},
673+
[&]{ os << ", "; });
674+
} else {
675+
os << "void";
676+
}
675677

676678
os << ')';
677679

678680
// Finish the result type.
679681
multiPart.finish();
680682

683+
if (funcTy->getResult()->isUninhabited()) {
684+
os << " SWIFT_NORETURN";
685+
} else if (!funcTy->getResult()->isVoid() &&
686+
!FD->getAttrs().hasAttribute<DiscardableResultAttr>()) {
687+
os << " SWIFT_WARN_UNUSED_RESULT";
688+
}
689+
681690
appendAvailabilityAttribute(FD);
682691

683692
os << ';';

test/PrintAsObjC/cdecl.swift

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@
99
// REQUIRES: objc_interop
1010

1111
// CHECK: /// What a nightmare!
12-
// CHECK-LABEL: double (^ _Nonnull block_nightmare(SWIFT_NOESCAPE float (^ _Nonnull x)(NSInteger)))(char);
12+
// CHECK-LABEL: double (^ _Nonnull block_nightmare(SWIFT_NOESCAPE float (^ _Nonnull x)(NSInteger)))(char) SWIFT_WARN_UNUSED_RESULT;
1313

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

19-
// CHECK-LABEL: double (^ _Nonnull block_recurring_nightmare(float (^ _Nonnull x)(SWIFT_NOESCAPE NSInteger (^ _Nonnull)(double))))(SWIFT_NOESCAPE char (^ _Nonnull)(unsigned char));
19+
// CHECK-LABEL: double (^ _Nonnull block_recurring_nightmare(float (^ _Nonnull x)(SWIFT_NOESCAPE NSInteger (^ _Nonnull)(double))))(SWIFT_NOESCAPE char (^ _Nonnull)(unsigned char)) SWIFT_WARN_UNUSED_RESULT;
2020
@_cdecl("block_recurring_nightmare")
2121
public func block_recurring_nightmare(x: @escaping @convention(block) (@convention(block) (Double) -> Int) -> Float)
2222
-> @convention(block) (_ asdfasdf: @convention(block) (CUnsignedChar) -> CChar) -> Double {
@@ -27,12 +27,12 @@ public func block_recurring_nightmare(x: @escaping @convention(block) (@conventi
2727
@_cdecl("foo_bar")
2828
func foo(x: Int, bar y: Int) {}
2929

30-
// CHECK-LABEL: double (* _Nonnull function_pointer_nightmare(SWIFT_NOESCAPE float (* _Nonnull x)(NSInteger)))(char);
30+
// CHECK-LABEL: double (* _Nonnull function_pointer_nightmare(SWIFT_NOESCAPE float (* _Nonnull x)(NSInteger)))(char) SWIFT_WARN_UNUSED_RESULT;
3131
@_cdecl("function_pointer_nightmare")
3232
func function_pointer_nightmare(x: @convention(c) (Int) -> Float)
3333
-> @convention(c) (CChar) -> Double { return { _ in 0 } }
3434

35-
// CHECK-LABEL: double (* _Nonnull function_pointer_recurring_nightmare(float (* _Nonnull x)(SWIFT_NOESCAPE NSInteger (* _Nonnull)(double))))(SWIFT_NOESCAPE char (* _Nonnull)(unsigned char));
35+
// CHECK-LABEL: double (* _Nonnull function_pointer_recurring_nightmare(float (* _Nonnull x)(SWIFT_NOESCAPE NSInteger (* _Nonnull)(double))))(SWIFT_NOESCAPE char (* _Nonnull)(unsigned char)) SWIFT_WARN_UNUSED_RESULT;
3636
@_cdecl("function_pointer_recurring_nightmare")
3737
public func function_pointer_recurring_nightmare(x: @escaping @convention(c) (@convention(c) (Double) -> Int) -> Float)
3838
-> @convention(c) (@convention(c) (CUnsignedChar) -> CChar) -> Double {
@@ -42,3 +42,7 @@ public func function_pointer_recurring_nightmare(x: @escaping @convention(c) (@c
4242
// CHECK-LABEL: void has_keyword_arg_names(NSInteger auto_, NSInteger union_);
4343
@_cdecl("has_keyword_arg_names")
4444
func keywordArgNames(auto: Int, union: Int) {}
45+
46+
// CHECK-LABEL: void return_never(void) SWIFT_NORETURN;
47+
@_cdecl("return_never")
48+
func returnNever() -> Never { fatalError() }

0 commit comments

Comments
 (0)