#ifndef TEST_INTEROP_CXX_TEMPLATES_INPUTS_FUNCTION_TEMPLATES_H #define TEST_INTEROP_CXX_TEMPLATES_INPUTS_FUNCTION_TEMPLATES_H template T addSameTypeParams(T a, T b) { return a + b; } template A addMixedTypeParams(A a, B b) { return a + b; } template T passThrough(T value) { return value; } template const T passThroughConst(const T value) { return value; } void takesString(const char *) {} template void expectsConstCharPtr(T str) { takesString(str); } template void hasNonTypeTemplateParameter() {} template void hasDefaultedNonTypeTemplateParameter() {} // NOTE: these will cause multi-def linker errors if used in more than one compilation unit int *intPtr; int get42(void) { return 42; } int (*functionPtrGet42)(void) = &get42; int (*_Nonnull nonNullFunctionPtrGet42)(void) = &get42; int tripleInt(int x) { return x * 3; } int (*functionPtrTripleInt)(int) = &tripleInt; int (*_Nonnull nonNullFunctionPtrTripleInt)(int) = &tripleInt; int (^blockReturns111)(void) = ^{ return 111; }; int (^_Nonnull nonNullBlockReturns222)(void) = ^{ return 222; }; int (^blockTripleInt)(int) = ^(int x) { return x * 3; }; int (^_Nonnull nonNullBlockTripleInt)(int) = ^(int x) { return x * 3; }; // These functions construct block literals that capture a local variable, and // then feed those blocks back to Swift via the given Swift closure (cb). void getConstantIntBlock(int returnValue, void (^_Nonnull cb)(int (^_Nonnull)(void))) { cb(^{ return returnValue; }); } int getMultiplyIntBlock(int multiplier, int (^_Nonnull cb)(int (^_Nonnull)(int))) { return cb(^(int x) { return x * multiplier; }); } // We cannot yet use this in Swift but, make sure we don't crash when parsing // it. template R templateParameterReturnType(T a, U b) { return a + b; } // Same here: template void cannotInferTemplate() {} struct HasVariadicMember { void test1(...) {} void test2(int, ...) {} }; // TODO: We should support these types. Until then, make sure we don't crash when importing. template void testPackExpansion(Ts...) { } template void testTypeOfExpr(T a, typeof(a + 1) b) { } template void testTypeOf(T a, typeof a b) { } template decltype(auto) testAuto(T arg) { return arg; } template struct ClassTemplate { T t; }; struct PlainStruct { int x; }; struct CxxClass { int x; void method() {} int getX() const { return x; } }; struct __attribute__((swift_attr("import_reference"))) __attribute__((swift_attr("retain:immortal"))) __attribute__((swift_attr("release:immortal"))) FRT { int x; }; template void takesPointerToDependent(ClassTemplate *ct) { ct->t++; } template T usedInDeclType(T) {} template void takesDeclTypePointer(decltype(usedInDeclType()) *) {} // TODO: Add tests for Decltype, UnaryTransform, and TemplateSpecialization with // a dependent type once those are supported. // TODO: Add test for DeducedTemplateSpecializationType once we support class templates. // TODO: We don't yet support dependent types but we still shouldn't // crash when importing one (https://github.com/apple/swift/issues/56206). template struct Dep { using TT = T; }; template void useDependentType(typename Dep::TT) {} template void takesValue(T value) { } template void lvalueReference(T &ref) { ref = 42; } template void lvalueReferenceZero(T &ref) { ref = 0; } template void constLvalueReference(const T &) {} template bool constLvalueReferenceToBool(const T &t) { return t; } template void forwardingReference(T &&) {} template void PointerTemplateParameter(T*){} template void callFunction(F f) { f(); } template void callFunctionWithParam(F f, T t) { f(t); } template T callFunctionWithReturn(F f) { return f(); } template T callFunctionWithPassthrough(F f, T t) { return f(t); } static inline void callBlock(void (^_Nonnull callback)(void)) { callback(); } template void indirectlyCallFunction(F f) { callBlock(f); } template void indirectlyCallFunctionTemplate(F f) { callFunction(f); } static inline void callBlockWith42(void (^_Nonnull callback)(int)) { callback(42); } template void indirectlyCallFunctionWith42(F f) { callBlockWith42(f); } static inline void callBlockWithCxxClass24(void (^_Nonnull cb)(CxxClass)) { CxxClass c = {24}; cb(c); } template void indirectlyCallFunctionWithCxxClass24(F f) { callBlockWithCxxClass24(f); } namespace Orbiters { template void galileo(T) { } template void cassini(T, U) { } template void magellan(T&) { } } // namespace Orbiters // We can't import these (and may never be able to in the case of "_Atomic"), // but don't crash while trying. namespace Unimportable { template struct Dependent {}; template void takesDependent(Dependent d) {} void takesAtomic(_Atomic(int) a) {} struct HasImpossibleMember { void memberTakesAtomic(_Atomic(int) a) {} }; } // namespace Unimportable #endif // TEST_INTEROP_CXX_TEMPLATES_INPUTS_FUNCTION_TEMPLATES_H