Index: clang/include/clang/AST/Attr.h =================================================================== --- clang/include/clang/AST/Attr.h +++ clang/include/clang/AST/Attr.h @@ -208,6 +208,8 @@ switch (getKind()) { case attr::SwiftContext: return ParameterABI::SwiftContext; + case attr::SwiftAsyncContext: + return ParameterABI::SwiftAsyncContext; case attr::SwiftErrorResult: return ParameterABI::SwiftErrorResult; case attr::SwiftIndirectResult: Index: clang/include/clang/Basic/Attr.td =================================================================== --- clang/include/clang/Basic/Attr.td +++ clang/include/clang/Basic/Attr.td @@ -2371,6 +2371,11 @@ let Documentation = [SwiftContextDocs]; } +def SwiftAsyncContext : ParameterABIAttr { + let Spellings = [Clang<"swift_async_context">]; + let Documentation = [SwiftAsyncContextDocs]; +} + def SwiftErrorResult : ParameterABIAttr { let Spellings = [Clang<"swift_error_result">]; let Documentation = [SwiftErrorResultDocs]; Index: clang/include/clang/Basic/AttrDocs.td =================================================================== --- clang/include/clang/Basic/AttrDocs.td +++ clang/include/clang/Basic/AttrDocs.td @@ -4392,6 +4392,19 @@ }]; } +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. + +This treatment generally passes the context value in a special register +which is normally callee-preserved. + +A context parameter must have pointer or reference type. + }]; +} + def SwiftErrorResultDocs : Documentation { let Category = DocCatVariable; let Content = [{ Index: clang/include/clang/Basic/Specifiers.h =================================================================== --- clang/include/clang/Basic/Specifiers.h +++ clang/include/clang/Basic/Specifiers.h @@ -344,7 +344,12 @@ /// This parameter (which must have pointer type) uses the special /// Swift context-pointer ABI treatment. There can be at /// most one parameter on a given function that uses this treatment. - SwiftContext + SwiftContext, + + /// This parameter (which must have pointer type) uses the special + /// Swift asynchronous context-pointer ABI treatment. There can be at + /// most one parameter on a given function that uses this treatment. + SwiftAsyncContext, }; /// Assigned inheritance model for a class in the MS C++ ABI. Must match order Index: clang/lib/AST/ItaniumMangle.cpp =================================================================== --- clang/lib/AST/ItaniumMangle.cpp +++ clang/lib/AST/ItaniumMangle.cpp @@ -2942,6 +2942,7 @@ // All of these start with "swift", so they come before "ns_consumed". case ParameterABI::SwiftContext: + case ParameterABI::SwiftAsyncContext: case ParameterABI::SwiftErrorResult: case ParameterABI::SwiftIndirectResult: mangleVendorQualifier(getParameterABISpelling(PI.getABI())); Index: clang/lib/AST/TypePrinter.cpp =================================================================== --- clang/lib/AST/TypePrinter.cpp +++ clang/lib/AST/TypePrinter.cpp @@ -846,6 +846,8 @@ llvm_unreachable("asking for spelling of ordinary parameter ABI"); case ParameterABI::SwiftContext: return "swift_context"; + case ParameterABI::SwiftAsyncContext: + return "swift_async_context"; case ParameterABI::SwiftErrorResult: return "swift_error_result"; case ParameterABI::SwiftIndirectResult: Index: clang/lib/CodeGen/CGCall.cpp =================================================================== --- clang/lib/CodeGen/CGCall.cpp +++ clang/lib/CodeGen/CGCall.cpp @@ -2365,6 +2365,10 @@ case ParameterABI::SwiftContext: Attrs.addAttribute(llvm::Attribute::SwiftSelf); break; + + case ParameterABI::SwiftAsyncContext: + Attrs.addAttribute(llvm::Attribute::SwiftAsync); + break; } if (FI.getExtParameterInfo(ArgNo).isNoEscape()) Index: clang/lib/Sema/SemaDeclAttr.cpp =================================================================== --- clang/lib/Sema/SemaDeclAttr.cpp +++ clang/lib/Sema/SemaDeclAttr.cpp @@ -4958,6 +4958,14 @@ D->addAttr(::new (Context) SwiftContextAttr(Context, CI)); return; + case ParameterABI::SwiftAsyncContext: + if (!isValidSwiftContextType(type)) { + Diag(CI.getLoc(), diag::err_swift_abi_parameter_wrong_type) + << getParameterABISpelling(abi) << /*pointer to pointer */ 0 << type; + } + D->addAttr(::new (Context) SwiftAsyncContextAttr(Context, CI)); + return; + case ParameterABI::SwiftErrorResult: if (!isValidSwiftErrorResultType(type)) { Diag(CI.getLoc(), diag::err_swift_abi_parameter_wrong_type) @@ -8086,6 +8094,9 @@ case ParsedAttr::AT_SwiftContext: S.AddParameterABIAttr(D, AL, ParameterABI::SwiftContext); break; + case ParsedAttr::AT_SwiftAsyncContext: + S.AddParameterABIAttr(D, AL, ParameterABI::SwiftAsyncContext); + break; case ParsedAttr::AT_SwiftErrorResult: S.AddParameterABIAttr(D, AL, ParameterABI::SwiftErrorResult); break; Index: clang/lib/Sema/SemaType.cpp =================================================================== --- clang/lib/Sema/SemaType.cpp +++ clang/lib/Sema/SemaType.cpp @@ -2791,6 +2791,10 @@ checkForSwiftCC(paramIndex); continue; + case ParameterABI::SwiftAsyncContext: + // FIXME: might want to require swiftasynccc when it exists + continue; + // swift_error parameters must be preceded by a swift_context parameter. case ParameterABI::SwiftErrorResult: checkForSwiftCC(paramIndex); Index: clang/test/CodeGen/arm-swiftcall.c =================================================================== --- clang/test/CodeGen/arm-swiftcall.c +++ clang/test/CodeGen/arm-swiftcall.c @@ -6,6 +6,7 @@ #define OUT __attribute__((swift_indirect_result)) #define ERROR __attribute__((swift_error_result)) #define CONTEXT __attribute__((swift_context)) +#define ASYNC_CONTEXT __attribute__((swift_async_context)) /*****************************************************************************/ /****************************** PARAMETER ABIS *******************************/ @@ -53,6 +54,9 @@ 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) {} +// CHECK-LABEL: define {{.*}} void @async_context_1(i8* swiftasync + /*****************************************************************************/ /********************************** LOWERING *********************************/ /*****************************************************************************/ Index: clang/test/Misc/pragma-attribute-supported-attributes-list.test =================================================================== --- clang/test/Misc/pragma-attribute-supported-attributes-list.test +++ clang/test/Misc/pragma-attribute-supported-attributes-list.test @@ -154,6 +154,7 @@ // CHECK-NEXT: SetTypestate (SubjectMatchRule_function_is_member) // CHECK-NEXT: SpeculativeLoadHardening (SubjectMatchRule_function, SubjectMatchRule_objc_method) // CHECK-NEXT: SwiftAsync (SubjectMatchRule_function, SubjectMatchRule_objc_method) +// CHECK-NEXT: SwiftAsyncContext (SubjectMatchRule_variable_is_parameter) // CHECK-NEXT: SwiftAsyncName (SubjectMatchRule_objc_method, SubjectMatchRule_function) // CHECK-NEXT: SwiftBridgedTypedef (SubjectMatchRule_type_alias) // CHECK-NEXT: SwiftContext (SubjectMatchRule_variable_is_parameter) Index: clang/test/Sema/attr-swiftcall.c =================================================================== --- clang/test/Sema/attr-swiftcall.c +++ clang/test/Sema/attr-swiftcall.c @@ -5,6 +5,7 @@ #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'}} void variadic(int x, ...) SWIFTCALL; // expected-error {{variadic function cannot use swiftcall calling convention}} @@ -29,3 +30,8 @@ void context_bad_type(CONTEXT int context) SWIFTCALL; // expected-error {{'swift_context' parameter must have pointer type; type here is 'int'}} 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;