SwiftAsync: add Clang attribute to apply the LLVM `swiftasync` one.

Expected to be used by Swift runtime developers.
This commit is contained in:
Tim Northover 2021-05-28 12:28:52 +01:00
parent 4694097dab
commit e94fada045
12 changed files with 61 additions and 1 deletions

View File

@ -208,6 +208,8 @@ public:
switch (getKind()) {
case attr::SwiftContext:
return ParameterABI::SwiftContext;
case attr::SwiftAsyncContext:
return ParameterABI::SwiftAsyncContext;
case attr::SwiftErrorResult:
return ParameterABI::SwiftErrorResult;
case attr::SwiftIndirectResult:

View File

@ -2457,6 +2457,11 @@ def SwiftContext : ParameterABIAttr {
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];

View File

@ -4529,6 +4529,19 @@ A context parameter must have pointer or reference type.
}];
}
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 = [{

View File

@ -344,7 +344,12 @@ namespace clang {
/// 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

View File

@ -3140,6 +3140,7 @@ CXXNameMangler::mangleExtParameterInfo(FunctionProtoType::ExtParameterInfo PI) {
// 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()));

View File

@ -846,6 +846,8 @@ StringRef clang::getParameterABISpelling(ParameterABI ABI) {
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:

View File

@ -2505,6 +2505,10 @@ void CodeGenModule::ConstructAttributeList(StringRef Name,
case ParameterABI::SwiftContext:
Attrs.addAttribute(llvm::Attribute::SwiftSelf);
break;
case ParameterABI::SwiftAsyncContext:
Attrs.addAttribute(llvm::Attribute::SwiftAsync);
break;
}
if (FI.getExtParameterInfo(ArgNo).isNoEscape())

View File

@ -4896,6 +4896,14 @@ void Sema::AddParameterABIAttr(Decl *D, const AttributeCommonInfo &CI,
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)
@ -8104,6 +8112,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
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;

View File

@ -2799,6 +2799,10 @@ static void checkExtParameterInfos(Sema &S, ArrayRef<QualType> paramTypes,
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);

View File

@ -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 @@ void test_context_error_1() {
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 *********************************/
/*****************************************************************************/

View File

@ -156,6 +156,7 @@
// CHECK-NEXT: SpeculativeLoadHardening (SubjectMatchRule_function, SubjectMatchRule_objc_method)
// CHECK-NEXT: StandaloneDebug (SubjectMatchRule_record)
// CHECK-NEXT: SwiftAsync (SubjectMatchRule_function, SubjectMatchRule_objc_method)
// CHECK-NEXT: SwiftAsyncContext (SubjectMatchRule_variable_is_parameter)
// CHECK-NEXT: SwiftAsyncError (SubjectMatchRule_function, SubjectMatchRule_objc_method)
// CHECK-NEXT: SwiftAsyncName (SubjectMatchRule_objc_method, SubjectMatchRule_function)
// CHECK-NEXT: SwiftBridgedTypedef (SubjectMatchRule_type_alias)

View File

@ -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,10 @@ void context_nonswift(CONTEXT void *context); // expected-error {{'swift_context
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_bad_pos(int context) ASYNC_CONTEXT SWIFTCALL; // expected-warning {{'swift_async_context' attribute only applies to parameters}}
void async_context_bad_args(__attribute__((swift_async_context(1))) void *context) SWIFTCALL; // expected-error {{'swift_async_context' attribute takes no arguments}}
void async_context_okay(ASYNC_CONTEXT void *context) SWIFTCALL;
void async_context_okay2(ASYNC_CONTEXT void *context, void *selfType, char **selfWitnessTable) SWIFTCALL;