Skip to content

Commit 7ab4b18

Browse files
varungandhi-appleetcwilde
authored andcommitted
[Clang] Introduce Swift async calling convention.
This change is intended as initial setup. The plan is to add more semantic checks later. Most of the code closely mirrors that for the Swift calling convention. Three places are marked as [FIXME: swiftasynccc]; those will be addressed in follow-up commits. Differential Revision: https://reviews.llvm.org/D95561 (cherry-pick to apple/stable/20210107 from not-yet-merged revision)
1 parent 6c72393 commit 7ab4b18

33 files changed

+157
-22
lines changed

clang/include/clang-c/Index.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
* compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
3434
*/
3535
#define CINDEX_VERSION_MAJOR 0
36-
#define CINDEX_VERSION_MINOR 61
36+
#define CINDEX_VERSION_MINOR 62
3737

3838
#define CINDEX_VERSION_ENCODE(major, minor) (((major)*10000) + ((minor)*1))
3939

@@ -3418,6 +3418,7 @@ enum CXCallingConv {
34183418
CXCallingConv_PreserveMost = 14,
34193419
CXCallingConv_PreserveAll = 15,
34203420
CXCallingConv_AArch64VectorCall = 16,
3421+
CXCallingConv_SwiftAsync = 17,
34213422

34223423
CXCallingConv_Invalid = 100,
34233424
CXCallingConv_Unexposed = 200

clang/include/clang/Basic/Attr.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2513,6 +2513,11 @@ def SwiftCall : DeclOrTypeAttr {
25132513
let Documentation = [SwiftCallDocs];
25142514
}
25152515

2516+
def SwiftAsyncCall : DeclOrTypeAttr {
2517+
let Spellings = [Clang<"swiftasynccall">];
2518+
let Documentation = [SwiftAsyncCallDocs];
2519+
}
2520+
25162521
def SwiftContext : ParameterABIAttr {
25172522
let Spellings = [Clang<"swift_context">];
25182523
let Documentation = [SwiftContextDocs];

clang/include/clang/Basic/AttrDocs.td

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4699,14 +4699,38 @@ A context parameter must have pointer or reference type.
46994699
}];
47004700
}
47014701

4702+
def SwiftAsyncCallDocs : Documentation {
4703+
let Category = DocCatVariable;
4704+
let Content = [{
4705+
The ``swiftasynccall`` attribute indicates that a function is
4706+
compatible with the low-level conventions of Swift async functions,
4707+
provided it declares the right formal arguments.
4708+
4709+
In most respects, this is similar to the ``swiftcall`` attribute, except for
4710+
the following:
4711+
- A parameter may be marked ``swift_async_context``, but the parameter
4712+
attributes ``swift_context``, ``swift_error_result`` and
4713+
``swift_indirect_result`` are not permitted.
4714+
- A ``swiftasynccall`` function must have return type ``void``.
4715+
- Within a ``swiftasynccall`` function, a call to a ``swiftasynccall``
4716+
function that is the immediate operand of a ``return`` statement is
4717+
guaranteed to be performed as a tail call. This syntax is allowed even
4718+
in C as an extension (a call to a void-returning function cannot be a
4719+
return operand in standard C). If something in the calling function would
4720+
semantically be performed after a guaranteed tail call, such as the
4721+
non-trivial destruction of a local variable or temporary,
4722+
then the program is ill-formed.
4723+
}];
4724+
}
4725+
47024726
def SwiftAsyncContextDocs : Documentation {
47034727
let Category = DocCatVariable;
47044728
let Content = [{
4705-
The ``swift_async_context`` attribute marks a parameter as having the
4706-
special asynchronous context-parameter ABI treatment.
4729+
The ``swift_async_context`` attribute marks a parameter of a ``swiftasynccall``
4730+
function as having the special asynchronous context-parameter ABI treatment.
47074731

4708-
This treatment generally passes the context value in a special register
4709-
which is normally callee-preserved.
4732+
If the function is not ``swiftasynccall``, this attribute only generates
4733+
extended frame information.
47104734

47114735
A context parameter must have pointer or reference type.
47124736
}];

clang/include/clang/Basic/Features.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ FEATURE(ptrauth_calls, LangOpts.PointerAuthCalls)
100100
FEATURE(ptrauth_returns, LangOpts.PointerAuthReturns)
101101
FEATURE(ptrauth_indirect_gotos, LangOpts.PointerAuthIndirectGotos)
102102
FEATURE(scudo, LangOpts.Sanitize.hasOneOf(SanitizerKind::Scudo))
103+
FEATURE(swiftasynccc, PP.getTargetInfo().isSwiftAsyncCCSupported())
103104
// Objective-C features
104105
FEATURE(objc_arr, LangOpts.ObjCAutoRefCount) // FIXME: REMOVE?
105106
FEATURE(objc_arc, LangOpts.ObjCAutoRefCount)

clang/include/clang/Basic/Specifiers.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ namespace clang {
266266
CC_SpirFunction, // default for OpenCL functions on SPIR target
267267
CC_OpenCLKernel, // inferred for OpenCL kernels
268268
CC_Swift, // __attribute__((swiftcall))
269+
CC_SwiftAsync, // __attribute__((swiftasynccall))
269270
CC_PreserveMost, // __attribute__((preserve_most))
270271
CC_PreserveAll, // __attribute__((preserve_all))
271272
CC_AArch64VectorCall, // __attribute__((aarch64_vector_pcs))
@@ -284,6 +285,7 @@ namespace clang {
284285
case CC_SpirFunction:
285286
case CC_OpenCLKernel:
286287
case CC_Swift:
288+
case CC_SwiftAsync:
287289
return false;
288290
default:
289291
return true;

clang/include/clang/Basic/TargetInfo.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1476,6 +1476,18 @@ class TargetInfo : public virtual TransferrableTargetInfo,
14761476

14771477
virtual CallingConvKind getCallingConvKind(bool ClangABICompat4) const;
14781478

1479+
/// \brief Is the Swift async calling convention supported for this target.
1480+
bool isSwiftAsyncCCSupported() const {
1481+
auto &triple = getTriple();
1482+
return triple.getArch() == llvm::Triple::x86_64 ||
1483+
triple.isARM() ||
1484+
triple.isAArch64();
1485+
}
1486+
1487+
CallingConvCheckResult checkSwiftAsyncCCSupported() const {
1488+
return isSwiftAsyncCCSupported() ? CCCR_OK : CCCR_Error;
1489+
}
1490+
14791491
/// Controls if __builtin_longjmp / __builtin_setjmp can be lowered to
14801492
/// llvm.eh.sjlj.longjmp / llvm.eh.sjlj.setjmp.
14811493
virtual bool hasSjLjLowering() const {

clang/include/clang/CodeGen/SwiftCallingConv.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
//
77
//===----------------------------------------------------------------------===//
88
//
9-
// Defines constants and types related to Swift ABI lowering.
9+
// Defines constants and types related to Swift ABI lowering. The same ABI
10+
// lowering applies to both sync and async functions.
1011
//
1112
//===----------------------------------------------------------------------===//
1213

clang/lib/AST/ItaniumMangle.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3109,6 +3109,8 @@ StringRef CXXNameMangler::getCallingConvQualifierName(CallingConv CC) {
31093109
return "ms_abi";
31103110
case CC_Swift:
31113111
return "swiftcall";
3112+
case CC_SwiftAsync:
3113+
return "swiftasynccall";
31123114
}
31133115
llvm_unreachable("bad calling convention");
31143116
}

clang/lib/AST/MicrosoftMangle.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2728,6 +2728,8 @@ void MicrosoftCXXNameMangler::mangleCallingConvention(CallingConv CC) {
27282728
// ::= J # __export __fastcall
27292729
// ::= Q # __vectorcall
27302730
// ::= S # __attribute__((__swiftcall__)) // Clang-only
2731+
// ::= T # __attribute__((__swiftasynccall__))
2732+
// // Clang-only
27312733
// ::= w # __regcall
27322734
// The 'export' calling conventions are from a bygone era
27332735
// (*cough*Win16*cough*) when functions were declared for export with
@@ -2747,6 +2749,7 @@ void MicrosoftCXXNameMangler::mangleCallingConvention(CallingConv CC) {
27472749
case CC_X86FastCall: Out << 'I'; break;
27482750
case CC_X86VectorCall: Out << 'Q'; break;
27492751
case CC_Swift: Out << 'S'; break;
2752+
case CC_SwiftAsync: Out << 'T'; break;
27502753
case CC_PreserveMost: Out << 'U'; break;
27512754
case CC_X86RegCall: Out << 'w'; break;
27522755
}

clang/lib/AST/Type.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3139,6 +3139,7 @@ StringRef FunctionType::getNameForCallConv(CallingConv CC) {
31393139
case CC_SpirFunction: return "spir_function";
31403140
case CC_OpenCLKernel: return "opencl_kernel";
31413141
case CC_Swift: return "swiftcall";
3142+
case CC_SwiftAsync: return "swiftasynccall";
31423143
case CC_PreserveMost: return "preserve_most";
31433144
case CC_PreserveAll: return "preserve_all";
31443145
}
@@ -3555,6 +3556,7 @@ bool AttributedType::isCallingConv() const {
35553556
case attr::ThisCall:
35563557
case attr::RegCall:
35573558
case attr::SwiftCall:
3559+
case attr::SwiftAsyncCall:
35583560
case attr::VectorCall:
35593561
case attr::AArch64VectorPcs:
35603562
case attr::Pascal:

clang/lib/AST/TypePrinter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,9 @@ void TypePrinter::printFunctionAfter(const FunctionType::ExtInfo &Info,
980980
case CC_Swift:
981981
OS << " __attribute__((swiftcall))";
982982
break;
983+
case CC_SwiftAsync:
984+
OS << "__attribute__((swiftasynccall))";
985+
break;
983986
case CC_PreserveMost:
984987
OS << " __attribute__((preserve_most))";
985988
break;
@@ -1719,6 +1722,7 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
17191722
case attr::StdCall: OS << "stdcall"; break;
17201723
case attr::ThisCall: OS << "thiscall"; break;
17211724
case attr::SwiftCall: OS << "swiftcall"; break;
1725+
case attr::SwiftAsyncCall: OS << "swiftasynccall"; break;
17221726
case attr::VectorCall: OS << "vectorcall"; break;
17231727
case attr::Pascal: OS << "pascal"; break;
17241728
case attr::MSABI: OS << "ms_abi"; break;

clang/lib/Basic/Targets/AArch64.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,8 @@ AArch64TargetInfo::checkCallingConvention(CallingConv CC) const {
586586
case CC_AArch64VectorCall:
587587
case CC_Win64:
588588
return CCCR_OK;
589+
case CC_SwiftAsync:
590+
return checkSwiftAsyncCCSupported();
589591
default:
590592
return CCCR_Warning;
591593
}
@@ -861,6 +863,8 @@ WindowsARM64TargetInfo::checkCallingConvention(CallingConv CC) const {
861863
case CC_Swift:
862864
case CC_Win64:
863865
return CCCR_OK;
866+
case CC_SwiftAsync:
867+
return checkSwiftAsyncCCSupported();
864868
default:
865869
return CCCR_Warning;
866870
}

clang/lib/Basic/Targets/ARM.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,6 +1140,8 @@ ARMTargetInfo::checkCallingConvention(CallingConv CC) const {
11401140
case CC_Swift:
11411141
case CC_OpenCLKernel:
11421142
return CCCR_OK;
1143+
case CC_SwiftAsync:
1144+
return checkSwiftAsyncCCSupported();
11431145
default:
11441146
return CCCR_Warning;
11451147
}
@@ -1218,6 +1220,8 @@ WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const {
12181220
case CC_PreserveAll:
12191221
case CC_Swift:
12201222
return CCCR_OK;
1223+
case CC_SwiftAsync:
1224+
return checkSwiftAsyncCCSupported();
12211225
default:
12221226
return CCCR_Warning;
12231227
}

clang/lib/Basic/Targets/PPC.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,8 @@ class LLVM_LIBRARY_VISIBILITY PPC64TargetInfo : public PPCTargetInfo {
454454
switch (CC) {
455455
case CC_Swift:
456456
return CCCR_OK;
457+
case CC_SwiftAsync:
458+
return checkSwiftAsyncCCSupported();
457459
default:
458460
return CCCR_Warning;
459461
}

clang/lib/Basic/Targets/SystemZ.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo {
143143
case CC_Swift:
144144
case CC_OpenCLKernel:
145145
return CCCR_OK;
146+
case CC_SwiftAsync:
147+
return checkSwiftAsyncCCSupported();
146148
default:
147149
return CCCR_Warning;
148150
}

clang/lib/Basic/Targets/WebAssembly.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyTargetInfo : public TargetInfo {
129129
case CC_C:
130130
case CC_Swift:
131131
return CCCR_OK;
132+
case CC_SwiftAsync:
133+
return checkSwiftAsyncCCSupported();
132134
default:
133135
return CCCR_Warning;
134136
}

clang/lib/Basic/Targets/X86.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,8 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
357357
case CC_IntelOclBicc:
358358
case CC_OpenCLKernel:
359359
return CCCR_OK;
360+
case CC_SwiftAsync:
361+
return checkSwiftAsyncCCSupported();
360362
default:
361363
return CCCR_Warning;
362364
}
@@ -723,6 +725,8 @@ class LLVM_LIBRARY_VISIBILITY X86_64TargetInfo : public X86TargetInfo {
723725
case CC_X86RegCall:
724726
case CC_OpenCLKernel:
725727
return CCCR_OK;
728+
case CC_SwiftAsync:
729+
return checkSwiftAsyncCCSupported();
726730
default:
727731
return CCCR_Warning;
728732
}
@@ -799,6 +803,8 @@ class LLVM_LIBRARY_VISIBILITY WindowsX86_64TargetInfo
799803
case CC_X86RegCall:
800804
case CC_OpenCLKernel:
801805
return CCCR_OK;
806+
case CC_SwiftAsync:
807+
return checkSwiftAsyncCCSupported();
802808
default:
803809
return CCCR_Warning;
804810
}

clang/lib/CodeGen/CGCall.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ unsigned CodeGenTypes::ClangCallConvToLLVMCallConv(CallingConv CC) {
6666
case CC_PreserveMost: return llvm::CallingConv::PreserveMost;
6767
case CC_PreserveAll: return llvm::CallingConv::PreserveAll;
6868
case CC_Swift: return llvm::CallingConv::Swift;
69+
// [FIXME: swiftasynccc] Update to SwiftAsync once LLVM support lands.
70+
case CC_SwiftAsync:
71+
return llvm::CallingConv::Swift;
6972
}
7073
}
7174

@@ -773,7 +776,7 @@ CodeGenTypes::arrangeLLVMFunctionInfo(CanQualType resultType,
773776
// Force target independent argument handling for the host visible
774777
// kernel functions.
775778
computeSPIRKernelABIInfo(CGM, *FI);
776-
} else if (info.getCC() == CC_Swift) {
779+
} else if (info.getCC() == CC_Swift || info.getCC() == CC_SwiftAsync) {
777780
swiftcall::computeABIInfo(CGM, *FI);
778781
} else {
779782
getABIInfo().computeInfo(*FI);
@@ -4035,11 +4038,11 @@ void CodeGenFunction::EmitNonNullArgCheck(RValue RV, QualType ArgType,
40354038
// later, so we can't check it directly.
40364039
static bool hasInAllocaArgs(CodeGenModule &CGM, CallingConv ExplicitCC,
40374040
ArrayRef<QualType> ArgTypes) {
4038-
// The Swift calling convention doesn't go through the target-specific
4039-
// argument classification, so it never uses inalloca.
4041+
// The Swift calling conventions don't go through the target-specific
4042+
// argument classification, they never use inalloca.
40404043
// TODO: Consider limiting inalloca use to only calling conventions supported
40414044
// by MSVC.
4042-
if (ExplicitCC == CC_Swift)
4045+
if (ExplicitCC == CC_Swift || ExplicitCC == CC_SwiftAsync)
40434046
return false;
40444047
if (!CGM.getTarget().getCXXABI().isMicrosoft())
40454048
return false;

clang/lib/CodeGen/CGDebugInfo.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1319,6 +1319,9 @@ static unsigned getDwarfCC(CallingConv CC) {
13191319
return llvm::dwarf::DW_CC_LLVM_OpenCLKernel;
13201320
case CC_Swift:
13211321
return llvm::dwarf::DW_CC_LLVM_Swift;
1322+
case CC_SwiftAsync:
1323+
// [FIXME: swiftasynccc] Update to SwiftAsync once LLVM support lands.
1324+
return llvm::dwarf::DW_CC_LLVM_Swift;
13221325
case CC_PreserveMost:
13231326
return llvm::dwarf::DW_CC_LLVM_PreserveMost;
13241327
case CC_PreserveAll:

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4570,6 +4570,9 @@ static void handleCallConvAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
45704570
case ParsedAttr::AT_SwiftCall:
45714571
D->addAttr(::new (S.Context) SwiftCallAttr(S.Context, AL));
45724572
return;
4573+
case ParsedAttr::AT_SwiftAsyncCall:
4574+
D->addAttr(::new (S.Context) SwiftAsyncCallAttr(S.Context, AL));
4575+
return;
45734576
case ParsedAttr::AT_VectorCall:
45744577
D->addAttr(::new (S.Context) VectorCallAttr(S.Context, AL));
45754578
return;
@@ -4734,6 +4737,9 @@ bool Sema::CheckCallingConvAttr(const ParsedAttr &Attrs, CallingConv &CC,
47344737
case ParsedAttr::AT_SwiftCall:
47354738
CC = CC_Swift;
47364739
break;
4740+
case ParsedAttr::AT_SwiftAsyncCall:
4741+
CC = CC_SwiftAsync;
4742+
break;
47374743
case ParsedAttr::AT_VectorCall:
47384744
CC = CC_X86VectorCall;
47394745
break;
@@ -8110,6 +8116,7 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
81108116
case ParsedAttr::AT_Pascal:
81118117
case ParsedAttr::AT_RegCall:
81128118
case ParsedAttr::AT_SwiftCall:
8119+
case ParsedAttr::AT_SwiftAsyncCall:
81138120
case ParsedAttr::AT_VectorCall:
81148121
case ParsedAttr::AT_MSABI:
81158122
case ParsedAttr::AT_SysVABI:

clang/lib/Sema/SemaType.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ static void diagnoseBadTypeAttribute(Sema &S, const ParsedAttr &attr,
117117
case ParsedAttr::AT_RegCall: \
118118
case ParsedAttr::AT_Pascal: \
119119
case ParsedAttr::AT_SwiftCall: \
120+
case ParsedAttr::AT_SwiftAsyncCall: \
120121
case ParsedAttr::AT_VectorCall: \
121122
case ParsedAttr::AT_AArch64VectorPcs: \
122123
case ParsedAttr::AT_MSABI: \
@@ -2759,13 +2760,16 @@ static void checkExtParameterInfos(Sema &S, ArrayRef<QualType> paramTypes,
27592760
assert(EPI.ExtParameterInfos && "shouldn't get here without param infos");
27602761

27612762
bool hasCheckedSwiftCall = false;
2763+
auto reportWrongABI = [&](unsigned paramIndex) {
2764+
S.Diag(getParamLoc(paramIndex), diag::err_swift_param_attr_not_swiftcall)
2765+
<< getParameterABISpelling(EPI.ExtParameterInfos[paramIndex].getABI());
2766+
};
27622767
auto checkForSwiftCC = [&](unsigned paramIndex) {
27632768
// Only do this once.
27642769
if (hasCheckedSwiftCall) return;
27652770
hasCheckedSwiftCall = true;
27662771
if (EPI.ExtInfo.getCC() == CC_Swift) return;
2767-
S.Diag(getParamLoc(paramIndex), diag::err_swift_param_attr_not_swiftcall)
2768-
<< getParameterABISpelling(EPI.ExtParameterInfos[paramIndex].getABI());
2772+
reportWrongABI(paramIndex);
27692773
};
27702774

27712775
for (size_t paramIndex = 0, numParams = paramTypes.size();
@@ -2791,8 +2795,8 @@ static void checkExtParameterInfos(Sema &S, ArrayRef<QualType> paramTypes,
27912795
checkForSwiftCC(paramIndex);
27922796
continue;
27932797

2798+
// SwiftAsyncContext is not limited to swiftasynccall functions.
27942799
case ParameterABI::SwiftAsyncContext:
2795-
// FIXME: might want to require swiftasynccc when it exists
27962800
continue;
27972801

27982802
// swift_error parameters must be preceded by a swift_context parameter.
@@ -7395,6 +7399,8 @@ static Attr *getCCTypeAttr(ASTContext &Ctx, ParsedAttr &Attr) {
73957399
return createSimpleAttr<PascalAttr>(Ctx, Attr);
73967400
case ParsedAttr::AT_SwiftCall:
73977401
return createSimpleAttr<SwiftCallAttr>(Ctx, Attr);
7402+
case ParsedAttr::AT_SwiftAsyncCall:
7403+
return createSimpleAttr<SwiftAsyncCallAttr>(Ctx, Attr);
73987404
case ParsedAttr::AT_VectorCall:
73997405
return createSimpleAttr<VectorCallAttr>(Ctx, Attr);
74007406
case ParsedAttr::AT_AArch64VectorPcs:

0 commit comments

Comments
 (0)