Hi rsmith, majnemer,
Wire it through everywhere we have support for fastcall, essentially.
This allows us to parse the MSVC "14" CTP headers, but we will
miscompile them because LLVM doesn't support __vectorcall yet.
http://reviews.llvm.org/D5808
Files:
include/clang-c/Index.h
include/clang/AST/Type.h
include/clang/Basic/Attr.td
include/clang/Basic/DiagnosticSemaKinds.td
include/clang/Basic/Specifiers.h
include/clang/Basic/TokenKinds.def
lib/AST/Expr.cpp
lib/AST/MicrosoftMangle.cpp
lib/AST/Type.cpp
lib/AST/TypePrinter.cpp
lib/Basic/Targets.cpp
lib/CodeGen/CGCall.cpp
lib/Parse/ParseDecl.cpp
lib/Parse/ParseTentative.cpp
lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclAttr.cpp
lib/Sema/SemaType.cpp
test/CodeGen/microsoft-call-conv.c
test/CodeGen/mrtd.c
test/CodeGenCXX/mangle-ms.cpp
test/Sema/callingconv.c
test/Sema/decl-microsoft-call-conv.c
test/Sema/stdcall-fastcall.c
test/SemaCXX/decl-microsoft-call-conv.cpp
tools/libclang/CXType.cpp
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 = [Undocumented];
}
+def VectorCall : InheritableAttr {
+ let Spellings = [GCC<"vectorcall">, Keyword<"__vectorcall">,
+ Keyword<"_vectorcall">];
+// let Subjects = [Function, ObjCMethod];
+ let Documentation = [Undocumented];
+}
+
def Pascal : InheritableAttr {
let Spellings = [GNU<"pascal">, Keyword<"__pascal">, Keyword<"_pascal">];
// let Subjects = [Function, ObjCMethod];
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<IgnoredAttributes>;
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">,
+ "function with no prototype cannot use the %0 calling convention">,
InGroup<DiagGroup<"missing-prototype-for-cc">>;
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
@@ -557,6 +557,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
@@ -1577,6 +1577,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";
@@ -1912,6 +1913,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
@@ -2088,8 +2088,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
@@ -48,6 +48,8 @@
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 __vectorcall to LLVM.
+ case CC_X86VectorCall: return llvm::CallingConv::C;
}
}
@@ -118,6 +120,9 @@
if (D->hasAttr<ThisCallAttr>())
return CC_X86ThisCall;
+ if (D->hasAttr<VectorCallAttr>())
+ return CC_X86VectorCall;
+
if (D->hasAttr<PascalAttr>())
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;
+ }
}
}
@@ -2877,6 +2890,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;
@@ -4067,6 +4081,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:
@@ -4235,6 +4250,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:
@@ -4458,6 +4474,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
@@ -7941,12 +7941,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<FunctionType>(NewQType);
if (isa<FunctionNoProtoType>(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<FunctionProtoType>(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,27 +20,36 @@
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;
void (__stdcall *pf2)(void) = f2;
void (__thiscall *pf3)(void) = f3;
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 <typename T> void __stdcall StdcallTemplate(T) {}
template <> void StdcallTemplate<int>(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);
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits