Add ms_abi and sysv_abi attribute handling.

Based on a patch by Benno Rice!

llvm-svn: 189644
This commit is contained in:
Charles Davis 2013-08-30 04:39:01 +00:00
parent 2bc74c2887
commit b5a214e4f3
17 changed files with 125 additions and 2 deletions

View File

@ -2694,6 +2694,8 @@ enum CXCallingConv {
CXCallingConv_AAPCS_VFP = 7,
CXCallingConv_PnaclCall = 8,
CXCallingConv_IntelOclBicc = 9,
CXCallingConv_X86_64Win64 = 10,
CXCallingConv_X86_64SysV = 11,
CXCallingConv_Invalid = 100,
CXCallingConv_Unexposed = 200

View File

@ -3393,6 +3393,8 @@ public:
attr_pascal,
attr_pnaclcall,
attr_inteloclbicc,
attr_ms_abi,
attr_sysv_abi,
attr_ptr32,
attr_ptr64,
attr_sptr,

View File

@ -426,6 +426,10 @@ def MayAlias : InheritableAttr {
let Spellings = [GNU<"may_alias">, CXX11<"gnu", "may_alias">];
}
def MSABI : InheritableAttr {
let Spellings = [GNU<"ms_abi">, CXX11<"gnu", "ms_abi">];
}
def MSP430Interrupt : InheritableAttr, TargetSpecificAttr {
let Spellings = [];
let Args = [UnsignedArgument<"Number">];
@ -660,6 +664,10 @@ def StdCall : InheritableAttr {
Keyword<"__stdcall">, Keyword<"_stdcall">];
}
def SysVABI : InheritableAttr {
let Spellings = [GNU<"sysv_abi">, CXX11<"gnu", "sysv_abi">];
}
def ThisCall : InheritableAttr {
let Spellings = [GNU<"thiscall">, CXX11<"gnu", "thiscall">,
Keyword<"__thiscall">, Keyword<"_thiscall">];

View File

@ -205,6 +205,8 @@ namespace clang {
CC_X86FastCall, // __attribute__((fastcall))
CC_X86ThisCall, // __attribute__((thiscall))
CC_X86Pascal, // __attribute__((pascal))
CC_X86_64Win64, // __attribute__((ms_abi))
CC_X86_64SysV, // __attribute__((sysv_abi))
CC_AAPCS, // __attribute__((pcs("aapcs")))
CC_AAPCS_VFP, // __attribute__((pcs("aapcs-vfp")))
CC_PnaclCall, // __attribute__((pnaclcall))

View File

@ -920,6 +920,8 @@ struct XMLDumper : public XMLDeclVisitor<XMLDumper>,
case CC_X86StdCall: return set("cc", "x86_stdcall");
case CC_X86ThisCall: return set("cc", "x86_thiscall");
case CC_X86Pascal: return set("cc", "x86_pascal");
case CC_X86_64Win64: return set("cc", "x86_64_win64");
case CC_X86_64SysV: return set("cc", "x86_64_sysv");
case CC_AAPCS: return set("cc", "aapcs");
case CC_AAPCS_VFP: return set("cc", "aapcs_vfp");
case CC_PnaclCall: return set("cc", "pnaclcall");

View File

@ -1394,6 +1394,8 @@ void MicrosoftCXXNameMangler::mangleCallingConvention(const FunctionType *T,
switch (CC) {
default:
llvm_unreachable("Unsupported CC for mangling");
case CC_X86_64Win64:
case CC_X86_64SysV:
case CC_C: Out << 'A'; break;
case CC_X86Pascal: Out << 'C'; break;
case CC_X86ThisCall: Out << 'E'; break;

View File

@ -1568,6 +1568,8 @@ StringRef FunctionType::getNameForCallConv(CallingConv CC) {
case CC_X86FastCall: return "fastcall";
case CC_X86ThisCall: return "thiscall";
case CC_X86Pascal: return "pascal";
case CC_X86_64Win64: return "ms_abi";
case CC_X86_64SysV: return "sysv_abi";
case CC_AAPCS: return "aapcs";
case CC_AAPCS_VFP: return "aapcs-vfp";
case CC_PnaclCall: return "pnaclcall";
@ -1877,6 +1879,8 @@ bool AttributedType::isCallingConv() const {
case attr_stdcall:
case attr_thiscall:
case attr_pascal:
case attr_ms_abi:
case attr_sysv_abi:
case attr_pnaclcall:
case attr_inteloclbicc:
return true;

View File

@ -667,6 +667,12 @@ void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T,
case CC_IntelOclBicc:
OS << " __attribute__((intel_ocl_bicc))";
break;
case CC_X86_64Win64:
OS << " __attribute__((ms_abi))";
break;
case CC_X86_64SysV:
OS << " __attribute__((sysv_abi))";
break;
}
}
@ -1207,6 +1213,8 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
case AttributedType::attr_stdcall: OS << "stdcall"; break;
case AttributedType::attr_thiscall: OS << "thiscall"; 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;
case AttributedType::attr_pcs:
case AttributedType::attr_pcs_vfp: {
OS << "pcs(";

View File

@ -3094,7 +3094,9 @@ public:
}
virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const {
return (CC == CC_C || CC == CC_IntelOclBicc) ? CCCR_OK : CCCR_Warning;
return (CC == CC_C ||
CC == CC_IntelOclBicc ||
CC == CC_X86_64Win64) ? CCCR_OK : CCCR_Warning;
}
virtual CallingConv getDefaultCallingConv(CallingConvMethodType MT) const {
@ -3130,6 +3132,11 @@ public:
virtual BuiltinVaListKind getBuiltinVaListKind() const {
return TargetInfo::CharPtrBuiltinVaList;
}
virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const {
return (CC == CC_C ||
CC == CC_IntelOclBicc ||
CC == CC_X86_64SysV) ? CCCR_OK : CCCR_Warning;
}
};
} // end anonymous namespace

View File

@ -41,6 +41,8 @@ static unsigned ClangCallConvToLLVMCallConv(CallingConv CC) {
case CC_X86StdCall: return llvm::CallingConv::X86_StdCall;
case CC_X86FastCall: return llvm::CallingConv::X86_FastCall;
case CC_X86ThisCall: return llvm::CallingConv::X86_ThisCall;
case CC_X86_64Win64: return llvm::CallingConv::X86_64_Win64;
case CC_X86_64SysV: return llvm::CallingConv::X86_64_SysV;
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;

View File

@ -3950,6 +3950,16 @@ static void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {
PascalAttr(Attr.getRange(), S.Context,
Attr.getAttributeSpellingListIndex()));
return;
case AttributeList::AT_MSABI:
D->addAttr(::new (S.Context)
MSABIAttr(Attr.getRange(), S.Context,
Attr.getAttributeSpellingListIndex()));
return;
case AttributeList::AT_SysVABI:
D->addAttr(::new (S.Context)
SysVABIAttr(Attr.getRange(), S.Context,
Attr.getAttributeSpellingListIndex()));
return;
case AttributeList::AT_Pcs: {
PcsAttr::PCSType PCS;
switch (CC) {
@ -4024,6 +4034,14 @@ 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_MSABI:
CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_C :
CC_X86_64Win64;
break;
case AttributeList::AT_SysVABI:
CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_X86_64SysV :
CC_C;
break;
case AttributeList::AT_Pcs: {
Expr *Arg = attr.getArg(0);
StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
@ -4869,6 +4887,8 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case AttributeList::AT_FastCall:
case AttributeList::AT_ThisCall:
case AttributeList::AT_Pascal:
case AttributeList::AT_MSABI:
case AttributeList::AT_SysVABI:
case AttributeList::AT_Pcs:
case AttributeList::AT_PnaclCall:
case AttributeList::AT_IntelOclBicc:

View File

@ -107,6 +107,8 @@ static void diagnoseBadTypeAttribute(Sema &S, const AttributeList &attr,
case AttributeList::AT_StdCall: \
case AttributeList::AT_ThisCall: \
case AttributeList::AT_Pascal: \
case AttributeList::AT_MSABI: \
case AttributeList::AT_SysVABI: \
case AttributeList::AT_Regparm: \
case AttributeList::AT_Pcs: \
case AttributeList::AT_PnaclCall: \
@ -3405,6 +3407,10 @@ static AttributeList::Kind getAttrListKind(AttributedType::Kind kind) {
return AttributeList::AT_PnaclCall;
case AttributedType::attr_inteloclbicc:
return AttributeList::AT_IntelOclBicc;
case AttributedType::attr_ms_abi:
return AttributeList::AT_MSABI;
case AttributedType::attr_sysv_abi:
return AttributeList::AT_SysVABI;
case AttributedType::attr_ptr32:
return AttributeList::AT_Ptr32;
case AttributedType::attr_ptr64:
@ -4386,6 +4392,10 @@ static AttributedType::Kind getCCTypeAttrKind(AttributeList &Attr) {
return AttributedType::attr_pnaclcall;
case AttributeList::AT_IntelOclBicc:
return AttributedType::attr_inteloclbicc;
case AttributeList::AT_MSABI:
return AttributedType::attr_ms_abi;
case AttributeList::AT_SysVABI:
return AttributedType::attr_sysv_abi;
}
llvm_unreachable("unexpected attribute kind!");
}
@ -4468,7 +4478,7 @@ static bool handleFunctionTypeAttr(TypeProcessingState &state,
CallingConv CCOld = fn->getCallConv();
AttributedType::Kind CCAttrKind = getCCTypeAttrKind(attr);
if (CC != CCOld) {
if (CCOld != CC) {
// Error out on when there's already an attribute on the type
// and the CCs don't match.
const AttributedType *AT = S.getCallingConvAttributedType(type);

View File

@ -0,0 +1,20 @@
// RUN: %clang_cc1 -triple x86_64-unknown-freebsd10.0 -emit-llvm < %s | FileCheck -check-prefix=FREEBSD %s
// RUN: %clang_cc1 -triple x86_64-pc-win32 -emit-llvm < %s | FileCheck -check-prefix=WIN64 %s
void __attribute__((ms_abi)) f1(void);
void __attribute__((sysv_abi)) f2(void);
void f3(void) {
// FREEBSD: define void @f3()
// WIN64: define void @f3()
f1();
// FREEBSD: call x86_64_win64cc void @f1()
// WIN64: call void @f1()
f2();
// FREEBSD: call void @f2()
// WIN64: call x86_64_sysvcc void @f2()
}
// FREEBSD: declare x86_64_win64cc void @f1()
// FREEBSD: declare void @f2()
// WIN64: declare void @f1()
// WIN64: declare x86_64_sysvcc void @f2()

View File

@ -0,0 +1,9 @@
// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-pc-win32 %s
void __attribute__((ms_abi)) foo(void);
void (*pfoo)(void) = foo;
void __attribute__((sysv_abi)) bar(void);
void (*pbar)(void) = bar; // expected-warning{{incompatible pointer types}}
void (__attribute__((sysv_abi)) *pfoo2)(void) = foo; // expected-warning{{incompatible pointer types}}

View File

@ -0,0 +1,9 @@
// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-pc-linux-gnu %s
void __attribute__((ms_abi)) foo(void);
void (*pfoo)(void) = foo; // expected-warning{{incompatible pointer types}}
void __attribute__((sysv_abi)) bar(void);
void (*pbar)(void) = bar;
void (__attribute__((ms_abi)) *pbar2)(void) = bar; // expected-warning{{incompatible pointer types}}

View File

@ -0,0 +1,14 @@
// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-pc-linux-gnu %s
// CC qualifier can be applied only to functions
int __attribute__((ms_abi)) var1; // expected-warning{{'ms_abi' only applies to function types; type here is 'int'}}
int __attribute__((sysv_abi)) var2; // expected-warning{{'sysv_abi' only applies to function types; type here is 'int'}}
// Different CC qualifiers are not compatible
// FIXME: Should say 'sysv_abi' instead of 'cdecl'
void __attribute__((ms_abi, sysv_abi)) foo3(void); // expected-error{{cdecl and ms_abi attributes are not compatible}}
void __attribute__((ms_abi)) foo4(); // expected-note{{previous declaration is here}}
void __attribute__((sysv_abi)) foo4(void); // expected-error{{function declared 'cdecl' here was previously declared 'ms_abi'}}
void bar(int i, int j) __attribute__((ms_abi, cdecl)); // expected-error{{cdecl and ms_abi attributes are not compatible}}
void bar2(int i, int j) __attribute__((sysv_abi, cdecl)); // no-error

View File

@ -509,6 +509,8 @@ CXCallingConv clang_getFunctionTypeCallingConv(CXType X) {
TCALLINGCONV(X86FastCall);
TCALLINGCONV(X86ThisCall);
TCALLINGCONV(X86Pascal);
TCALLINGCONV(X86_64Win64);
TCALLINGCONV(X86_64SysV);
TCALLINGCONV(AAPCS);
TCALLINGCONV(AAPCS_VFP);
TCALLINGCONV(PnaclCall);