Skip to content

Commit 00e866a

Browse files
authored
[cxx-interop] noexcept specifier before function attributes (swiftlang#74780)
In swiftlang#74516 the `SWIFT_NOEXCEPT` specifier is added to the imported Swift functions in C++ mode, but it is added after the function attributes. It seems that the tests only do `-fsyntax-only`, which seems not to catch an error like "expected function body after function declarator" when the header is used without that flag. Flip the attributes and the specifier around in the printer, and flip them in all the tests. The tests were using `%check-in-clang`, but it only checks importing as an objective-c-header. Add a parallel `%check-in-clang-cxx` to test also in C++. It uses C++17 because of some details in the imported headers and disables a warning about variadic macros that was promoted to an error and was blocking passing the tests. The clang-importer-sdk gets the minimal set of files to compile the two modified tests as C++. The files are mostly empty, except `cstddef` that imports the equivalent C header. Some modifications were needed in `ctypes.h` because the header was using features only available in C and not C++.
1 parent b1fc313 commit 00e866a

File tree

11 files changed

+31
-8
lines changed

11 files changed

+31
-8
lines changed

lib/PrintAsClang/DeclAndTypePrinter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1440,8 +1440,8 @@ class DeclAndTypePrinter::Implementation
14401440
assert(FD->getAttrs().hasAttribute<CDeclAttr>() && "not a cdecl function");
14411441
os << "SWIFT_EXTERN ";
14421442
printFunctionDeclAsCFunctionDecl(FD, FD->getCDeclName(), resultTy);
1443-
printFunctionClangAttributes(FD, funcTy);
14441443
os << " SWIFT_NOEXCEPT";
1444+
printFunctionClangAttributes(FD, funcTy);
14451445
printAvailability(FD);
14461446
os << ";\n";
14471447
}

test/Inputs/clang-importer-sdk/usr/include/c++/v1/cstdbool

Whitespace-only changes.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#ifndef _LIBCPP_CSTDDEF
2+
#define _LIBCPP_CSTDDEF
3+
4+
#include <stddef.h>
5+
6+
#endif

test/Inputs/clang-importer-sdk/usr/include/c++/v1/cstdint

Whitespace-only changes.

test/Inputs/clang-importer-sdk/usr/include/c++/v1/cstring

Whitespace-only changes.

test/Inputs/clang-importer-sdk/usr/include/c++/v1/new

Whitespace-only changes.

test/Inputs/clang-importer-sdk/usr/include/c++/v1/type_traits

Whitespace-only changes.

test/Inputs/clang-importer-sdk/usr/include/ctypes.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,10 @@ typedef OpaqueTypedefForFP2 (*FunctionPointerReturningOpaqueTypedef2)(void);
242242
size_t returns_size_t();
243243

244244
// This will probably never be serializable.
245+
#if !defined(__cplusplus)
246+
// C++ error: unnamed struct cannot be defined in the result type of a function
245247
typedef struct { int x; int y; } *(*UnserializableFunctionPointer)(void);
248+
#endif
246249

247250
//===---
248251
// Unions
@@ -308,7 +311,10 @@ typedef struct ModRM {
308311
// Arrays
309312
//===---
310313
void useArray(char x[4], char y[], char z[][8]);
314+
#if !defined(__cplusplus)
315+
// error: static array size is a C99 feature, not permitted in C++
311316
void staticBoundsArray(const char x[static 4]);
317+
#endif
312318

313319
void useBigArray(char max_size[4096], char max_size_plus_one[4097]);
314320
void useBigArray2d(char max_size[][4096], char max_size_plus_one[][4097]);

test/PrintAsObjC/cdecl-imports.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck %s -parse-as-library -emit-objc-header-path %t/swift.h
33
// RUN: %FileCheck %s < %t/swift.h
44
// RUN: %check-in-clang %t/swift.h
5+
// RUN: %check-in-clang-cxx %t/swift.h
56

67
// REQUIRES: objc_interop
78

@@ -12,7 +13,7 @@ import Foundation
1213
// CHECK-NOT: @import Foundation;
1314

1415
// CHECK: @class Bee;
15-
// CHECK-LABEL: Bee * _Nonnull fwd_declares_bee(void) SWIFT_WARN_UNUSED_RESULT SWIFT_NOEXCEPT;
16+
// CHECK-LABEL: Bee * _Nonnull fwd_declares_bee(void) SWIFT_NOEXCEPT SWIFT_WARN_UNUSED_RESULT;
1617

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

test/PrintAsObjC/cdecl.swift

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,19 @@
44
// RUN: %FileCheck %s < %t/cdecl.h
55
// RUN: %check-in-clang %t/cdecl.h
66
// RUN: %check-in-clang -fno-modules -Qunused-arguments %t/cdecl.h -include ctypes.h -include CoreFoundation.h
7+
// RUN: %check-in-clang-cxx -fno-modules -Qunused-arguments %t/cdecl.h -include ctypes.h -include CoreFoundation.h
78

89
// REQUIRES: objc_interop
910

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

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

18-
// 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;
19+
// CHECK-LABEL: SWIFT_EXTERN double (^ _Nonnull block_recurring_nightmare(float (^ _Nonnull x)(SWIFT_NOESCAPE NSInteger (^ _Nonnull)(double))))(SWIFT_NOESCAPE char (^ _Nonnull)(unsigned char)) SWIFT_NOEXCEPT SWIFT_WARN_UNUSED_RESULT;
1920
@_cdecl("block_recurring_nightmare")
2021
public func block_recurring_nightmare(x: @escaping @convention(block) (@convention(block) (Double) -> Int) -> Float)
2122
-> @convention(block) (_ asdfasdf: @convention(block) (CUnsignedChar) -> CChar) -> Double {
@@ -26,12 +27,12 @@ public func block_recurring_nightmare(x: @escaping @convention(block) (@conventi
2627
@_cdecl("foo_bar")
2728
func foo(x: Int, bar y: Int) {}
2829

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

34-
// 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;
35+
// CHECK-LABEL: SWIFT_EXTERN double (* _Nonnull function_pointer_recurring_nightmare(float (* _Nonnull x)(NSInteger (* _Nonnull)(double))))(char (* _Nonnull)(unsigned char)) SWIFT_NOEXCEPT SWIFT_WARN_UNUSED_RESULT;
3536
@_cdecl("function_pointer_recurring_nightmare")
3637
public func function_pointer_recurring_nightmare(x: @escaping @convention(c) (@convention(c) (Double) -> Int) -> Float)
3738
-> @convention(c) (@convention(c) (CUnsignedChar) -> CChar) -> Double {
@@ -45,11 +46,11 @@ func keywordArgNames(auto: Int, union: Int) {}
4546
@objc
4647
class C {}
4748

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

52-
// CHECK-LABEL: SWIFT_EXTERN void return_never(void) SWIFT_NORETURN SWIFT_NOEXCEPT;
53+
// CHECK-LABEL: SWIFT_EXTERN void return_never(void) SWIFT_NOEXCEPT SWIFT_NORETURN;
5354
@_cdecl("return_never")
5455
func returnNever() -> Never { fatalError() }
5556

0 commit comments

Comments
 (0)