diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -33,7 +33,7 @@ * compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable. */ #define CINDEX_VERSION_MAJOR 0 -#define CINDEX_VERSION_MINOR 61 +#define CINDEX_VERSION_MINOR 62 #define CINDEX_VERSION_ENCODE(major, minor) (((major)*10000) + ((minor)*1)) @@ -3394,6 +3394,7 @@ CXCallingConv_PreserveMost = 14, CXCallingConv_PreserveAll = 15, CXCallingConv_AArch64VectorCall = 16, + CXCallingConv_SwiftAsync = 17, CXCallingConv_Invalid = 100, CXCallingConv_Unexposed = 200 diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -2374,6 +2374,11 @@ let Documentation = [SwiftCallDocs]; } +def SwiftAsyncCall : DeclOrTypeAttr { + let Spellings = [Clang<"swiftasynccall">]; + let Documentation = [SwiftAsyncCallDocs]; +} + def SwiftContext : ParameterABIAttr { let Spellings = [Clang<"swift_context">]; let Documentation = [SwiftContextDocs]; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -4392,14 +4392,38 @@ }]; } +def SwiftAsyncCallDocs : Documentation { + let Category = DocCatVariable; + let Content = [{ +The ``swiftasynccall`` attribute indicates that a function is +compatible with the low-level conventions of Swift async functions, +provided it declares the right formal arguments. + +In most respects, this is similar to the ``swiftcall`` attribute, except for +the following: +- A parameter may be marked ``swift_async_context``, but the parameter + attributes ``swift_context``, ``swift_error_result`` and + ``swift_indirect_result`` are not permitted. +- A ``swiftasynccall`` function must have return type ``void``. +- Within a ``swiftasynccall`` function, a call to a ``swiftasynccall`` + function that is the immediate operand of a ``return`` statement is + guaranteed to be performed as a tail call. This syntax is allowed even + in C as an extension (a call to a void-returning function cannot be a + return operand in standard C). If something in the calling function would + semantically be performed after a guaranteed tail call, such as the + non-trivial destruction of a local variable or temporary, + then the program is ill-formed. + }]; +} + def SwiftAsyncContextDocs : Documentation { let Category = DocCatVariable; let Content = [{ -The ``swift_async_context`` attribute marks a parameter as having the -special asynchronous context-parameter ABI treatment. +The ``swift_async_context`` attribute marks a parameter of a ``swiftasynccall`` +function as having the special asynchronous context-parameter ABI treatment. -This treatment generally passes the context value in a special register -which is normally callee-preserved. +If the function is not ``swiftasynccall``, this attribute only generates +extended frame information. A context parameter must have pointer or reference type. }]; diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def --- a/clang/include/clang/Basic/Features.def +++ b/clang/include/clang/Basic/Features.def @@ -92,6 +92,9 @@ FEATURE(thread_sanitizer, LangOpts.Sanitize.has(SanitizerKind::Thread)) FEATURE(dataflow_sanitizer, LangOpts.Sanitize.has(SanitizerKind::DataFlow)) FEATURE(scudo, LangOpts.Sanitize.hasOneOf(SanitizerKind::Scudo)) +FEATURE(swiftasynccc, + PP.getTargetInfo().checkCallingConvention(CC_SwiftAsync) == + clang::TargetInfo::CCCR_OK) // Objective-C features FEATURE(objc_arr, LangOpts.ObjCAutoRefCount) // FIXME: REMOVE? FEATURE(objc_arc, LangOpts.ObjCAutoRefCount) diff --git a/clang/include/clang/Basic/Specifiers.h b/clang/include/clang/Basic/Specifiers.h --- a/clang/include/clang/Basic/Specifiers.h +++ b/clang/include/clang/Basic/Specifiers.h @@ -266,6 +266,7 @@ CC_SpirFunction, // default for OpenCL functions on SPIR target CC_OpenCLKernel, // inferred for OpenCL kernels CC_Swift, // __attribute__((swiftcall)) + CC_SwiftAsync, // __attribute__((swiftasynccall)) CC_PreserveMost, // __attribute__((preserve_most)) CC_PreserveAll, // __attribute__((preserve_all)) CC_AArch64VectorCall, // __attribute__((aarch64_vector_pcs)) @@ -284,6 +285,7 @@ case CC_SpirFunction: case CC_OpenCLKernel: case CC_Swift: + case CC_SwiftAsync: return false; default: return true; diff --git a/clang/include/clang/CodeGen/SwiftCallingConv.h b/clang/include/clang/CodeGen/SwiftCallingConv.h --- a/clang/include/clang/CodeGen/SwiftCallingConv.h +++ b/clang/include/clang/CodeGen/SwiftCallingConv.h @@ -6,7 +6,8 @@ // //===----------------------------------------------------------------------===// // -// Defines constants and types related to Swift ABI lowering. +// Defines constants and types related to Swift ABI lowering. The same ABI +// lowering applies to both sync and async functions. // //===----------------------------------------------------------------------===// diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -2908,6 +2908,8 @@ return "ms_abi"; case CC_Swift: return "swiftcall"; + case CC_SwiftAsync: + return "swiftasynccall"; } llvm_unreachable("bad calling convention"); } diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -2685,6 +2685,8 @@ // ::= J # __export __fastcall // ::= Q # __vectorcall // ::= S # __attribute__((__swiftcall__)) // Clang-only + // ::= T # __attribute__((__swiftasynccall__)) + // // Clang-only // ::= w # __regcall // The 'export' calling conventions are from a bygone era // (*cough*Win16*cough*) when functions were declared for export with @@ -2704,6 +2706,7 @@ case CC_X86FastCall: Out << 'I'; break; case CC_X86VectorCall: Out << 'Q'; break; case CC_Swift: Out << 'S'; break; + case CC_SwiftAsync: Out << 'T'; break; case CC_PreserveMost: Out << 'U'; break; case CC_X86RegCall: Out << 'w'; break; } diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -3134,6 +3134,7 @@ case CC_SpirFunction: return "spir_function"; case CC_OpenCLKernel: return "opencl_kernel"; case CC_Swift: return "swiftcall"; + case CC_SwiftAsync: return "swiftasynccall"; case CC_PreserveMost: return "preserve_most"; case CC_PreserveAll: return "preserve_all"; } @@ -3550,6 +3551,7 @@ case attr::ThisCall: case attr::RegCall: case attr::SwiftCall: + case attr::SwiftAsyncCall: case attr::VectorCall: case attr::AArch64VectorPcs: case attr::Pascal: diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -976,6 +976,9 @@ case CC_Swift: OS << " __attribute__((swiftcall))"; break; + case CC_SwiftAsync: + OS << "__attribute__((swiftasynccall))"; + break; case CC_PreserveMost: OS << " __attribute__((preserve_most))"; break; @@ -1704,6 +1707,7 @@ case attr::StdCall: OS << "stdcall"; break; case attr::ThisCall: OS << "thiscall"; break; case attr::SwiftCall: OS << "swiftcall"; break; + case attr::SwiftAsyncCall: OS << "swiftasynccall"; break; case attr::VectorCall: OS << "vectorcall"; break; case attr::Pascal: OS << "pascal"; break; case attr::MSABI: OS << "ms_abi"; break; diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -537,6 +537,7 @@ switch (CC) { case CC_C: case CC_Swift: + case CC_SwiftAsync: case CC_PreserveMost: case CC_PreserveAll: case CC_OpenCLKernel: @@ -810,6 +811,7 @@ case CC_PreserveMost: case CC_PreserveAll: case CC_Swift: + case CC_SwiftAsync: case CC_Win64: return CCCR_OK; default: diff --git a/clang/lib/Basic/Targets/ARM.cpp b/clang/lib/Basic/Targets/ARM.cpp --- a/clang/lib/Basic/Targets/ARM.cpp +++ b/clang/lib/Basic/Targets/ARM.cpp @@ -1120,6 +1120,7 @@ case CC_AAPCS: case CC_AAPCS_VFP: case CC_Swift: + case CC_SwiftAsync: case CC_OpenCLKernel: return CCCR_OK; default: @@ -1199,6 +1200,7 @@ case CC_PreserveMost: case CC_PreserveAll: case CC_Swift: + case CC_SwiftAsync: return CCCR_OK; default: return CCCR_Warning; diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -451,6 +451,8 @@ switch (CC) { case CC_Swift: return CCCR_OK; + case CC_SwiftAsync: + return CCCR_Error; default: return CCCR_Warning; } diff --git a/clang/lib/Basic/Targets/SystemZ.h b/clang/lib/Basic/Targets/SystemZ.h --- a/clang/lib/Basic/Targets/SystemZ.h +++ b/clang/lib/Basic/Targets/SystemZ.h @@ -143,6 +143,8 @@ case CC_Swift: case CC_OpenCLKernel: return CCCR_OK; + case CC_SwiftAsync: + return CCCR_Error; default: return CCCR_Warning; } diff --git a/clang/lib/Basic/Targets/WebAssembly.h b/clang/lib/Basic/Targets/WebAssembly.h --- a/clang/lib/Basic/Targets/WebAssembly.h +++ b/clang/lib/Basic/Targets/WebAssembly.h @@ -130,6 +130,8 @@ case CC_C: case CC_Swift: return CCCR_OK; + case CC_SwiftAsync: + return CCCR_Error; default: return CCCR_Warning; } diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h --- a/clang/lib/Basic/Targets/X86.h +++ b/clang/lib/Basic/Targets/X86.h @@ -348,6 +348,8 @@ case CC_IntelOclBicc: case CC_OpenCLKernel: return CCCR_OK; + case CC_SwiftAsync: + return CCCR_Error; default: return CCCR_Warning; } @@ -702,6 +704,7 @@ switch (CC) { case CC_C: case CC_Swift: + case CC_SwiftAsync: case CC_X86VectorCall: case CC_IntelOclBicc: case CC_Win64: @@ -783,6 +786,7 @@ case CC_PreserveAll: case CC_X86_64SysV: case CC_Swift: + case CC_SwiftAsync: case CC_X86RegCall: case CC_OpenCLKernel: return CCCR_OK; diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -66,6 +66,9 @@ case CC_PreserveMost: return llvm::CallingConv::PreserveMost; case CC_PreserveAll: return llvm::CallingConv::PreserveAll; case CC_Swift: return llvm::CallingConv::Swift; + // [FIXME: swiftasynccc] Update to SwiftAsync once LLVM support lands. + case CC_SwiftAsync: + return llvm::CallingConv::Swift; } } @@ -773,7 +776,7 @@ // Force target independent argument handling for the host visible // kernel functions. computeSPIRKernelABIInfo(CGM, *FI); - } else if (info.getCC() == CC_Swift) { + } else if (info.getCC() == CC_Swift || info.getCC() == CC_SwiftAsync) { swiftcall::computeABIInfo(CGM, *FI); } else { getABIInfo().computeInfo(*FI); @@ -3885,11 +3888,11 @@ // later, so we can't check it directly. static bool hasInAllocaArgs(CodeGenModule &CGM, CallingConv ExplicitCC, ArrayRef ArgTypes) { - // The Swift calling convention doesn't go through the target-specific - // argument classification, so it never uses inalloca. + // The Swift calling conventions don't go through the target-specific + // argument classification, they never use inalloca. // TODO: Consider limiting inalloca use to only calling conventions supported // by MSVC. - if (ExplicitCC == CC_Swift) + if (ExplicitCC == CC_Swift || ExplicitCC == CC_SwiftAsync) return false; if (!CGM.getTarget().getCXXABI().isMicrosoft()) return false; diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1248,6 +1248,9 @@ return llvm::dwarf::DW_CC_LLVM_OpenCLKernel; case CC_Swift: return llvm::dwarf::DW_CC_LLVM_Swift; + case CC_SwiftAsync: + // [FIXME: swiftasynccc] Update to SwiftAsync once LLVM support lands. + return llvm::dwarf::DW_CC_LLVM_Swift; case CC_PreserveMost: return llvm::dwarf::DW_CC_LLVM_PreserveMost; case CC_PreserveAll: diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -4645,6 +4645,9 @@ case ParsedAttr::AT_SwiftCall: D->addAttr(::new (S.Context) SwiftCallAttr(S.Context, AL)); return; + case ParsedAttr::AT_SwiftAsyncCall: + D->addAttr(::new (S.Context) SwiftAsyncCallAttr(S.Context, AL)); + return; case ParsedAttr::AT_VectorCall: D->addAttr(::new (S.Context) VectorCallAttr(S.Context, AL)); return; @@ -4806,6 +4809,9 @@ case ParsedAttr::AT_SwiftCall: CC = CC_Swift; break; + case ParsedAttr::AT_SwiftAsyncCall: + CC = CC_SwiftAsync; + break; case ParsedAttr::AT_VectorCall: CC = CC_X86VectorCall; break; @@ -8097,6 +8103,7 @@ case ParsedAttr::AT_Pascal: case ParsedAttr::AT_RegCall: case ParsedAttr::AT_SwiftCall: + case ParsedAttr::AT_SwiftAsyncCall: case ParsedAttr::AT_VectorCall: case ParsedAttr::AT_MSABI: case ParsedAttr::AT_SysVABI: diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -117,6 +117,7 @@ case ParsedAttr::AT_RegCall: \ case ParsedAttr::AT_Pascal: \ case ParsedAttr::AT_SwiftCall: \ + case ParsedAttr::AT_SwiftAsyncCall: \ case ParsedAttr::AT_VectorCall: \ case ParsedAttr::AT_AArch64VectorPcs: \ case ParsedAttr::AT_MSABI: \ @@ -2759,13 +2760,16 @@ assert(EPI.ExtParameterInfos && "shouldn't get here without param infos"); bool hasCheckedSwiftCall = false; + auto reportWrongABI = [&](unsigned paramIndex) { + S.Diag(getParamLoc(paramIndex), diag::err_swift_param_attr_not_swiftcall) + << getParameterABISpelling(EPI.ExtParameterInfos[paramIndex].getABI()); + }; auto checkForSwiftCC = [&](unsigned paramIndex) { // Only do this once. if (hasCheckedSwiftCall) return; hasCheckedSwiftCall = true; if (EPI.ExtInfo.getCC() == CC_Swift) return; - S.Diag(getParamLoc(paramIndex), diag::err_swift_param_attr_not_swiftcall) - << getParameterABISpelling(EPI.ExtParameterInfos[paramIndex].getABI()); + reportWrongABI(paramIndex); }; for (size_t paramIndex = 0, numParams = paramTypes.size(); @@ -2791,8 +2795,8 @@ checkForSwiftCC(paramIndex); continue; + // SwiftAsyncContext is not limited to swiftasynccall functions. case ParameterABI::SwiftAsyncContext: - // FIXME: might want to require swiftasynccc when it exists continue; // swift_error parameters must be preceded by a swift_context parameter. @@ -7303,6 +7307,8 @@ return createSimpleAttr(Ctx, Attr); case ParsedAttr::AT_SwiftCall: return createSimpleAttr(Ctx, Attr); + case ParsedAttr::AT_SwiftAsyncCall: + return createSimpleAttr(Ctx, Attr); case ParsedAttr::AT_VectorCall: return createSimpleAttr(Ctx, Attr); case ParsedAttr::AT_AArch64VectorPcs: diff --git a/clang/test/CodeGen/arm-swiftcall.c b/clang/test/CodeGen/arm-swiftcall.c --- a/clang/test/CodeGen/arm-swiftcall.c +++ b/clang/test/CodeGen/arm-swiftcall.c @@ -3,6 +3,7 @@ // RUN: %clang_cc1 -triple armv7k-apple-ios9 -emit-llvm -o - %s | FileCheck %s #define SWIFTCALL __attribute__((swiftcall)) +#define SWIFTASYNCCALL __attribute__((swiftasynccall)) #define OUT __attribute__((swift_indirect_result)) #define ERROR __attribute__((swift_error_result)) #define CONTEXT __attribute__((swift_context)) @@ -54,7 +55,7 @@ SWIFTCALL void context_error_2(short s, CONTEXT int *self, ERROR float **error) {} // CHECK-LABEL: define{{.*}} void @context_error_2(i16{{.*}}, i32* swiftself{{.*}}, float** swifterror %0) -SWIFTCALL void async_context_1(ASYNC_CONTEXT void *self) {} +SWIFTASYNCCALL void async_context_1(ASYNC_CONTEXT void *self) {} // CHECK-LABEL: define {{.*}} void @async_context_1(i8* swiftasync /*****************************************************************************/ diff --git a/clang/test/CodeGen/debug-info-cc.c b/clang/test/CodeGen/debug-info-cc.c --- a/clang/test/CodeGen/debug-info-cc.c +++ b/clang/test/CodeGen/debug-info-cc.c @@ -19,6 +19,7 @@ // CC_SpirFunction, // default for OpenCL functions on SPIR target // CC_OpenCLKernel, // inferred for OpenCL kernels // CC_Swift, // __attribute__((swiftcall)) +// CC_SwiftAsync, // __attribute__((swiftasynccall)) // CC_PreserveMost, // __attribute__((preserve_most)) // CC_PreserveAll, // __attribute__((preserve_all)) // }; @@ -56,6 +57,13 @@ return a+b; } +// [FIXME: swiftasynccc] Update debuginfo tag to SwiftAsync once LLVM support lands. +// LINUX: !DISubprogram({{.*}}"add_swiftasynccall", {{.*}}type: ![[FTY:[0-9]+]] +// LINUX: ![[FTY]] = !DISubroutineType({{.*}}cc: DW_CC_LLVM_Swift, +__attribute__((swiftasynccall)) int add_swiftasynccall(int a, int b, int c) { + return a+b+c; +} + // LINUX: !DISubprogram({{.*}}"add_inteloclbicc", {{.*}}type: ![[FTY:[0-9]+]] // LINUX: ![[FTY]] = !DISubroutineType({{.*}}cc: DW_CC_LLVM_IntelOclBicc, __attribute__((intel_ocl_bicc)) int add_inteloclbicc(int a, int b) { diff --git a/clang/test/CodeGen/swift-call-conv.c b/clang/test/CodeGen/swift-call-conv.c --- a/clang/test/CodeGen/swift-call-conv.c +++ b/clang/test/CodeGen/swift-call-conv.c @@ -1,5 +1,4 @@ // RUN: %clang_cc1 -triple aarch64-unknown-windows-msvc -emit-llvm %s -o - | FileCheck %s -// RUN: %clang_cc1 -triple thumbv7-unknown-windows-msvc -emit-llvm %s -o - | FileCheck %s // RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -emit-llvm %s -o - | FileCheck %s // REQUIRES: aarch64-registered-target,arm-registered-target,x86-registered-target diff --git a/clang/test/Sema/attr-c2x.c b/clang/test/Sema/attr-c2x.c --- a/clang/test/Sema/attr-c2x.c +++ b/clang/test/Sema/attr-c2x.c @@ -16,6 +16,8 @@ void context_okay(void *context [[clang::swift_context]]) [[clang::swiftcall]]; void context_okay2(void *context [[clang::swift_context]], void *selfType, char **selfWitnessTable) [[clang::swiftcall]]; +void context_async_okay(void *context [[clang::swift_async_context]]) [[clang::swiftasynccall]]; +void context_async_okay2(void *context [[clang::swift_async_context]], void *selfType, char **selfWitnessTable) [[clang::swiftasynccall]]; void *f1(void) [[clang::ownership_returns(foo)]]; void *f2() [[clang::ownership_returns(foo)]]; // expected-warning {{'ownership_returns' attribute only applies to non-K&R-style functions}} diff --git a/clang/test/Sema/attr-swiftcall.c b/clang/test/Sema/attr-swiftcall.c --- a/clang/test/Sema/attr-swiftcall.c +++ b/clang/test/Sema/attr-swiftcall.c @@ -2,16 +2,22 @@ // RUN: %clang_cc1 -triple x86_64-unknown-windows -fsyntax-only -verify %s #define SWIFTCALL __attribute__((swiftcall)) +#define SWIFTASYNCCALL __attribute__((swiftasynccall)) #define INDIRECT_RESULT __attribute__((swift_indirect_result)) #define ERROR_RESULT __attribute__((swift_error_result)) #define CONTEXT __attribute__((swift_context)) #define ASYNC_CONTEXT __attribute__((swift_async_context)) int notAFunction SWIFTCALL; // expected-warning {{'swiftcall' only applies to function types; type here is 'int'}} +int notAnAsyncFunction SWIFTASYNCCALL; // expected-warning {{'swiftasynccall' only applies to function types; type here is 'int'}} void variadic(int x, ...) SWIFTCALL; // expected-error {{variadic function cannot use swiftcall calling convention}} +void variadic_async(int x, ...) SWIFTASYNCCALL; // expected-error {{variadic function cannot use swiftasynccall calling convention}} void unprototyped() SWIFTCALL; // expected-error {{function with no prototype cannot use the swiftcall calling convention}} +void unprototyped_async() SWIFTASYNCCALL; // expected-error {{function with no prototype cannot use the swiftasynccall calling convention}} void multiple_ccs(int x) SWIFTCALL __attribute__((vectorcall)); // expected-error {{vectorcall and swiftcall attributes are not compatible}} +void multiple_ccs_async(int x) SWIFTASYNCCALL __attribute__((vectorcall)); // expected-error {{vectorcall and swiftasynccall attributes are not compatible}} void (*functionPointer)(void) SWIFTCALL; +void (*asyncFunctionPointer)(void) SWIFTASYNCCALL; void indirect_result_nonswift(INDIRECT_RESULT void *out); // expected-error {{'swift_indirect_result' parameter can only be used with swiftcall calling convention}} void indirect_result_bad_position(int first, INDIRECT_RESULT void *out) SWIFTCALL; // expected-error {{'swift_indirect_result' parameters must be first parameters of function}} @@ -31,7 +37,7 @@ void context_okay(CONTEXT void *context) SWIFTCALL; void context_okay2(CONTEXT void *context, void *selfType, char **selfWitnessTable) SWIFTCALL; -void async_context_okay_for_now(ASYNC_CONTEXT void *context); -void async_context_bad_type(ASYNC_CONTEXT int context) SWIFTCALL; // expected-error {{'swift_async_context' parameter must have pointer type; type here is 'int'}} -void async_context_okay(ASYNC_CONTEXT void *context) SWIFTCALL; -void async_context_okay2(ASYNC_CONTEXT void *context, void *selfType, char **selfWitnessTable) SWIFTCALL; +void async_context_nonswift(ASYNC_CONTEXT void *context); // OK +void async_context_bad_type(ASYNC_CONTEXT int context) SWIFTASYNCCALL; // expected-error {{'swift_async_context' parameter must have pointer type; type here is 'int'}} +void async_context_okay(ASYNC_CONTEXT void *context) SWIFTASYNCCALL; +void async_context_okay2(void *someArg, ASYNC_CONTEXT void *context, void *otherArg) SWIFTASYNCCALL; diff --git a/clang/test/Sema/no_callconv.cpp b/clang/test/Sema/no_callconv.cpp --- a/clang/test/Sema/no_callconv.cpp +++ b/clang/test/Sema/no_callconv.cpp @@ -11,6 +11,7 @@ void __attribute__((ms_abi)) funcH() {} // expected-error {{'ms_abi' calling convention is not supported for this target}} void __attribute__((intel_ocl_bicc)) funcJ() {} // expected-error {{'intel_ocl_bicc' calling convention is not supported for this target}} void __attribute__((swiftcall)) funcK() {} // expected-error {{'swiftcall' calling convention is not supported for this target}} +void __attribute__((swiftasynccall)) funcKK() {} // expected-error {{'swiftasynccall' calling convention is not supported for this target}} void __attribute__((pascal)) funcG() {} // expected-error {{'pascal' calling convention is not supported for this target}} void __attribute__((preserve_most)) funcL() {} // expected-error {{'preserve_most' calling convention is not supported for this target}} void __attribute__((preserve_all)) funcM() {} // expected-error {{'preserve_all' calling convention is not supported for this target}} @@ -26,6 +27,7 @@ void __attribute__((ms_abi)) funcH() {} void __attribute__((intel_ocl_bicc)) funcJ() {} void __attribute__((swiftcall)) funcK() {} +void __attribute__((swiftasynccall)) funcKK() {} void __attribute__((preserve_most)) funcL() {} void __attribute__((preserve_all)) funcM() {} diff --git a/clang/test/SemaCXX/attr-swiftcall.cpp b/clang/test/SemaCXX/attr-swiftcall.cpp --- a/clang/test/SemaCXX/attr-swiftcall.cpp +++ b/clang/test/SemaCXX/attr-swiftcall.cpp @@ -1,14 +1,20 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify %s #define SWIFTCALL __attribute__((swiftcall)) +#define SWIFTASYNCCALL __attribute__((swiftasynccall)) #define INDIRECT_RESULT __attribute__((swift_indirect_result)) #define ERROR_RESULT __attribute__((swift_error_result)) #define CONTEXT __attribute__((swift_context)) +#define ASYNC_CONTEXT __attribute__((swift_async_context)) int notAFunction SWIFTCALL; // expected-warning {{'swiftcall' only applies to function types; type here is 'int'}} +int notAnAsyncFunction SWIFTASYNCCALL; // expected-warning {{'swiftasynccall' only applies to function types; type here is 'int'}} void variadic(int x, ...) SWIFTCALL; // expected-error {{variadic function cannot use swiftcall calling convention}} +void variadic_async(int x, ...) SWIFTASYNCCALL; // expected-error {{variadic function cannot use swiftasynccall calling convention}} void multiple_ccs(int x) SWIFTCALL __attribute__((vectorcall)); // expected-error {{vectorcall and swiftcall attributes are not compatible}} +void multiple_ccs_async(int x) SWIFTASYNCCALL __attribute__((vectorcall)); // expected-error {{vectorcall and swiftasynccall attributes are not compatible}} void (*functionPointer)(void) SWIFTCALL; +void (*asyncFunctionPointer)(void) SWIFTASYNCCALL; void indirect_result_nonswift(INDIRECT_RESULT void *out); // expected-error {{'swift_indirect_result' parameter can only be used with swiftcall calling convention}} void indirect_result_bad_position(int first, INDIRECT_RESULT void *out) SWIFTCALL; // expected-error {{'swift_indirect_result' parameters must be first parameters of function}} @@ -28,6 +34,11 @@ void context_okay(CONTEXT void *context) SWIFTCALL; void context_okay(CONTEXT void *context, void *selfType, char **selfWitnessTable) SWIFTCALL; +void async_context_nonswift(ASYNC_CONTEXT void *context); // OK +void async_context_bad_type(ASYNC_CONTEXT int context) SWIFTASYNCCALL; // expected-error {{'swift_async_context' parameter must have pointer type; type here is 'int'}} +void async_context_okay(ASYNC_CONTEXT void *context) SWIFTASYNCCALL; +void async_context_okay(void *someArg, ASYNC_CONTEXT void *context, void *otherArg) SWIFTASYNCCALL; + template void indirect_result_temp_okay1(INDIRECT_RESULT T *out) SWIFTCALL; template void indirect_result_temp_okay2(INDIRECT_RESULT T out) SWIFTCALL; // expected-note {{candidate template ignored: substitution failure [with T = int]: 'swift_indirect_result' parameter must have pointer type; type here is 'int'}} void test_indirect_result_temp(void *out) { diff --git a/clang/tools/libclang/CXType.cpp b/clang/tools/libclang/CXType.cpp --- a/clang/tools/libclang/CXType.cpp +++ b/clang/tools/libclang/CXType.cpp @@ -664,6 +664,7 @@ TCALLINGCONV(AAPCS_VFP); TCALLINGCONV(IntelOclBicc); TCALLINGCONV(Swift); + TCALLINGCONV(SwiftAsync); TCALLINGCONV(PreserveMost); TCALLINGCONV(PreserveAll); case CC_SpirFunction: return CXCallingConv_Unexposed; diff --git a/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h b/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h --- a/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h +++ b/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h @@ -67,7 +67,8 @@ Eabi, Vectorcall, Regcall, - Swift, // Clang-only + Swift, // Clang-only + SwiftAsync, // Clang-only }; enum class ReferenceKind : uint8_t { None, LValueRef, RValueRef }; diff --git a/llvm/lib/Demangle/MicrosoftDemangle.cpp b/llvm/lib/Demangle/MicrosoftDemangle.cpp --- a/llvm/lib/Demangle/MicrosoftDemangle.cpp +++ b/llvm/lib/Demangle/MicrosoftDemangle.cpp @@ -1713,6 +1713,8 @@ return CallingConv::Vectorcall; case 'S': return CallingConv::Swift; + case 'T': + return CallingConv::SwiftAsync; } return CallingConv::None; diff --git a/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp b/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp --- a/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp +++ b/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp @@ -110,6 +110,9 @@ case CallingConv::Swift: OS << "__attribute__((__swiftcall__)) "; break; + case CallingConv::SwiftAsync: + OS << "__attribute__((__swiftasynccall__)) "; + break; default: break; } diff --git a/llvm/test/Demangle/ms-mangle.test b/llvm/test/Demangle/ms-mangle.test --- a/llvm/test/Demangle/ms-mangle.test +++ b/llvm/test/Demangle/ms-mangle.test @@ -341,6 +341,9 @@ ?swift_func@@YSXXZ ; CHECK: void __attribute__((__swiftcall__)) swift_func(void) +?swift_async_func@@YTXXZ +; CHECK: void __attribute__((__swiftasynccall__)) swift_async_func(void) + ??$fn_tmpl@$1?extern_c_func@@YAXXZ@@YAXXZ ; CHECK: void __cdecl fn_tmpl<&void __cdecl extern_c_func(void)>(void)