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,11 +4392,35 @@ }]; } +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. diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3049,7 +3049,8 @@ def note_nsdictionary_duplicate_key_here : Note< "previous equal key is here">; def err_swift_param_attr_not_swiftcall : Error< - "'%0' parameter can only be used with swiftcall calling convention">; + "'%0' parameter can only be used with %select{swiftcall|swiftasynccall}1 " + "calling convention">; def err_swift_indirect_result_not_first : Error< "'swift_indirect_result' parameters must be first parameters of function">; def err_swift_error_result_not_after_swift_context : Error< 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 @@ -251,23 +251,24 @@ /// CallingConv - Specifies the calling convention that a function uses. enum CallingConv { - CC_C, // __attribute__((cdecl)) - CC_X86StdCall, // __attribute__((stdcall)) - CC_X86FastCall, // __attribute__((fastcall)) - CC_X86ThisCall, // __attribute__((thiscall)) - CC_X86VectorCall, // __attribute__((vectorcall)) - CC_X86Pascal, // __attribute__((pascal)) - CC_Win64, // __attribute__((ms_abi)) - CC_X86_64SysV, // __attribute__((sysv_abi)) - CC_X86RegCall, // __attribute__((regcall)) - CC_AAPCS, // __attribute__((pcs("aapcs"))) - CC_AAPCS_VFP, // __attribute__((pcs("aapcs-vfp"))) - CC_IntelOclBicc, // __attribute__((intel_ocl_bicc)) - CC_SpirFunction, // default for OpenCL functions on SPIR target - CC_OpenCLKernel, // inferred for OpenCL kernels - CC_Swift, // __attribute__((swiftcall)) - CC_PreserveMost, // __attribute__((preserve_most)) - CC_PreserveAll, // __attribute__((preserve_all)) + CC_C, // __attribute__((cdecl)) + CC_X86StdCall, // __attribute__((stdcall)) + CC_X86FastCall, // __attribute__((fastcall)) + CC_X86ThisCall, // __attribute__((thiscall)) + CC_X86VectorCall, // __attribute__((vectorcall)) + CC_X86Pascal, // __attribute__((pascal)) + CC_Win64, // __attribute__((ms_abi)) + CC_X86_64SysV, // __attribute__((sysv_abi)) + CC_X86RegCall, // __attribute__((regcall)) + CC_AAPCS, // __attribute__((pcs("aapcs"))) + CC_AAPCS_VFP, // __attribute__((pcs("aapcs-vfp"))) + CC_IntelOclBicc, // __attribute__((intel_ocl_bicc)) + 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 @@ -450,6 +450,7 @@ CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { switch (CC) { case CC_Swift: + case CC_SwiftAsync: return CCCR_OK; 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 @@ -141,6 +141,7 @@ switch (CC) { case CC_C: case CC_Swift: + case CC_SwiftAsync: case CC_OpenCLKernel: return CCCR_OK; default: 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 @@ -129,6 +129,7 @@ switch (CC) { case CC_C: case CC_Swift: + case CC_SwiftAsync: return CCCR_OK; 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 @@ -344,6 +344,7 @@ case CC_C: case CC_PreserveMost: case CC_Swift: + case CC_SwiftAsync: case CC_X86Pascal: case CC_IntelOclBicc: case CC_OpenCLKernel: @@ -702,6 +703,7 @@ switch (CC) { case CC_C: case CC_Swift: + case CC_SwiftAsync: case CC_X86VectorCall: case CC_IntelOclBicc: case CC_Win64: @@ -783,6 +785,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,18 @@ assert(EPI.ExtParameterInfos && "shouldn't get here without param infos"); bool hasCheckedSwiftCall = false; + bool hasCheckedSwiftAsyncCall = false; + auto reportWrongABI = [&](unsigned paramIndex, bool shouldBeAsync) { + S.Diag(getParamLoc(paramIndex), diag::err_swift_param_attr_not_swiftcall) + << getParameterABISpelling(EPI.ExtParameterInfos[paramIndex].getABI()) + << shouldBeAsync; + }; 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, false); }; for (size_t paramIndex = 0, numParams = paramTypes.size(); @@ -2792,7 +2798,10 @@ continue; case ParameterABI::SwiftAsyncContext: - // FIXME: might want to require swiftasynccc when it exists + if (!hasCheckedSwiftAsyncCall && EPI.ExtInfo.getCC() != CC_SwiftAsync) { + reportWrongABI(paramIndex, true); + } + hasCheckedSwiftAsyncCall = true; continue; // swift_error parameters must be preceded by a swift_context parameter. @@ -7303,6 +7312,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) { + return a+b; +} + // 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/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); // expected-error {{'swift_async_context' parameter can only be used with swiftasynccall calling convention}} +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); // expected-error {{'swift_async_context' parameter can only be used with swiftasynccall calling convention}} +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)