summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/TargetInfo.cpp
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2014-01-31 22:54:50 +0000
committerReid Kleckner <reid@kleckner.net>2014-01-31 22:54:50 +0000
commit4982b82b739199de64e852b114cd70b65a29cf8c (patch)
tree5294c690c21731953b26695fdb6032f74394b17c /clang/lib/CodeGen/TargetInfo.cpp
parent394e34f5c2ed7d33b81dc3abdc7687af0b7ceb1a (diff)
downloadbcm5719-llvm-4982b82b739199de64e852b114cd70b65a29cf8c.tar.gz
bcm5719-llvm-4982b82b739199de64e852b114cd70b65a29cf8c.zip
[ms-cxxabi] Use x86_cdeclmethodcc for __cdecl methods on win32
This fixes PR15768, where the sret parameter and the 'this' parameter are in the wrong order. Instance methods compiled by MSVC never return records in registers, they always return indirectly through an sret pointer. That sret pointer always comes after the 'this' parameter, for both __cdecl and __thiscall methods. Unfortunately, the same is true for other calling conventions, so we'll have to change the overall approach here relatively soon. Reviewers: rsmith Differential Revision: http://llvm-reviews.chandlerc.com/D2664 llvm-svn: 200587
Diffstat (limited to 'clang/lib/CodeGen/TargetInfo.cpp')
-rw-r--r--clang/lib/CodeGen/TargetInfo.cpp39
1 files changed, 22 insertions, 17 deletions
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp
index c538234d009..bf968f34815 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -552,8 +552,8 @@ class X86_32ABIInfo : public ABIInfo {
return (Size == 8 || Size == 16 || Size == 32 || Size == 64);
}
- static bool shouldReturnTypeInRegister(QualType Ty, ASTContext &Context,
- unsigned callingConvention);
+ bool shouldReturnTypeInRegister(QualType Ty, ASTContext &Context,
+ bool IsInstanceMethod) const;
/// getIndirectResult - Give a source type \arg Ty, return a suitable result
/// such that the argument will be passed in memory.
@@ -565,7 +565,8 @@ class X86_32ABIInfo : public ABIInfo {
unsigned getTypeStackAlignInBytes(QualType Ty, unsigned Align) const;
Class classify(QualType Ty) const;
- ABIArgInfo classifyReturnType(QualType RetTy, CCState &State) const;
+ ABIArgInfo classifyReturnType(QualType RetTy, CCState &State,
+ bool IsInstanceMethod) const;
ABIArgInfo classifyArgumentType(QualType RetTy, CCState &State) const;
bool shouldUseInReg(QualType Ty, CCState &State, bool &NeedsPadding) const;
@@ -622,9 +623,8 @@ public:
/// shouldReturnTypeInRegister - Determine if the given type should be
/// passed in a register (for the Darwin ABI).
-bool X86_32ABIInfo::shouldReturnTypeInRegister(QualType Ty,
- ASTContext &Context,
- unsigned callingConvention) {
+bool X86_32ABIInfo::shouldReturnTypeInRegister(QualType Ty, ASTContext &Context,
+ bool IsInstanceMethod) const {
uint64_t Size = Context.getTypeSize(Ty);
// Type must be register sized.
@@ -650,7 +650,7 @@ bool X86_32ABIInfo::shouldReturnTypeInRegister(QualType Ty,
// Arrays are treated like records.
if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty))
return shouldReturnTypeInRegister(AT->getElementType(), Context,
- callingConvention);
+ IsInstanceMethod);
// Otherwise, it must be a record type.
const RecordType *RT = Ty->getAs<RecordType>();
@@ -660,10 +660,8 @@ bool X86_32ABIInfo::shouldReturnTypeInRegister(QualType Ty,
// For thiscall conventions, structures will never be returned in
// a register. This is for compatibility with the MSVC ABI
- if (callingConvention == llvm::CallingConv::X86_ThisCall &&
- RT->isStructureType()) {
+ if (IsWin32StructABI && IsInstanceMethod && RT->isStructureType())
return false;
- }
// Structure types are passed in register if all fields would be
// passed in a register.
@@ -676,8 +674,7 @@ bool X86_32ABIInfo::shouldReturnTypeInRegister(QualType Ty,
continue;
// Check fields recursively.
- if (!shouldReturnTypeInRegister(FD->getType(), Context,
- callingConvention))
+ if (!shouldReturnTypeInRegister(FD->getType(), Context, IsInstanceMethod))
return false;
}
return true;
@@ -693,8 +690,8 @@ ABIArgInfo X86_32ABIInfo::getIndirectReturnResult(CCState &State) const {
return ABIArgInfo::getIndirect(/*Align=*/0, /*ByVal=*/false);
}
-ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
- CCState &State) const {
+ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy, CCState &State,
+ bool IsInstanceMethod) const {
if (RetTy->isVoidType())
return ABIArgInfo::getIgnore();
@@ -739,8 +736,7 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
// Small structures which are register sized are generally returned
// in a register.
- if (X86_32ABIInfo::shouldReturnTypeInRegister(RetTy, getContext(),
- State.CC)) {
+ if (shouldReturnTypeInRegister(RetTy, getContext(), IsInstanceMethod)) {
uint64_t Size = getContext().getTypeSize(RetTy);
// As a special-case, if the struct is a "single-element" struct, and
@@ -987,7 +983,16 @@ void X86_32ABIInfo::computeInfo(CGFunctionInfo &FI) const {
else
State.FreeRegs = DefaultNumRegisterParameters;
- FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), State);
+ FI.getReturnInfo() =
+ classifyReturnType(FI.getReturnType(), State, FI.isInstanceMethod());
+
+ // On win32, use the x86_cdeclmethodcc convention for cdecl methods that use
+ // sret. This convention swaps the order of the first two parameters behind
+ // the scenes to match MSVC.
+ if (IsWin32StructABI && FI.isInstanceMethod() &&
+ FI.getCallingConvention() == llvm::CallingConv::C &&
+ FI.getReturnInfo().isIndirect())
+ FI.setEffectiveCallingConvention(llvm::CallingConv::X86_CDeclMethod);
for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
it != ie; ++it)
OpenPOWER on IntegriCloud