forked from OSchip/llvm-project
Add ms_abi and sysv_abi attribute handling.
Based on a patch by Benno Rice! llvm-svn: 189644
This commit is contained in:
parent
2bc74c2887
commit
b5a214e4f3
|
@ -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
|
||||
|
|
|
@ -3393,6 +3393,8 @@ public:
|
|||
attr_pascal,
|
||||
attr_pnaclcall,
|
||||
attr_inteloclbicc,
|
||||
attr_ms_abi,
|
||||
attr_sysv_abi,
|
||||
attr_ptr32,
|
||||
attr_ptr64,
|
||||
attr_sptr,
|
||||
|
|
|
@ -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">];
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(";
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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()
|
||||
|
|
@ -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}}
|
|
@ -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}}
|
|
@ -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
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue