diff options
author | Reid Kleckner <reid@kleckner.net> | 2014-05-09 22:46:15 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2014-05-09 22:46:15 +0000 |
commit | 37abaca3c26a4f89e34df356c3ad6018f42580ce (patch) | |
tree | 5c1cceb3a6330f0477c8a155faa4989ac0832d12 /clang/lib/CodeGen/TargetInfo.cpp | |
parent | 46e1ecdecc9b6e6809fd85d9a2f7ae707e1aadd0 (diff) | |
download | bcm5719-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.cpp | 20 |
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); } |