varungandhi-apple updated this revision to Diff 321801. varungandhi-apple added a comment.
Correct documentation on tail call behavior as pointed out by John. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D95561/new/ https://reviews.llvm.org/D95561 Files: clang/include/clang-c/Index.h clang/include/clang/Basic/Attr.td clang/include/clang/Basic/AttrDocs.td clang/include/clang/Basic/DiagnosticSemaKinds.td clang/include/clang/Basic/Specifiers.h clang/include/clang/CodeGen/SwiftCallingConv.h clang/lib/AST/ItaniumMangle.cpp clang/lib/AST/MicrosoftMangle.cpp clang/lib/AST/Type.cpp clang/lib/AST/TypePrinter.cpp clang/lib/Basic/Targets/AArch64.cpp clang/lib/Basic/Targets/ARM.cpp clang/lib/Basic/Targets/PPC.h clang/lib/Basic/Targets/SystemZ.h clang/lib/Basic/Targets/WebAssembly.h clang/lib/Basic/Targets/X86.h clang/lib/CodeGen/CGCall.cpp clang/lib/CodeGen/CGDebugInfo.cpp clang/lib/Sema/SemaDeclAttr.cpp clang/lib/Sema/SemaType.cpp clang/test/CodeGen/arm-swiftcall.c clang/test/CodeGen/debug-info-cc.c clang/test/Sema/attr-c2x.c clang/test/Sema/attr-swiftcall.c clang/test/Sema/no_callconv.cpp clang/test/SemaCXX/attr-swiftcall.cpp clang/tools/libclang/CXType.cpp llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h llvm/lib/Demangle/MicrosoftDemangle.cpp llvm/lib/Demangle/MicrosoftDemangleNodes.cpp llvm/test/Demangle/ms-mangle.test
Index: llvm/test/Demangle/ms-mangle.test =================================================================== --- llvm/test/Demangle/ms-mangle.test +++ 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) Index: llvm/lib/Demangle/MicrosoftDemangleNodes.cpp =================================================================== --- llvm/lib/Demangle/MicrosoftDemangleNodes.cpp +++ 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; } Index: llvm/lib/Demangle/MicrosoftDemangle.cpp =================================================================== --- llvm/lib/Demangle/MicrosoftDemangle.cpp +++ 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; Index: llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h =================================================================== --- llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h +++ 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 }; Index: clang/tools/libclang/CXType.cpp =================================================================== --- clang/tools/libclang/CXType.cpp +++ 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; Index: clang/test/SemaCXX/attr-swiftcall.cpp =================================================================== --- clang/test/SemaCXX/attr-swiftcall.cpp +++ 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 <class T> void indirect_result_temp_okay1(INDIRECT_RESULT T *out) SWIFTCALL; template <class T> 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) { Index: clang/test/Sema/no_callconv.cpp =================================================================== --- clang/test/Sema/no_callconv.cpp +++ 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() {} Index: clang/test/Sema/attr-swiftcall.c =================================================================== --- clang/test/Sema/attr-swiftcall.c +++ 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; Index: clang/test/Sema/attr-c2x.c =================================================================== --- clang/test/Sema/attr-c2x.c +++ 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}} Index: clang/test/CodeGen/debug-info-cc.c =================================================================== --- clang/test/CodeGen/debug-info-cc.c +++ 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) { Index: clang/test/CodeGen/arm-swiftcall.c =================================================================== --- clang/test/CodeGen/arm-swiftcall.c +++ 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 /*****************************************************************************/ Index: clang/lib/Sema/SemaType.cpp =================================================================== --- clang/lib/Sema/SemaType.cpp +++ 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<PascalAttr>(Ctx, Attr); case ParsedAttr::AT_SwiftCall: return createSimpleAttr<SwiftCallAttr>(Ctx, Attr); + case ParsedAttr::AT_SwiftAsyncCall: + return createSimpleAttr<SwiftAsyncCallAttr>(Ctx, Attr); case ParsedAttr::AT_VectorCall: return createSimpleAttr<VectorCallAttr>(Ctx, Attr); case ParsedAttr::AT_AArch64VectorPcs: Index: clang/lib/Sema/SemaDeclAttr.cpp =================================================================== --- clang/lib/Sema/SemaDeclAttr.cpp +++ 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: Index: clang/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- clang/lib/CodeGen/CGDebugInfo.cpp +++ 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: Index: clang/lib/CodeGen/CGCall.cpp =================================================================== --- clang/lib/CodeGen/CGCall.cpp +++ 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<QualType> 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; Index: clang/lib/Basic/Targets/X86.h =================================================================== --- clang/lib/Basic/Targets/X86.h +++ 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; Index: clang/lib/Basic/Targets/WebAssembly.h =================================================================== --- clang/lib/Basic/Targets/WebAssembly.h +++ 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; Index: clang/lib/Basic/Targets/SystemZ.h =================================================================== --- clang/lib/Basic/Targets/SystemZ.h +++ 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: Index: clang/lib/Basic/Targets/PPC.h =================================================================== --- clang/lib/Basic/Targets/PPC.h +++ 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; Index: clang/lib/Basic/Targets/ARM.cpp =================================================================== --- clang/lib/Basic/Targets/ARM.cpp +++ 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; Index: clang/lib/Basic/Targets/AArch64.cpp =================================================================== --- clang/lib/Basic/Targets/AArch64.cpp +++ 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: Index: clang/lib/AST/TypePrinter.cpp =================================================================== --- clang/lib/AST/TypePrinter.cpp +++ 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; Index: clang/lib/AST/Type.cpp =================================================================== --- clang/lib/AST/Type.cpp +++ 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: Index: clang/lib/AST/MicrosoftMangle.cpp =================================================================== --- clang/lib/AST/MicrosoftMangle.cpp +++ 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; } Index: clang/lib/AST/ItaniumMangle.cpp =================================================================== --- clang/lib/AST/ItaniumMangle.cpp +++ 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"); } Index: clang/include/clang/CodeGen/SwiftCallingConv.h =================================================================== --- clang/include/clang/CodeGen/SwiftCallingConv.h +++ 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. // //===----------------------------------------------------------------------===// Index: clang/include/clang/Basic/Specifiers.h =================================================================== --- clang/include/clang/Basic/Specifiers.h +++ 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; Index: clang/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticSemaKinds.td +++ 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< Index: clang/include/clang/Basic/AttrDocs.td =================================================================== --- clang/include/clang/Basic/AttrDocs.td +++ 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. Index: clang/include/clang/Basic/Attr.td =================================================================== --- clang/include/clang/Basic/Attr.td +++ 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]; Index: clang/include/clang-c/Index.h =================================================================== --- clang/include/clang-c/Index.h +++ 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
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits