mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[cxx-interop] noexcept specifier before function attributes (#74780)
In #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++.
This commit is contained in:
committed by
GitHub
parent
b1fc313f22
commit
00e866ae53
@@ -1440,8 +1440,8 @@ private:
|
||||
assert(FD->getAttrs().hasAttribute<CDeclAttr>() && "not a cdecl function");
|
||||
os << "SWIFT_EXTERN ";
|
||||
printFunctionDeclAsCFunctionDecl(FD, FD->getCDeclName(), resultTy);
|
||||
printFunctionClangAttributes(FD, funcTy);
|
||||
os << " SWIFT_NOEXCEPT";
|
||||
printFunctionClangAttributes(FD, funcTy);
|
||||
printAvailability(FD);
|
||||
os << ";\n";
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef _LIBCPP_CSTDDEF
|
||||
#define _LIBCPP_CSTDDEF
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#endif
|
||||
@@ -242,7 +242,10 @@ typedef OpaqueTypedefForFP2 (*FunctionPointerReturningOpaqueTypedef2)(void);
|
||||
size_t returns_size_t();
|
||||
|
||||
// This will probably never be serializable.
|
||||
#if !defined(__cplusplus)
|
||||
// C++ error: unnamed struct cannot be defined in the result type of a function
|
||||
typedef struct { int x; int y; } *(*UnserializableFunctionPointer)(void);
|
||||
#endif
|
||||
|
||||
//===---
|
||||
// Unions
|
||||
@@ -308,7 +311,10 @@ typedef struct ModRM {
|
||||
// Arrays
|
||||
//===---
|
||||
void useArray(char x[4], char y[], char z[][8]);
|
||||
#if !defined(__cplusplus)
|
||||
// error: static array size is a C99 feature, not permitted in C++
|
||||
void staticBoundsArray(const char x[static 4]);
|
||||
#endif
|
||||
|
||||
void useBigArray(char max_size[4096], char max_size_plus_one[4097]);
|
||||
void useBigArray2d(char max_size[][4096], char max_size_plus_one[][4097]);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck %s -parse-as-library -emit-objc-header-path %t/swift.h
|
||||
// RUN: %FileCheck %s < %t/swift.h
|
||||
// RUN: %check-in-clang %t/swift.h
|
||||
// RUN: %check-in-clang-cxx %t/swift.h
|
||||
|
||||
// REQUIRES: objc_interop
|
||||
|
||||
@@ -12,7 +13,7 @@ import Foundation
|
||||
// CHECK-NOT: @import Foundation;
|
||||
|
||||
// CHECK: @class Bee;
|
||||
// CHECK-LABEL: Bee * _Nonnull fwd_declares_bee(void) SWIFT_WARN_UNUSED_RESULT SWIFT_NOEXCEPT;
|
||||
// CHECK-LABEL: Bee * _Nonnull fwd_declares_bee(void) SWIFT_NOEXCEPT SWIFT_WARN_UNUSED_RESULT;
|
||||
|
||||
@_cdecl("fwd_declares_bee")
|
||||
public func fwdDeclaresBee() -> Bee { fatalError() }
|
||||
|
||||
@@ -4,18 +4,19 @@
|
||||
// RUN: %FileCheck %s < %t/cdecl.h
|
||||
// RUN: %check-in-clang %t/cdecl.h
|
||||
// RUN: %check-in-clang -fno-modules -Qunused-arguments %t/cdecl.h -include ctypes.h -include CoreFoundation.h
|
||||
// RUN: %check-in-clang-cxx -fno-modules -Qunused-arguments %t/cdecl.h -include ctypes.h -include CoreFoundation.h
|
||||
|
||||
// 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 SWIFT_NOEXCEPT;
|
||||
// CHECK-LABEL: SWIFT_EXTERN double (^ _Nonnull block_nightmare(SWIFT_NOESCAPE float (^ _Nonnull x)(NSInteger)))(char) SWIFT_NOEXCEPT SWIFT_WARN_UNUSED_RESULT;
|
||||
|
||||
/// 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 SWIFT_NOEXCEPT;
|
||||
// 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;
|
||||
@_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 {
|
||||
@@ -26,12 +27,12 @@ public func block_recurring_nightmare(x: @escaping @convention(block) (@conventi
|
||||
@_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 SWIFT_NOEXCEPT;
|
||||
// CHECK-LABEL: SWIFT_EXTERN double (* _Nonnull function_pointer_nightmare(float (* _Nonnull x)(NSInteger)))(char) SWIFT_NOEXCEPT SWIFT_WARN_UNUSED_RESULT;
|
||||
@_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 SWIFT_NOEXCEPT;
|
||||
// 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;
|
||||
@_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 {
|
||||
@@ -45,11 +46,11 @@ func keywordArgNames(auto: Int, union: Int) {}
|
||||
@objc
|
||||
class C {}
|
||||
|
||||
// CHECK-LABEL: SWIFT_EXTERN C * _Null_unspecified return_iuo(void) SWIFT_WARN_UNUSED_RESULT SWIFT_NOEXCEPT;
|
||||
// CHECK-LABEL: SWIFT_EXTERN C * _Null_unspecified return_iuo(void) SWIFT_NOEXCEPT SWIFT_WARN_UNUSED_RESULT;
|
||||
@_cdecl("return_iuo")
|
||||
func returnIUO() -> C! { return C() }
|
||||
|
||||
// CHECK-LABEL: SWIFT_EXTERN void return_never(void) SWIFT_NORETURN SWIFT_NOEXCEPT;
|
||||
// CHECK-LABEL: SWIFT_EXTERN void return_never(void) SWIFT_NOEXCEPT SWIFT_NORETURN;
|
||||
@_cdecl("return_never")
|
||||
func returnNever() -> Never { fatalError() }
|
||||
|
||||
|
||||
@@ -9,3 +9,12 @@ config.substitutions.insert(0, ('%check-in-clang',
|
||||
'-F %%clang-importer-sdk-path/frameworks '
|
||||
'-I %%clang-include-dir '
|
||||
'-isysroot %r/Inputs/clang-importer-sdk' % config.test_source_root) )
|
||||
|
||||
config.substitutions.insert(0, ('%check-in-clang-cxx',
|
||||
'%%clang -fsyntax-only -x objective-c++-header -std=c++17 '
|
||||
'-fobjc-arc -fmodules -fmodules-validate-system-headers '
|
||||
'-Weverything -Werror -Wno-unused-macros -Wno-incomplete-module '
|
||||
'-Wno-auto-import -Wno-c++98-compat-pedantic '
|
||||
'-F %%clang-importer-sdk-path/frameworks '
|
||||
'-I %%clang-include-dir '
|
||||
'-isysroot %r/Inputs/clang-importer-sdk' % config.test_source_root) )
|
||||
|
||||
Reference in New Issue
Block a user