summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/TargetInfo.cpp
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2014-05-09 22:46:15 +0000
committerReid Kleckner <reid@kleckner.net>2014-05-09 22:46:15 +0000
commit37abaca3c26a4f89e34df356c3ad6018f42580ce (patch)
tree5c1cceb3a6330f0477c8a155faa4989ac0832d12 /clang/lib/CodeGen/TargetInfo.cpp
parent46e1ecdecc9b6e6809fd85d9a2f7ae707e1aadd0 (diff)
downloadbcm5719-llvm-37abaca3c26a4f89e34df356c3ad6018f42580ce.tar.gz
bcm5719-llvm-37abaca3c26a4f89e34df356c3ad6018f42580ce.zip
MS ABI: Pass 'sret' as the second parameter of instance methods
Summary: MSVC always passes 'sret' after 'this', unlike GCC. This required changing a number of places in Clang that assumed the sret parameter was always first in LLVM IR. This fixes win64 MSVC ABI compatibility for methods returning structs. Reviewers: rsmith, majnemer Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D3618 llvm-svn: 208458
Diffstat (limited to 'clang/lib/CodeGen/TargetInfo.cpp')
-rw-r--r--clang/lib/CodeGen/TargetInfo.cpp20
1 files changed, 14 insertions, 6 deletions
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp
index 64f9e7b544c..6f0df6bda11 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -992,13 +992,13 @@ void X86_32ABIInfo::computeInfo(CGFunctionInfo &FI) const {
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.
+ // On win32, swap the order of the first two parameters for instance methods
+ // which are sret behind the scenes to match MSVC.
if (IsWin32StructABI && FI.isInstanceMethod() &&
- FI.getCallingConvention() == llvm::CallingConv::C &&
- FI.getReturnInfo().isIndirect())
- FI.setEffectiveCallingConvention(llvm::CallingConv::X86_CDeclMethod);
+ FI.getReturnInfo().isIndirect()) {
+ assert(FI.arg_size() >= 1 && "instance method should have this");
+ FI.getReturnInfo().setSRetAfterThis(true);
+ }
bool UsedInAlloca = false;
for (auto &I : FI.arguments()) {
@@ -2768,6 +2768,14 @@ void WinX86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const {
QualType RetTy = FI.getReturnType();
FI.getReturnInfo() = classify(RetTy, true);
+ // On win64, swap the order of the first two parameters for instance methods
+ // which are sret behind the scenes to match MSVC.
+ if (FI.getReturnInfo().isIndirect() && FI.isInstanceMethod() &&
+ getCXXABI().isSRetParameterAfterThis()) {
+ assert(FI.arg_size() >= 1 && "instance method should have this");
+ FI.getReturnInfo().setSRetAfterThis(true);
+ }
+
for (auto &I : FI.arguments())
I.info = classify(I.type, false);
}
OpenPOWER on IntegriCloud