3 changes: 3 additions & 0 deletions clang/lib/AST/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2655,6 +2655,7 @@ StringRef FunctionType::getNameForCallConv(CallingConv CC) {
case CC_IntelOclBicc: return "intel_ocl_bicc";
case CC_SpirFunction: return "spir_function";
case CC_SpirKernel: return "spir_kernel";
case CC_Swift: return "swiftcall";
}

llvm_unreachable("Invalid calling convention.");
Expand Down Expand Up @@ -2995,6 +2996,7 @@ bool AttributedType::isQualifier() const {
case AttributedType::attr_stdcall:
case AttributedType::attr_thiscall:
case AttributedType::attr_pascal:
case AttributedType::attr_swiftcall:
case AttributedType::attr_vectorcall:
case AttributedType::attr_inteloclbicc:
case AttributedType::attr_ms_abi:
Expand Down Expand Up @@ -3048,6 +3050,7 @@ bool AttributedType::isCallingConv() const {
case attr_fastcall:
case attr_stdcall:
case attr_thiscall:
case attr_swiftcall:
case attr_vectorcall:
case attr_pascal:
case attr_ms_abi:
Expand Down
20 changes: 20 additions & 0 deletions clang/lib/AST/TypePrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,20 @@ void TypePrinter::printFunctionProtoBefore(const FunctionProtoType *T,
}
}

llvm::StringRef clang::getParameterABISpelling(ParameterABI ABI) {
switch (ABI) {
case ParameterABI::Ordinary:
llvm_unreachable("asking for spelling of ordinary parameter ABI");
case ParameterABI::SwiftContext:
return "swift_context";
case ParameterABI::SwiftErrorResult:
return "swift_error_result";
case ParameterABI::SwiftIndirectResult:
return "swift_indirect_result";
}
llvm_unreachable("bad parameter ABI kind");
}

void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T,
raw_ostream &OS) {
// If needed for precedence reasons, wrap the inner part in grouping parens.
Expand All @@ -644,6 +658,9 @@ void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T,

auto EPI = T->getExtParameterInfo(i);
if (EPI.isConsumed()) OS << "__attribute__((ns_consumed)) ";
auto ABI = EPI.getABI();
if (ABI != ParameterABI::Ordinary)
OS << "__attribute__((" << getParameterABISpelling(ABI) << ")) ";

print(T->getParamType(i), OS, StringRef());
}
Expand Down Expand Up @@ -707,6 +724,8 @@ void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T,
case CC_SpirKernel:
// Do nothing. These CCs are not available as attributes.
break;
case CC_Swift:
OS << " __attribute__((swiftcall))";
}
}

Expand Down Expand Up @@ -1309,6 +1328,7 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
case AttributedType::attr_fastcall: OS << "fastcall"; break;
case AttributedType::attr_stdcall: OS << "stdcall"; break;
case AttributedType::attr_thiscall: OS << "thiscall"; break;
case AttributedType::attr_swiftcall: OS << "swiftcall"; break;
case AttributedType::attr_vectorcall: OS << "vectorcall"; break;
case AttributedType::attr_pascal: OS << "pascal"; break;
case AttributedType::attr_ms_abi: OS << "ms_abi"; break;
Expand Down
55 changes: 42 additions & 13 deletions clang/lib/Basic/Targets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2561,14 +2561,20 @@ class X86TargetInfo : public TargetInfo {
bool setFPMath(StringRef Name) override;

CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
// We accept all non-ARM calling conventions
return (CC == CC_X86ThisCall ||
CC == CC_X86FastCall ||
CC == CC_X86StdCall ||
CC == CC_X86VectorCall ||
CC == CC_C ||
CC == CC_X86Pascal ||
CC == CC_IntelOclBicc) ? CCCR_OK : CCCR_Warning;
// Most of the non-ARM calling conventions are i386 conventions.
switch (CC) {
case CC_X86ThisCall:
case CC_X86FastCall:
case CC_X86StdCall:
case CC_X86VectorCall:
case CC_C:
case CC_Swift:
case CC_X86Pascal:
case CC_IntelOclBicc:
return CCCR_OK;
default:
return CCCR_Warning;
}
}

CallingConv getDefaultCallingConv(CallingConvMethodType MT) const override {
Expand Down Expand Up @@ -4111,10 +4117,16 @@ class X86_64TargetInfo : public X86TargetInfo {
}

CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
return (CC == CC_C ||
CC == CC_X86VectorCall ||
CC == CC_IntelOclBicc ||
CC == CC_X86_64Win64) ? CCCR_OK : CCCR_Warning;
switch (CC) {
case CC_C:
case CC_Swift:
case CC_X86VectorCall:
case CC_IntelOclBicc:
case CC_X86_64Win64:
return CCCR_OK;
default:
return CCCR_Warning;
}
}

CallingConv getDefaultCallingConv(CallingConvMethodType MT) const override {
Expand Down Expand Up @@ -5095,7 +5107,14 @@ class ARMTargetInfo : public TargetInfo {
}

CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
return (CC == CC_AAPCS || CC == CC_AAPCS_VFP) ? CCCR_OK : CCCR_Warning;
switch (CC) {
case CC_AAPCS:
case CC_AAPCS_VFP:
case CC_Swift:
return CCCR_OK;
default:
return CCCR_Warning;
}
}

int getEHDataRegisterNumber(unsigned RegNo) const override {
Expand Down Expand Up @@ -5547,6 +5566,16 @@ class AArch64TargetInfo : public TargetInfo {
return true;
}

CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
switch (CC) {
case CC_C:
case CC_Swift:
return CCCR_OK;
default:
return CCCR_Warning;
}
}

bool isCLZForZeroUndef() const override { return false; }

BuiltinVaListKind getBuiltinVaListKind() const override {
Expand Down
106 changes: 106 additions & 0 deletions clang/lib/Sema/SemaDeclAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3728,6 +3728,11 @@ static void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {
PascalAttr(Attr.getRange(), S.Context,
Attr.getAttributeSpellingListIndex()));
return;
case AttributeList::AT_SwiftCall:
D->addAttr(::new (S.Context)
SwiftCallAttr(Attr.getRange(), S.Context,
Attr.getAttributeSpellingListIndex()));
return;
case AttributeList::AT_VectorCall:
D->addAttr(::new (S.Context)
VectorCallAttr(Attr.getRange(), S.Context,
Expand Down Expand Up @@ -3795,6 +3800,7 @@ bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC,
case AttributeList::AT_StdCall: CC = CC_X86StdCall; break;
case AttributeList::AT_ThisCall: CC = CC_X86ThisCall; break;
case AttributeList::AT_Pascal: CC = CC_X86Pascal; break;
case AttributeList::AT_SwiftCall: CC = CC_Swift; break;
case AttributeList::AT_VectorCall: CC = CC_X86VectorCall; break;
case AttributeList::AT_MSABI:
CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_C :
Expand Down Expand Up @@ -3845,6 +3851,96 @@ bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC,
return false;
}

/// Pointer-like types in the default address space.
static bool isValidSwiftContextType(QualType type) {
if (!type->hasPointerRepresentation())
return type->isDependentType();
return type->getPointeeType().getAddressSpace() == 0;
}

/// Pointers and references in the default address space.
static bool isValidSwiftIndirectResultType(QualType type) {
if (auto ptrType = type->getAs<PointerType>()) {
type = ptrType->getPointeeType();
} else if (auto refType = type->getAs<ReferenceType>()) {
type = refType->getPointeeType();
} else {
return type->isDependentType();
}
return type.getAddressSpace() == 0;
}

/// Pointers and references to pointers in the default address space.
static bool isValidSwiftErrorResultType(QualType type) {
if (auto ptrType = type->getAs<PointerType>()) {
type = ptrType->getPointeeType();
} else if (auto refType = type->getAs<ReferenceType>()) {
type = refType->getPointeeType();
} else {
return type->isDependentType();
}
if (!type.getQualifiers().empty())
return false;
return isValidSwiftContextType(type);
}

static void handleParameterABIAttr(Sema &S, Decl *D, const AttributeList &attr,
ParameterABI abi) {
S.AddParameterABIAttr(attr.getRange(), D, abi,
attr.getAttributeSpellingListIndex());
}

void Sema::AddParameterABIAttr(SourceRange range, Decl *D, ParameterABI abi,
unsigned spellingIndex) {

QualType type = cast<ParmVarDecl>(D)->getType();

if (auto existingAttr = D->getAttr<ParameterABIAttr>()) {
if (existingAttr->getABI() != abi) {
Diag(range.getBegin(), diag::err_attributes_are_not_compatible)
<< getParameterABISpelling(abi) << existingAttr;
Diag(existingAttr->getLocation(), diag::note_conflicting_attribute);
return;
}
}

switch (abi) {
case ParameterABI::Ordinary:
llvm_unreachable("explicit attribute for ordinary parameter ABI?");

case ParameterABI::SwiftContext:
if (!isValidSwiftContextType(type)) {
Diag(range.getBegin(), diag::err_swift_abi_parameter_wrong_type)
<< getParameterABISpelling(abi)
<< /*pointer to pointer */ 0 << type;
}
D->addAttr(::new (Context)
SwiftContextAttr(range, Context, spellingIndex));
return;

case ParameterABI::SwiftErrorResult:
if (!isValidSwiftErrorResultType(type)) {
Diag(range.getBegin(), diag::err_swift_abi_parameter_wrong_type)
<< getParameterABISpelling(abi)
<< /*pointer to pointer */ 1 << type;
}
D->addAttr(::new (Context)
SwiftErrorResultAttr(range, Context, spellingIndex));
return;

case ParameterABI::SwiftIndirectResult:
if (!isValidSwiftIndirectResultType(type)) {
Diag(range.getBegin(), diag::err_swift_abi_parameter_wrong_type)
<< getParameterABISpelling(abi)
<< /*pointer*/ 0 << type;
}
D->addAttr(::new (Context)
SwiftIndirectResultAttr(range, Context, spellingIndex));
return;
}
llvm_unreachable("bad parameter ABI attribute");
}

/// Checks a regparm attribute, returning true if it is ill-formed and
/// otherwise setting numParams to the appropriate value.
bool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) {
Expand Down Expand Up @@ -5484,6 +5580,7 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case AttributeList::AT_FastCall:
case AttributeList::AT_ThisCall:
case AttributeList::AT_Pascal:
case AttributeList::AT_SwiftCall:
case AttributeList::AT_VectorCall:
case AttributeList::AT_MSABI:
case AttributeList::AT_SysVABI:
Expand All @@ -5497,6 +5594,15 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case AttributeList::AT_OpenCLAccess:
handleOpenCLAccessAttr(S, D, Attr);
break;
case AttributeList::AT_SwiftContext:
handleParameterABIAttr(S, D, Attr, ParameterABI::SwiftContext);
break;
case AttributeList::AT_SwiftErrorResult:
handleParameterABIAttr(S, D, Attr, ParameterABI::SwiftErrorResult);
break;
case AttributeList::AT_SwiftIndirectResult:
handleParameterABIAttr(S, D, Attr, ParameterABI::SwiftIndirectResult);
break;
case AttributeList::AT_InternalLinkage:
handleInternalLinkageAttr(S, D, Attr);
break;
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,12 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
}
}

if (auto ABIAttr = dyn_cast<ParameterABIAttr>(TmplAttr)) {
AddParameterABIAttr(ABIAttr->getRange(), New, ABIAttr->getABI(),
ABIAttr->getSpellingListIndex());
continue;
}

if (isa<NSConsumedAttr>(TmplAttr) || isa<CFConsumedAttr>(TmplAttr)) {
AddNSConsumedAttr(TmplAttr->getRange(), New,
TmplAttr->getSpellingListIndex(),
Expand Down
89 changes: 88 additions & 1 deletion clang/lib/Sema/SemaType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ static void diagnoseBadTypeAttribute(Sema &S, const AttributeList &attr,
case AttributeList::AT_StdCall: \
case AttributeList::AT_ThisCall: \
case AttributeList::AT_Pascal: \
case AttributeList::AT_SwiftCall: \
case AttributeList::AT_VectorCall: \
case AttributeList::AT_MSABI: \
case AttributeList::AT_SysVABI: \
Expand Down Expand Up @@ -2268,6 +2269,74 @@ bool Sema::CheckFunctionReturnType(QualType T, SourceLocation Loc) {
return false;
}

/// Check the extended parameter information. Most of the necessary
/// checking should occur when applying the parameter attribute; the
/// only other checks required are positional restrictions.
static void checkExtParameterInfos(Sema &S, ArrayRef<QualType> paramTypes,
const FunctionProtoType::ExtProtoInfo &EPI,
llvm::function_ref<SourceLocation(unsigned)> getParamLoc) {
assert(EPI.ExtParameterInfos && "shouldn't get here without param infos");

bool hasCheckedSwiftCall = false;
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());
};

for (size_t paramIndex = 0, numParams = paramTypes.size();
paramIndex != numParams; ++paramIndex) {
switch (EPI.ExtParameterInfos[paramIndex].getABI()) {
// Nothing interesting to check for orindary-ABI parameters.
case ParameterABI::Ordinary:
continue;

// swift_indirect_result parameters must be a prefix of the function
// arguments.
case ParameterABI::SwiftIndirectResult:
checkForSwiftCC(paramIndex);
if (paramIndex != 0 &&
EPI.ExtParameterInfos[paramIndex - 1].getABI()
!= ParameterABI::SwiftIndirectResult) {
S.Diag(getParamLoc(paramIndex),
diag::err_swift_indirect_result_not_first);
}
continue;

// swift_context parameters must be the last parameter except for
// a possible swift_error parameter.
case ParameterABI::SwiftContext:
checkForSwiftCC(paramIndex);
if (!(paramIndex == numParams - 1 ||
(paramIndex == numParams - 2 &&
EPI.ExtParameterInfos[numParams - 1].getABI()
== ParameterABI::SwiftErrorResult))) {
S.Diag(getParamLoc(paramIndex),
diag::err_swift_context_not_before_swift_error_result);
}
continue;

// swift_error parameters must be the last parameter.
case ParameterABI::SwiftErrorResult:
checkForSwiftCC(paramIndex);
if (paramIndex != numParams - 1) {
S.Diag(getParamLoc(paramIndex),
diag::err_swift_error_result_not_last);
} else if (paramIndex == 0 ||
EPI.ExtParameterInfos[paramIndex - 1].getABI()
!= ParameterABI::SwiftContext) {
S.Diag(getParamLoc(paramIndex),
diag::err_swift_error_result_not_after_swift_context);
}
continue;
}
llvm_unreachable("bad ABI kind");
}
}

QualType Sema::BuildFunctionType(QualType T,
MutableArrayRef<QualType> ParamTypes,
SourceLocation Loc, DeclarationName Entity,
Expand All @@ -2292,6 +2361,11 @@ QualType Sema::BuildFunctionType(QualType T,
ParamTypes[Idx] = ParamType;
}

if (EPI.ExtParameterInfos) {
checkExtParameterInfos(*this, ParamTypes, EPI,
[=](unsigned i) { return Loc; });
}

if (Invalid)
return QualType();

Expand Down Expand Up @@ -4071,11 +4145,20 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
HasAnyInterestingExtParameterInfos = true;
}

if (auto attr = Param->getAttr<ParameterABIAttr>()) {
ExtParameterInfos[i] =
ExtParameterInfos[i].withABI(attr->getABI());
HasAnyInterestingExtParameterInfos = true;
}

ParamTys.push_back(ParamTy);
}

if (HasAnyInterestingExtParameterInfos)
if (HasAnyInterestingExtParameterInfos) {
EPI.ExtParameterInfos = ExtParameterInfos.data();
checkExtParameterInfos(S, ParamTys, EPI,
[&](unsigned i) { return FTI.Params[i].Param->getLocation(); });
}

SmallVector<QualType, 4> Exceptions;
SmallVector<ParsedType, 2> DynamicExceptions;
Expand Down Expand Up @@ -4534,6 +4617,8 @@ static AttributeList::Kind getAttrListKind(AttributedType::Kind kind) {
return AttributeList::AT_ThisCall;
case AttributedType::attr_pascal:
return AttributeList::AT_Pascal;
case AttributedType::attr_swiftcall:
return AttributeList::AT_SwiftCall;
case AttributedType::attr_vectorcall:
return AttributeList::AT_VectorCall;
case AttributedType::attr_pcs:
Expand Down Expand Up @@ -5857,6 +5942,8 @@ static AttributedType::Kind getCCTypeAttrKind(AttributeList &Attr) {
return AttributedType::attr_thiscall;
case AttributeList::AT_Pascal:
return AttributedType::attr_pascal;
case AttributeList::AT_SwiftCall:
return AttributedType::attr_swiftcall;
case AttributeList::AT_VectorCall:
return AttributedType::attr_vectorcall;
case AttributeList::AT_Pcs: {
Expand Down
30 changes: 30 additions & 0 deletions clang/test/Sema/attr-swiftcall.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify %s

#define SWIFTCALL __attribute__((swiftcall))
#define INDIRECT_RESULT __attribute__((swift_indirect_result))
#define ERROR_RESULT __attribute__((swift_error_result))
#define CONTEXT __attribute__((swift_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}}
void unprototyped() SWIFTCALL; // expected-error {{function with no prototype cannot use the swiftcall calling convention}}
void multiple_ccs(int x) SWIFTCALL __attribute__((vectorcall)); // expected-error {{vectorcall and swiftcall attributes are not compatible}}
void (*functionPointer)(void) SWIFTCALL;

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}}
void indirect_result_bad_type(INDIRECT_RESULT int out) SWIFTCALL; // expected-error {{'swift_indirect_result' parameter must have pointer type; type here is 'int'}}
void indirect_result_single(INDIRECT_RESULT void *out) SWIFTCALL;
void indirect_result_multiple(INDIRECT_RESULT void *out1, INDIRECT_RESULT void *out2) SWIFTCALL;

void error_result_nonswift(ERROR_RESULT void **error); // expected-error {{'swift_error_result' parameter can only be used with swiftcall calling convention}} expected-error{{'swift_error_result' parameter must follow 'swift_context' parameter}}
void error_result_bad_position(ERROR_RESULT void **error, int last) SWIFTCALL; // expected-error {{'swift_error_result' parameter must be last parameter of function}}
void error_result_bad_position2(int first, ERROR_RESULT void **error) SWIFTCALL; // expected-error {{'swift_error_result' parameter must follow 'swift_context' parameter}}
void error_result_bad_type(CONTEXT void *context, ERROR_RESULT int error) SWIFTCALL; // expected-error {{'swift_error_result' parameter must have pointer to unqualified pointer type; type here is 'int'}}
void error_result_bad_type2(CONTEXT void *context, ERROR_RESULT int *error) SWIFTCALL; // expected-error {{'swift_error_result' parameter must have pointer to unqualified pointer type; type here is 'int *'}}
void error_result_okay(int a, int b, CONTEXT void *context, ERROR_RESULT void **error) SWIFTCALL;

void context_nonswift(CONTEXT void *context); // expected-error {{'swift_context' parameter can only be used with swiftcall calling convention}}
void context_bad_position(CONTEXT void *context, int x) SWIFTCALL; // expected-error {{'swift_context' parameter can only be followed by 'swift_error_result' parameter}}
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;
37 changes: 37 additions & 0 deletions clang/test/SemaCXX/attr-swiftcall.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify %s

#define SWIFTCALL __attribute__((swiftcall))
#define INDIRECT_RESULT __attribute__((swift_indirect_result))
#define ERROR_RESULT __attribute__((swift_error_result))
#define CONTEXT __attribute__((swift_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}}
void multiple_ccs(int x) SWIFTCALL __attribute__((vectorcall)); // expected-error {{vectorcall and swiftcall attributes are not compatible}}
void (*functionPointer)(void) SWIFTCALL;

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}}
void indirect_result_bad_type(INDIRECT_RESULT int out) SWIFTCALL; // expected-error {{'swift_indirect_result' parameter must have pointer type; type here is 'int'}}
void indirect_result_single(INDIRECT_RESULT void *out) SWIFTCALL;
void indirect_result_multiple(INDIRECT_RESULT void *out1, INDIRECT_RESULT void *out2) SWIFTCALL;

void error_result_nonswift(ERROR_RESULT void **error); // expected-error {{'swift_error_result' parameter can only be used with swiftcall calling convention}} expected-error{{'swift_error_result' parameter must follow 'swift_context' parameter}}
void error_result_bad_position(ERROR_RESULT void **error, int last) SWIFTCALL; // expected-error {{'swift_error_result' parameter must be last parameter of function}}
void error_result_bad_position2(int first, ERROR_RESULT void **error) SWIFTCALL; // expected-error {{'swift_error_result' parameter must follow 'swift_context' parameter}}
void error_result_bad_type(CONTEXT void *context, ERROR_RESULT int error) SWIFTCALL; // expected-error {{'swift_error_result' parameter must have pointer to unqualified pointer type; type here is 'int'}}
void error_result_bad_type2(CONTEXT void *context, ERROR_RESULT int *error) SWIFTCALL; // expected-error {{'swift_error_result' parameter must have pointer to unqualified pointer type; type here is 'int *'}}
void error_result_okay(int a, int b, CONTEXT void *context, ERROR_RESULT void **error) SWIFTCALL;

void context_nonswift(CONTEXT void *context); // expected-error {{'swift_context' parameter can only be used with swiftcall calling convention}}
void context_bad_position(CONTEXT void *context, int x) SWIFTCALL; // expected-error {{'swift_context' parameter can only be followed by 'swift_error_result' parameter}}
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;

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) {
indirect_result_temp_okay1(out);
indirect_result_temp_okay2(out);
indirect_result_temp_okay2(1); // expected-error {{no matching function for call to 'indirect_result_temp_okay2'}}
}
1 change: 1 addition & 0 deletions clang/tools/libclang/CXType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,7 @@ CXCallingConv clang_getFunctionTypeCallingConv(CXType X) {
TCALLINGCONV(AAPCS);
TCALLINGCONV(AAPCS_VFP);
TCALLINGCONV(IntelOclBicc);
TCALLINGCONV(Swift);
case CC_SpirFunction: return CXCallingConv_Unexposed;
case CC_SpirKernel: return CXCallingConv_Unexposed;
break;
Expand Down
3 changes: 2 additions & 1 deletion clang/utils/TableGen/ClangAttrEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1762,7 +1762,8 @@ namespace {
static const AttrClassDescriptor AttrClassDescriptors[] = {
{ "ATTR", "Attr" },
{ "INHERITABLE_ATTR", "InheritableAttr" },
{ "INHERITABLE_PARAM_ATTR", "InheritableParamAttr" }
{ "INHERITABLE_PARAM_ATTR", "InheritableParamAttr" },
{ "PARAMETER_ABI_ATTR", "ParameterABIAttr" }
};

static void emitDefaultDefine(raw_ostream &OS, StringRef name,
Expand Down