Index: include/clang-c/Index.h =================================================================== --- include/clang-c/Index.h +++ include/clang-c/Index.h @@ -2853,6 +2853,7 @@ CXCallingConv_IntelOclBicc = 9, CXCallingConv_X86_64Win64 = 10, CXCallingConv_X86_64SysV = 11, + CXCallingConv_X86VectorCall = 12, CXCallingConv_Invalid = 100, CXCallingConv_Unexposed = 200 Index: include/clang/AST/Type.h =================================================================== --- include/clang/AST/Type.h +++ include/clang/AST/Type.h @@ -3432,6 +3432,7 @@ attr_stdcall, attr_thiscall, attr_pascal, + attr_vectorcall, attr_pnaclcall, attr_inteloclbicc, attr_ms_abi, Index: include/clang/Basic/Attr.td =================================================================== --- include/clang/Basic/Attr.td +++ include/clang/Basic/Attr.td @@ -1167,6 +1167,13 @@ let Documentation = [ThisCallDocs]; } +def VectorCall : InheritableAttr { + let Spellings = [GNU<"vectorcall">, Keyword<"__vectorcall">, + Keyword<"_vectorcall">]; +// let Subjects = [Function, ObjCMethod]; + let Documentation = [VectorCallDocs]; +} + def Pascal : InheritableAttr { let Spellings = [GNU<"pascal">, Keyword<"__pascal">, Keyword<"_pascal">]; // let Subjects = [Function, ObjCMethod]; Index: include/clang/Basic/AttrDocs.td =================================================================== --- include/clang/Basic/AttrDocs.td +++ include/clang/Basic/AttrDocs.td @@ -761,6 +761,32 @@ }]; } +def VectorCallDocs : Documentation { + let Category = DocCatCallingConvs; + let Content = [{ +On 32-bit x86 *and* x86_64 targets, this attribute changes the calling +convention of a function to pass vector parameters in SSE registers. + +On 32-bit x86 targets, this calling convention is similar to ``__fastcall``. +The first two integer parameters are passed in ECX and EDX. Subsequent integer +parameters are passed in memory, and callee clears the stack. On x86_64 +targets, the callee does *not* clear the stack, and integer parameters are +passed in RCX, RDX, R8, and R9 as is done for the default Windows x64 calling +convention. + +On both 32-bit x86 and x86_64 targets, vector and floating point arguments are +passed in XMM0-XMM5. Homogenous vector aggregates of up to four elements are +passed in sequential SSE registers if enough are available. If AVX is enabled, +256 bit vectors are passed in YMM0-YMM5. Any vector or aggregate type that +cannot be passed in registers for any reason is passed by reference, which +allows the caller to align the parameter memory. + +See the documentation for `__vectorcall`_ on MSDN for more details. + +.. _`__vectorcall`: http://msdn.microsoft.com/en-us/library/dn375768.aspx + }]; +} + def DocCatConsumed : DocumentationCategory<"Consumed Annotation Checking"> { let Content = [{ Clang supports additional attributes for checking basic resource management Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -2255,9 +2255,9 @@ def warn_cconv_ignored : Warning< "calling convention %0 ignored for this target">, InGroup; def err_cconv_knr : Error< - "function with no prototype cannot use the callee-cleanup %0 calling convention">; + "function with no prototype cannot use the %0 calling convention">; def warn_cconv_knr : Warning< - "function with no prototype cannot use the callee-cleanup %0 calling convention">, + err_cconv_knr.Text>, InGroup>; def err_cconv_varargs : Error< "variadic function cannot use %0 calling convention">; Index: include/clang/Basic/Specifiers.h =================================================================== --- include/clang/Basic/Specifiers.h +++ include/clang/Basic/Specifiers.h @@ -203,6 +203,7 @@ CC_X86StdCall, // __attribute__((stdcall)) CC_X86FastCall, // __attribute__((fastcall)) CC_X86ThisCall, // __attribute__((thiscall)) + CC_X86VectorCall, // __attribute__((vectorcall)) CC_X86Pascal, // __attribute__((pascal)) CC_X86_64Win64, // __attribute__((ms_abi)) CC_X86_64SysV, // __attribute__((sysv_abi)) @@ -212,16 +213,18 @@ CC_IntelOclBicc // __attribute__((intel_ocl_bicc)) }; - /// \brief Checks whether the given calling convention is callee-cleanup. - inline bool isCalleeCleanup(CallingConv CC) { + /// \brief Checks whether the given calling convention supports variadic + /// calls. Unprototyped calls also use the variadic call rules. + inline bool supportsVariadicCall(CallingConv CC) { switch (CC) { case CC_X86StdCall: case CC_X86FastCall: case CC_X86ThisCall: case CC_X86Pascal: - return true; - default: + case CC_X86VectorCall: return false; + default: + return true; } } Index: include/clang/Basic/TokenKinds.def =================================================================== --- include/clang/Basic/TokenKinds.def +++ include/clang/Basic/TokenKinds.def @@ -457,6 +457,7 @@ KEYWORD(__stdcall , KEYALL) KEYWORD(__fastcall , KEYALL) KEYWORD(__thiscall , KEYALL) +KEYWORD(__vectorcall , KEYALL) KEYWORD(__forceinline , KEYMS) KEYWORD(__unaligned , KEYMS) KEYWORD(__super , KEYMS) @@ -560,6 +561,7 @@ ALIAS("_fastcall" , __fastcall , KEYMS | KEYBORLAND) ALIAS("_stdcall" , __stdcall , KEYMS | KEYBORLAND) ALIAS("_thiscall" , __thiscall , KEYMS) +ALIAS("_vectorcall" , __vectorcall, KEYMS) ALIAS("_uuidof" , __uuidof , KEYMS | KEYBORLAND) ALIAS("_inline" , inline , KEYMS) ALIAS("_declspec" , __declspec , KEYMS) Index: lib/AST/Expr.cpp =================================================================== --- lib/AST/Expr.cpp +++ lib/AST/Expr.cpp @@ -546,6 +546,7 @@ case CC_X86StdCall: POut << "__stdcall "; break; case CC_X86FastCall: POut << "__fastcall "; break; case CC_X86ThisCall: POut << "__thiscall "; break; + case CC_X86VectorCall: POut << "__vectorcall "; break; // Only bother printing the conventions that MSVC knows about. default: break; } Index: lib/AST/MicrosoftMangle.cpp =================================================================== --- lib/AST/MicrosoftMangle.cpp +++ lib/AST/MicrosoftMangle.cpp @@ -1687,6 +1687,7 @@ // ::= H # __export __stdcall // ::= I # __fastcall // ::= J # __export __fastcall + // ::= Q # __vectorcall // The 'export' calling conventions are from a bygone era // (*cough*Win16*cough*) when functions were declared for export with // that keyword. (It didn't actually export them, it just made them so @@ -1703,6 +1704,7 @@ case CC_X86ThisCall: Out << 'E'; break; case CC_X86StdCall: Out << 'G'; break; case CC_X86FastCall: Out << 'I'; break; + case CC_X86VectorCall: Out << 'Q'; break; } } void MicrosoftCXXNameMangler::mangleThrowSpecification( Index: lib/AST/Type.cpp =================================================================== --- lib/AST/Type.cpp +++ lib/AST/Type.cpp @@ -1578,6 +1578,7 @@ case CC_X86FastCall: return "fastcall"; case CC_X86ThisCall: return "thiscall"; case CC_X86Pascal: return "pascal"; + case CC_X86VectorCall: return "vectorcall"; case CC_X86_64Win64: return "ms_abi"; case CC_X86_64SysV: return "sysv_abi"; case CC_AAPCS: return "aapcs"; @@ -1913,6 +1914,7 @@ case attr_fastcall: case attr_stdcall: case attr_thiscall: + case attr_vectorcall: case attr_pascal: case attr_ms_abi: case attr_sysv_abi: Index: lib/AST/TypePrinter.cpp =================================================================== --- lib/AST/TypePrinter.cpp +++ lib/AST/TypePrinter.cpp @@ -673,6 +673,9 @@ case CC_X86ThisCall: OS << " __attribute__((thiscall))"; break; + case CC_X86VectorCall: + OS << " __attribute__((vectorcall))"; + break; case CC_X86Pascal: OS << " __attribute__((pascal))"; break; @@ -1235,6 +1238,7 @@ case AttributedType::attr_fastcall: OS << "fastcall"; break; case AttributedType::attr_stdcall: OS << "stdcall"; break; case AttributedType::attr_thiscall: OS << "thiscall"; break; + case AttributedType::attr_vectorcall: OS << "vectorcall"; break; case AttributedType::attr_pascal: OS << "pascal"; break; case AttributedType::attr_ms_abi: OS << "ms_abi"; break; case AttributedType::attr_sysv_abi: OS << "sysv_abi"; break; Index: lib/Basic/Targets.cpp =================================================================== --- lib/Basic/Targets.cpp +++ lib/Basic/Targets.cpp @@ -2095,8 +2095,9 @@ // We accept all non-ARM calling conventions return (CC == CC_X86ThisCall || CC == CC_X86FastCall || - CC == CC_X86StdCall || - CC == CC_C || + CC == CC_X86StdCall || + CC == CC_X86VectorCall || + CC == CC_C || CC == CC_X86Pascal || CC == CC_IntelOclBicc) ? CCCR_OK : CCCR_Warning; } Index: lib/CodeGen/CGCall.cpp =================================================================== --- lib/CodeGen/CGCall.cpp +++ lib/CodeGen/CGCall.cpp @@ -47,7 +47,10 @@ case CC_AAPCS: return llvm::CallingConv::ARM_AAPCS; case CC_AAPCS_VFP: return llvm::CallingConv::ARM_AAPCS_VFP; case CC_IntelOclBicc: return llvm::CallingConv::Intel_OCL_BI; - // TODO: add support for CC_X86Pascal to llvm + // TODO: Add support for __pascal to LLVM. + case CC_X86Pascal: return llvm::CallingConv::C; + // TODO: Add support for __vectorcall to LLVM. + case CC_X86VectorCall: return llvm::CallingConv::C; } } @@ -118,6 +121,9 @@ if (D->hasAttr()) return CC_X86ThisCall; + if (D->hasAttr()) + return CC_X86VectorCall; + if (D->hasAttr()) return CC_X86Pascal; Index: lib/Parse/ParseDecl.cpp =================================================================== --- lib/Parse/ParseDecl.cpp +++ lib/Parse/ParseDecl.cpp @@ -588,15 +588,28 @@ void Parser::ParseMicrosoftTypeAttributes(ParsedAttributes &attrs) { // Treat these like attributes - while (Tok.is(tok::kw___fastcall) || Tok.is(tok::kw___stdcall) || - Tok.is(tok::kw___thiscall) || Tok.is(tok::kw___cdecl) || - Tok.is(tok::kw___ptr64) || Tok.is(tok::kw___w64) || - Tok.is(tok::kw___ptr32) || Tok.is(tok::kw___unaligned) || - Tok.is(tok::kw___sptr) || Tok.is(tok::kw___uptr)) { - IdentifierInfo *AttrName = Tok.getIdentifierInfo(); - SourceLocation AttrNameLoc = ConsumeToken(); - attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0, - AttributeList::AS_Keyword); + while (true) { + switch (Tok.getKind()) { + case tok::kw___fastcall: + case tok::kw___stdcall: + case tok::kw___thiscall: + case tok::kw___cdecl: + case tok::kw___vectorcall: + case tok::kw___ptr64: + case tok::kw___w64: + case tok::kw___ptr32: + case tok::kw___unaligned: + case tok::kw___sptr: + case tok::kw___uptr: { + IdentifierInfo *AttrName = Tok.getIdentifierInfo(); + SourceLocation AttrNameLoc = ConsumeToken(); + attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0, + AttributeList::AS_Keyword); + break; + } + default: + return; + } } } @@ -2876,6 +2889,7 @@ case tok::kw___stdcall: case tok::kw___fastcall: case tok::kw___thiscall: + case tok::kw___vectorcall: case tok::kw___unaligned: ParseMicrosoftTypeAttributes(DS.getAttributes()); continue; @@ -4066,6 +4080,7 @@ case tok::kw___stdcall: case tok::kw___fastcall: case tok::kw___thiscall: + case tok::kw___vectorcall: case tok::kw___w64: case tok::kw___ptr64: case tok::kw___ptr32: @@ -4234,6 +4249,7 @@ case tok::kw___stdcall: case tok::kw___fastcall: case tok::kw___thiscall: + case tok::kw___vectorcall: case tok::kw___w64: case tok::kw___sptr: case tok::kw___uptr: @@ -4457,6 +4473,7 @@ case tok::kw___stdcall: case tok::kw___fastcall: case tok::kw___thiscall: + case tok::kw___vectorcall: case tok::kw___unaligned: if (AttrReqs & AR_DeclspecAttributesParsed) { ParseMicrosoftTypeAttributes(DS.getAttributes()); Index: lib/Parse/ParseTentative.cpp =================================================================== --- lib/Parse/ParseTentative.cpp +++ lib/Parse/ParseTentative.cpp @@ -837,6 +837,7 @@ Tok.is(tok::kw___stdcall) || Tok.is(tok::kw___fastcall) || Tok.is(tok::kw___thiscall) || + Tok.is(tok::kw___vectorcall) || Tok.is(tok::kw___unaligned)) return TPResult::True; // attributes indicate declaration TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier); @@ -984,6 +985,7 @@ case tok::kw___stdcall: case tok::kw___fastcall: case tok::kw___thiscall: + case tok::kw___vectorcall: case tok::kw___unaligned: case tok::kw___vector: case tok::kw___pixel: @@ -1254,6 +1256,7 @@ case tok::kw___stdcall: case tok::kw___fastcall: case tok::kw___thiscall: + case tok::kw___vectorcall: case tok::kw___w64: case tok::kw___sptr: case tok::kw___uptr: Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -7943,12 +7943,12 @@ // Semantic checking for this function declaration (in isolation). - // Diagnose the use of callee-cleanup calls on unprototyped functions. + // Diagnose calling conventions that don't support variadic calls. QualType NewQType = Context.getCanonicalType(NewFD->getType()); const FunctionType *NewType = cast(NewQType); if (isa(NewType)) { FunctionType::ExtInfo NewTypeInfo = NewType->getExtInfo(); - if (isCalleeCleanup(NewTypeInfo.getCC())) { + if (!supportsVariadicCall(NewTypeInfo.getCC())) { // Windows system headers sometimes accidentally use stdcall without // (void) parameters, so use a default-error warning in this case :-/ int DiagID = NewTypeInfo.getCC() == CC_X86StdCall Index: lib/Sema/SemaDeclAttr.cpp =================================================================== --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -3226,6 +3226,11 @@ PascalAttr(Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex())); return; + case AttributeList::AT_VectorCall: + D->addAttr(::new (S.Context) + VectorCallAttr(Attr.getRange(), S.Context, + Attr.getAttributeSpellingListIndex())); + return; case AttributeList::AT_MSABI: D->addAttr(::new (S.Context) MSABIAttr(Attr.getRange(), S.Context, @@ -3288,6 +3293,7 @@ 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_VectorCall: CC = CC_X86VectorCall; break; case AttributeList::AT_MSABI: CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_C : CC_X86_64Win64; @@ -4529,6 +4535,7 @@ case AttributeList::AT_FastCall: case AttributeList::AT_ThisCall: case AttributeList::AT_Pascal: + case AttributeList::AT_VectorCall: case AttributeList::AT_MSABI: case AttributeList::AT_SysVABI: case AttributeList::AT_Pcs: Index: lib/Sema/SemaType.cpp =================================================================== --- lib/Sema/SemaType.cpp +++ lib/Sema/SemaType.cpp @@ -107,6 +107,7 @@ case AttributeList::AT_StdCall: \ case AttributeList::AT_ThisCall: \ case AttributeList::AT_Pascal: \ + case AttributeList::AT_VectorCall: \ case AttributeList::AT_MSABI: \ case AttributeList::AT_SysVABI: \ case AttributeList::AT_Regparm: \ @@ -3418,6 +3419,8 @@ return AttributeList::AT_ThisCall; case AttributedType::attr_pascal: return AttributeList::AT_Pascal; + case AttributedType::attr_vectorcall: + return AttributeList::AT_VectorCall; case AttributedType::attr_pcs: case AttributedType::attr_pcs_vfp: return AttributeList::AT_Pcs; @@ -4434,6 +4437,8 @@ return AttributedType::attr_thiscall; case AttributeList::AT_Pascal: return AttributedType::attr_pascal; + case AttributeList::AT_VectorCall: + return AttributedType::attr_vectorcall; case AttributeList::AT_Pcs: { // The attribute may have had a fixit applied where we treated an // identifier as a string literal. The contents of the string are valid, @@ -4551,7 +4556,7 @@ } // Diagnose use of callee-cleanup calling convention on variadic functions. - if (isCalleeCleanup(CC)) { + if (!supportsVariadicCall(CC)) { const FunctionProtoType *FnP = dyn_cast(fn); if (FnP && FnP->isVariadic()) { unsigned DiagID = diag::err_cconv_varargs; Index: test/CodeGen/microsoft-call-conv.c =================================================================== --- test/CodeGen/microsoft-call-conv.c +++ test/CodeGen/microsoft-call-conv.c @@ -20,6 +20,12 @@ f3(); // CHECK: call x86_thiscallcc void @f3() } +// FIXME: Add this to LLVM. +void __vectorcall f61(void) { +// CHECK-LABEL: define void @f61() + f3(); +// CHECK: call x86_thiscallcc void @f3() +} // PR5280 void (__fastcall *pf1)(void) = f1; @@ -28,19 +34,22 @@ void (__fastcall *pf4)(void) = f4; void (__stdcall *pf5)(void) = f5; void (__thiscall *pf6)(void) = f6; +void (__vectorcall *pf7)(void) = f61; int main(void) { - f4(); f5(); f6(); + f4(); f5(); f6(); f61(); // CHECK: call x86_fastcallcc void @f4() // CHECK: call x86_stdcallcc void @f5() // CHECK: call x86_thiscallcc void @f6() - pf1(); pf2(); pf3(); pf4(); pf5(); pf6(); + // CHECK: call void @f61() + pf1(); pf2(); pf3(); pf4(); pf5(); pf6(); pf7(); // CHECK: call x86_fastcallcc void %{{.*}}() // CHECK: call x86_stdcallcc void %{{.*}}() // CHECK: call x86_thiscallcc void %{{.*}}() // CHECK: call x86_fastcallcc void %{{.*}}() // CHECK: call x86_stdcallcc void %{{.*}}() // CHECK: call x86_thiscallcc void %{{.*}}() + // CHECK: call void %{{.*}}() return 0; } Index: test/CodeGen/mrtd.c =================================================================== --- test/CodeGen/mrtd.c +++ test/CodeGen/mrtd.c @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -mrtd -triple i386-unknown-unknown -std=c89 -emit-llvm -o - %s 2>&1 | FileCheck %s -// CHECK: mrtd.c:10:3: warning: function with no prototype cannot use the callee-cleanup stdcall calling convention +// CHECK: mrtd.c:10:3: warning: function with no prototype cannot use the stdcall calling convention void baz(int arg); Index: test/CodeGenCXX/mangle-ms.cpp =================================================================== --- test/CodeGenCXX/mangle-ms.cpp +++ test/CodeGenCXX/mangle-ms.cpp @@ -365,3 +365,5 @@ // CHECK-DAG: ??3TypedefNewDelete@@SAXPAX@Z // CHECK-DAG: ??_VTypedefNewDelete@@SAXPAX@Z +void __vectorcall vector_func() { } +// CHECK-DAG: @"\01?vector_func@@YQXXZ" Index: test/Sema/callingconv.c =================================================================== --- test/Sema/callingconv.c +++ test/Sema/callingconv.c @@ -10,7 +10,7 @@ void __attribute__((fastcall(1))) baz(float *a) { // expected-error {{'fastcall' attribute takes no arguments}} } -void __attribute__((fastcall)) test0() { // expected-error {{function with no prototype cannot use the callee-cleanup fastcall calling convention}} +void __attribute__((fastcall)) test0() { // expected-error {{function with no prototype cannot use the fastcall calling convention}} } void __attribute__((fastcall)) test1(void) { Index: test/Sema/decl-microsoft-call-conv.c =================================================================== --- test/Sema/decl-microsoft-call-conv.c +++ test/Sema/decl-microsoft-call-conv.c @@ -11,11 +11,14 @@ void __thiscall CrcGenerateTableThiscall() {} void __pascal CrcGenerateTablePascal(void); void __pascal CrcGenerateTablePascal() {} +void __vectorcall CrcGenerateTableVectorcall(void); +void __vectorcall CrcGenerateTableVectorcall() {} -void __fastcall CrcGenerateTableNoProtoFastcall() {} // expected-error{{function with no prototype cannot use the callee-cleanup fastcall calling convention}} -void __stdcall CrcGenerateTableNoProtoStdcall() {} // expected-warning{{function with no prototype cannot use the callee-cleanup stdcall calling convention}} -void __thiscall CrcGenerateTableNoProtoThiscall() {} // expected-error{{function with no prototype cannot use the callee-cleanup thiscall calling convention}} -void __pascal CrcGenerateTableNoProtoPascal() {} // expected-error{{function with no prototype cannot use the callee-cleanup pascal calling convention}} +void __fastcall CrcGenerateTableNoProtoFastcall() {} // expected-error{{function with no prototype cannot use the fastcall calling convention}} +void __stdcall CrcGenerateTableNoProtoStdcall() {} // expected-warning{{function with no prototype cannot use the stdcall calling convention}} +void __thiscall CrcGenerateTableNoProtoThiscall() {} // expected-error{{function with no prototype cannot use the thiscall calling convention}} +void __pascal CrcGenerateTableNoProtoPascal() {} // expected-error{{function with no prototype cannot use the pascal calling convention}} +void __vectorcall CrcGenerateTableNoProtoVectorcall() {} // expected-error{{function with no prototype cannot use the vectorcall calling convention}} // Regular calling convention is fine. void CrcGenerateTableNoProto() {} Index: test/Sema/stdcall-fastcall.c =================================================================== --- test/Sema/stdcall-fastcall.c +++ test/Sema/stdcall-fastcall.c @@ -6,7 +6,7 @@ // Different CC qualifiers are not compatible void __attribute__((stdcall, fastcall)) foo3(void); // expected-error{{fastcall and stdcall attributes are not compatible}} -void __attribute__((stdcall)) foo4(); // expected-note{{previous declaration is here}} expected-warning{{function with no prototype cannot use the callee-cleanup stdcall calling convention}} +void __attribute__((stdcall)) foo4(); // expected-note{{previous declaration is here}} expected-warning{{function with no prototype cannot use the stdcall calling convention}} void __attribute__((fastcall)) foo4(void); // expected-error{{function declared 'fastcall' here was previously declared 'stdcall'}} // rdar://8876096 Index: test/SemaCXX/decl-microsoft-call-conv.cpp =================================================================== --- test/SemaCXX/decl-microsoft-call-conv.cpp +++ test/SemaCXX/decl-microsoft-call-conv.cpp @@ -10,6 +10,7 @@ void __cdecl free_func_cdecl(); // expected-note 2 {{previous declaration is here}} void __stdcall free_func_stdcall(); // expected-note 2 {{previous declaration is here}} void __fastcall free_func_fastcall(); // expected-note 2 {{previous declaration is here}} +void __vectorcall free_func_vectorcall(); // expected-note 2 {{previous declaration is here}} void __cdecl free_func_default(); void __stdcall free_func_default(); // expected-error {{function declared 'stdcall' here was previously declared without calling convention}} @@ -27,6 +28,10 @@ void __stdcall free_func_fastcall(); // expected-error {{function declared 'stdcall' here was previously declared 'fastcall'}} void free_func_fastcall(); +void __cdecl free_func_vectorcall(); // expected-error {{function declared 'cdecl' here was previously declared 'vectorcall'}} +void __stdcall free_func_vectorcall(); // expected-error {{function declared 'stdcall' here was previously declared 'vectorcall'}} +void free_func_vectorcall(); + // Overloaded functions may have different calling conventions void __fastcall free_func_default(int); void __cdecl free_func_default(int *); @@ -45,6 +50,8 @@ void __cdecl member_cdecl2(); // expected-note {{previous declaration is here}} void __thiscall member_thiscall1(); void __thiscall member_thiscall2(); // expected-note {{previous declaration is here}} + void __vectorcall member_vectorcall1(); + void __vectorcall member_vectorcall2(); // expected-note {{previous declaration is here}} // Typedefs carrying the __cdecl convention are adjusted to __thiscall. void_fun_t member_typedef_default; // expected-note {{previous declaration is here}} @@ -83,6 +90,9 @@ void S::member_thiscall1() {} void __cdecl S::member_thiscall2() {} // expected-error {{function declared 'cdecl' here was previously declared 'thiscall'}} +void S::member_vectorcall1() {} +void __cdecl S::member_vectorcall2() {} // expected-error {{function declared 'cdecl' here was previously declared 'vectorcall'}} + void S::static_member_default1() {} void __cdecl S::static_member_default2() {} void __stdcall S::static_member_default3() {} // expected-error {{function declared 'stdcall' here was previously declared without calling convention}} @@ -143,9 +153,10 @@ void multi_attribute(int x) { __builtin_unreachable(); } +// expected-error@+3 {{vectorcall and cdecl attributes are not compatible}} // expected-error@+2 {{stdcall and cdecl attributes are not compatible}} // expected-error@+1 {{fastcall and cdecl attributes are not compatible}} -void __cdecl __cdecl __stdcall __cdecl __fastcall multi_cc(int x); +void __cdecl __cdecl __stdcall __cdecl __fastcall __vectorcall multi_cc(int x); template void __stdcall StdcallTemplate(T) {} template <> void StdcallTemplate(int) {} Index: tools/libclang/CXType.cpp =================================================================== --- tools/libclang/CXType.cpp +++ tools/libclang/CXType.cpp @@ -520,6 +520,7 @@ TCALLINGCONV(X86FastCall); TCALLINGCONV(X86ThisCall); TCALLINGCONV(X86Pascal); + TCALLINGCONV(X86VectorCall); TCALLINGCONV(X86_64Win64); TCALLINGCONV(X86_64SysV); TCALLINGCONV(AAPCS);