// RUN: %empty-directory(%t) // RUN: %target-swift-frontend %s -module-name Functions -clang-header-expose-decls=all-public -typecheck -verify -emit-clang-header-path %t/functions.h // RUN: %FileCheck %s < %t/functions.h // RUN: %check-interop-cxx-header-in-clang(%t/functions.h -Wno-unused-function -DSWIFT_CXX_INTEROP_HIDE_STL_OVERLAY) // RUN: %target-swift-frontend %s -module-name Functions -enable-library-evolution -clang-header-expose-decls=all-public -typecheck -verify -emit-clang-header-path %t/functions-evo.h // RUN: %FileCheck %s < %t/functions-evo.h // RUN: %check-interop-cxx-header-in-clang(%t/functions-evo.h -Wno-unused-function -DSWIFT_CXX_INTEROP_HIDE_STL_OVERLAY) public func genericPrintFunctionTwoArg(_ x: T, _ y: Int) { print("X:", x) print("Y:", y) } public func genericPrintFunction(_ x: T) { print("\(T.self) value=\(x)") } public func genericPrintFunctionMultiGeneric(_ x: Int, _ t1: T1, _ t1p: T1, _ y: Int, _ t2: T2) { print("\(T1.self) value 1=\(t1)") print("\(T1.self) value 2=\(t1p)") print("\(T2.self) value 1=\(t2)") print("other values=\(x),\(y)") } public func genericSwap(_ x: inout T, _ y: inout T) { let t = x x = y y = t } public func genericRet(_ x: T) -> T { return x } public func genericRequirementProtocol(_ x: T) { } public func genericRequirementClass(_ x: T) where T: TestClass { } public class TestClass { let field: Int init() { field = 0 } deinit { print("deinit TestClass") } } public func createTestClass() -> TestClass { return TestClass() } public struct TestLargeStruct { var x1, x2, x3, x4, x5, x6: Int init(_ x: Int) { x1 = x x2 = x+1 x3 = x-1 x4 = x x5 = x+2 x6 = x-2 } public mutating func mut() { x1 = -x1 x6 = x5 } } public func createTestLargeStruct(_ x: Int) -> TestLargeStruct { return TestLargeStruct(x) } @frozen public struct TestSmallStruct { var x1: UInt32 public mutating func mut() { x1 = ~x1 } public func genericMethodPassThrough(_ x: T) -> T { return x } public mutating func genericMethodMutTake(_ x: T) { if let y = x as? UInt32 { x1 += y } else { x1 -= 1 } } } public func createTestSmallStruct(_ x: UInt32) -> TestSmallStruct { return TestSmallStruct(x1: x) } // CHECK: SWIFT_EXTERN void $s9Functions15TestSmallStructV24genericMethodPassThroughyxxlF(SWIFT_INDIRECT_RESULT void * _Nonnull, const void * _Nonnull x, struct swift_interop_passStub_Functions_uint32_t_0_4 _self, void * _Nonnull ) SWIFT_NOEXCEPT SWIFT_CALL; // genericMethodPassThrough(_:) // CHECK-NEXT: SWIFT_EXTERN void $s9Functions15TestSmallStructV20genericMethodMutTakeyyxlF(const void * _Nonnull x, void * _Nonnull , SWIFT_CONTEXT void * _Nonnull _self) SWIFT_NOEXCEPT SWIFT_CALL; // genericMethodMutTake(_:) // CHECK: SWIFT_EXTERN void $s9Functions20genericPrintFunctionyyxlF(const void * _Nonnull x, void * _Nonnull ) SWIFT_NOEXCEPT SWIFT_CALL; // genericPrintFunction(_:) // CHECK-NEXT: SWIFT_EXTERN void $s9Functions32genericPrintFunctionMultiGenericyySi_xxSiq_tr0_lF(ptrdiff_t x, const void * _Nonnull t1, const void * _Nonnull t1p, ptrdiff_t y, const void * _Nonnull t2, void * _Nonnull , void * _Nonnull ) SWIFT_NOEXCEPT SWIFT_CALL; // genericPrintFunctionMultiGeneric(_:_:_:_:_:) // CHECK-NEXT: SWIFT_EXTERN void $s9Functions26genericPrintFunctionTwoArgyyx_SitlF(const void * _Nonnull x, ptrdiff_t y, void * _Nonnull ) SWIFT_NOEXCEPT SWIFT_CALL; // genericPrintFunctionTwoArg(_:_:) // CHECK-NEXT: SWIFT_EXTERN void $s9Functions10genericRetyxxlF(SWIFT_INDIRECT_RESULT void * _Nonnull, const void * _Nonnull x, void * _Nonnull ) SWIFT_NOEXCEPT SWIFT_CALL; // genericRet(_:) // CHECK-NEXT: SWIFT_EXTERN void $s9Functions11genericSwapyyxz_xztlF(void * _Nonnull x, void * _Nonnull y, void * _Nonnull ) SWIFT_NOEXCEPT SWIFT_CALL; // genericSwap(_:_:) // CHECK-NOT: genericRequirement // Skip templates in impl classes. // CHECK: _impl_TestSmallStruct // CHECK: template // CHECK-NEXT: #ifdef __cpp_concepts // CHECK-NEXT: requires swift::isUsableInGenericContext // CHECK-NEXT: #endif // CHECK-NEXT: SWIFT_INLINE_THUNK T_0_0 genericMethodPassThrough(const T_0_0& x) const SWIFT_SYMBOL("s:9Functions15TestSmallStructV24genericMethodPassThroughyxxlF"); // CHECK-NEXT: template // CHECK-NEXT: #ifdef __cpp_concepts // CHECK-NEXT: requires swift::isUsableInGenericContext // CHECK-NEXT: #endif // CHECK-NEXT: SWIFT_INLINE_THUNK void genericMethodMutTake(const T_0_0& x) SWIFT_SYMBOL("s:9Functions15TestSmallStructV20genericMethodMutTakeyyxlF"); // CHECK: template // CHECK-NEXT: returnNewValue // CHECK: template // CHECK-NEXT: #ifdef __cpp_concepts // CHECK-NEXT: requires swift::isUsableInGenericContext // CHECK-NEXT: #endif // CHECK-NEXT: SWIFT_INLINE_THUNK void genericPrintFunction(const T_0_0& x) noexcept SWIFT_SYMBOL("s:9Functions20genericPrintFunctionyyxlF") { // CHECK-NEXT: #ifndef __cpp_concepts // CHECK-NEXT: static_assert(swift::isUsableInGenericContext, "type cannot be used in a Swift generic context"); // CHECK-NEXT: #endif // CHECK-NEXT: _impl::$s9Functions20genericPrintFunctionyyxlF(swift::_impl::getOpaquePointer(x), swift::TypeMetadataTrait::getTypeMetadata()); // CHECK-NEXT: } // CHECK: template // CHECK-NEXT: #ifdef __cpp_concepts // CHECK-NEXT: requires swift::isUsableInGenericContext && swift::isUsableInGenericContext // CHECK-NEXT: #endif // CHECK-NEXT: SWIFT_INLINE_THUNK void genericPrintFunctionMultiGeneric(swift::Int x, const T_0_0& t1, const T_0_0& t1p, swift::Int y, const T_0_1& t2) noexcept SWIFT_SYMBOL("s:9Functions32genericPrintFunctionMultiGenericyySi_xxSiq_tr0_lF") { // CHECK-NEXT: #ifndef __cpp_concepts // CHECK-NEXT: static_assert(swift::isUsableInGenericContext, "type cannot be used in a Swift generic context"); // CHECK-NEXT: static_assert(swift::isUsableInGenericContext, "type cannot be used in a Swift generic context"); // CHECK-NEXT: #endif // CHECK-NEXT: _impl::$s9Functions32genericPrintFunctionMultiGenericyySi_xxSiq_tr0_lF(x, swift::_impl::getOpaquePointer(t1), swift::_impl::getOpaquePointer(t1p), y, swift::_impl::getOpaquePointer(t2), swift::TypeMetadataTrait::getTypeMetadata(), swift::TypeMetadataTrait::getTypeMetadata()); // CHECK-NEXT: } // CHECK: template // CHECK-NEXT: #ifdef __cpp_concepts // CHECK-NEXT: requires swift::isUsableInGenericContext // CHECK-NEXT: #endif // CHECK-NEXT: SWIFT_INLINE_THUNK void genericPrintFunctionTwoArg(const T_0_0& x, swift::Int y) noexcept SWIFT_SYMBOL("s:9Functions26genericPrintFunctionTwoArgyyx_SitlF") { // CHECK-NEXT: #ifndef __cpp_concepts // CHECK-NEXT: static_assert(swift::isUsableInGenericContext, "type cannot be used in a Swift generic context"); // CHECK-NEXT: #endif // CHECK-NEXT: _impl::$s9Functions26genericPrintFunctionTwoArgyyx_SitlF(swift::_impl::getOpaquePointer(x), y, swift::TypeMetadataTrait::getTypeMetadata()); // CHECK-NEXT: } // CHECK: template // CHECK-NEXT: #ifdef __cpp_concepts // CHECK-NEXT: requires swift::isUsableInGenericContext // CHECK-NEXT: #endif // CHECK-NEXT: SWIFT_INLINE_THUNK T_0_0 genericRet(const T_0_0& x) noexcept SWIFT_SYMBOL("s:9Functions10genericRetyxxlF") SWIFT_WARN_UNUSED_RESULT { // CHECK-NEXT: #ifndef __cpp_concepts // CHECK-NEXT: static_assert(swift::isUsableInGenericContext, "type cannot be used in a Swift generic context"); // CHECK-NEXT: #endif // CHECK-NEXT: #pragma clang diagnostic push // CHECK-NEXT: #pragma clang diagnostic ignored "-Wc++17-extensions" // CHECK-NEXT: if constexpr (std::is_base_of<::swift::_impl::RefCountedClass, T_0_0>::value) { // CHECK-NEXT: void *returnValue; // CHECK-NEXT: _impl::$s9Functions10genericRetyxxlF(reinterpret_cast(&returnValue), swift::_impl::getOpaquePointer(x), swift::TypeMetadataTrait::getTypeMetadata()); // CHECK-NEXT: return ::swift::_impl::implClassFor::type::makeRetained(returnValue); // CHECK-NEXT: } else if constexpr (::swift::_impl::isValueType) { // CHECK-NEXT: return ::swift::_impl::implClassFor::type::returnNewValue([&](void * _Nonnull returnValue) SWIFT_INLINE_THUNK_ATTRIBUTES { // CHECK-NEXT: _impl::$s9Functions10genericRetyxxlF(returnValue, swift::_impl::getOpaquePointer(x), swift::TypeMetadataTrait::getTypeMetadata()); // CHECK-NEXT: }); // CHECK-NEXT: } else if constexpr (::swift::_impl::isSwiftBridgedCxxRecord) { // CHECK-NEXT: alignas(alignof(T_0_0)) char storage[sizeof(T_0_0)]; // CHECK-NEXT: auto * _Nonnull storageObjectPtr = reinterpret_cast(storage); // CHECK-NEXT: _impl::$s9Functions10genericRetyxxlF(storage, swift::_impl::getOpaquePointer(x), swift::TypeMetadataTrait::getTypeMetadata()); // CHECK-NEXT: T_0_0 result(static_cast(*storageObjectPtr)); // CHECK-NEXT: storageObjectPtr->~T_0_0(); // CHECK-NEXT: return result; // CHECK-NEXT: } else { // CHECK-NEXT: T_0_0 returnValue; // CHECK-NEXT: _impl::$s9Functions10genericRetyxxlF(reinterpret_cast(&returnValue), swift::_impl::getOpaquePointer(x), swift::TypeMetadataTrait::getTypeMetadata()); // CHECK-NEXT: return returnValue; // CHECK-NEXT: } // CHECK-NEXT: #pragma clang diagnostic pop // CHECK-NEXT: } // CHECK: template // CHECK-NEXT: #ifdef __cpp_concepts // CHECK-NEXT: requires swift::isUsableInGenericContext // CHECK-NEXT: #endif // CHECK-NEXT: SWIFT_INLINE_THUNK void genericSwap(T_0_0& x, T_0_0& y) noexcept SWIFT_SYMBOL("s:9Functions11genericSwapyyxz_xztlF") { // CHECK-NEXT: #ifndef __cpp_concepts // CHECK-NEXT: static_assert(swift::isUsableInGenericContext, "type cannot be used in a Swift generic context"); // CHECK-NEXT: #endif // CHECK-NEXT: _impl::$s9Functions11genericSwapyyxz_xztlF(swift::_impl::getOpaquePointer(x), swift::_impl::getOpaquePointer(y), swift::TypeMetadataTrait::getTypeMetadata()); // CHECK-NEXT: } // CHECK: template // CHECK-NEXT: #ifdef __cpp_concepts // CHECK-NEXT: requires swift::isUsableInGenericContext // CHECK-NEXT: #endif // CHECK-NEXT: SWIFT_INLINE_THUNK T_0_0 TestSmallStruct::genericMethodPassThrough(const T_0_0& x) const { // CHECK-NEXT: #ifndef __cpp_concepts // CHECK-NEXT: static_assert(swift::isUsableInGenericContext, "type cannot be used in a Swift generic context"); // CHECK-NEXT: #endif // CHECK-NEXT: #pragma clang diagnostic push // CHECK-NEXT: #pragma clang diagnostic ignored "-Wc++17-extensions" // CHECK-NEXT: if constexpr (std::is_base_of<::swift::_impl::RefCountedClass, T_0_0>::value) { // CHECK-NEXT: void *returnValue; // CHECK-NEXT: _impl::$s9Functions15TestSmallStructV24genericMethodPassThroughyxxlF(reinterpret_cast(&returnValue), swift::_impl::getOpaquePointer(x), Functions::_impl::swift_interop_passDirect_Functions_uint32_t_0_4(_getOpaquePointer()), swift::TypeMetadataTrait::getTypeMetadata()); // CHECK-NEXT: return ::swift::_impl::implClassFor::type::makeRetained(returnValue); // CHECK-NEXT: } else if constexpr (::swift::_impl::isValueType) { // CHECK-NEXT: return ::swift::_impl::implClassFor::type::returnNewValue([&](void * _Nonnull returnValue) SWIFT_INLINE_THUNK_ATTRIBUTES { // CHECK-NEXT: _impl::$s9Functions15TestSmallStructV24genericMethodPassThroughyxxlF(returnValue, swift::_impl::getOpaquePointer(x), Functions::_impl::swift_interop_passDirect_Functions_uint32_t_0_4(_getOpaquePointer()), swift::TypeMetadataTrait::getTypeMetadata()); // CHECK-NEXT: }); // CHECK-NEXT: } else if constexpr (::swift::_impl::isSwiftBridgedCxxRecord) { // CHECK-NEXT: alignas(alignof(T_0_0)) char storage[sizeof(T_0_0)]; // CHECK-NEXT: auto * _Nonnull storageObjectPtr = reinterpret_cast(storage); // CHECK-NEXT: _impl::$s9Functions15TestSmallStructV24genericMethodPassThroughyxxlF(storage, swift::_impl::getOpaquePointer(x), Functions::_impl::swift_interop_passDirect_Functions_uint32_t_0_4(_getOpaquePointer()), swift::TypeMetadataTrait::getTypeMetadata()) // CHECK-NEXT: T_0_0 result(static_cast(*storageObjectPtr)); // CHECK-NEXT: storageObjectPtr->~T_0_0(); // CHECK-NEXT: return result; // CHECK-NEXT: } else { // CHECK-NEXT: T_0_0 returnValue; // CHECK-NEXT: _impl::$s9Functions15TestSmallStructV24genericMethodPassThroughyxxlF(reinterpret_cast(&returnValue), swift::_impl::getOpaquePointer(x), Functions::_impl::swift_interop_passDirect_Functions_uint32_t_0_4(_getOpaquePointer()), swift::TypeMetadataTrait::getTypeMetadata()); // CHECK-NEXT: return returnValue; // CHECK-NEXT: } // CHECK-NEXT: #pragma clang diagnostic pop // CHECK-NEXT: } // CHECK-NEXT: template // CHECK-NEXT: #ifdef __cpp_concepts // CHECK-NEXT: requires swift::isUsableInGenericContext // CHECK-NEXT: #endif // CHECK-NEXT: SWIFT_INLINE_THUNK void TestSmallStruct::genericMethodMutTake(const T_0_0& x) { // CHECK-NEXT: #ifndef __cpp_concepts // CHECK-NEXT: static_assert(swift::isUsableInGenericContext, "type cannot be used in a Swift generic context"); // CHECK-NEXT: #endif // CHECK-NEXT: _impl::$s9Functions15TestSmallStructV20genericMethodMutTakeyyxlF(swift::_impl::getOpaquePointer(x), swift::TypeMetadataTrait::getTypeMetadata(), _getOpaquePointer()); // CHECK-NEXT: }