[cfe-commits] r151122 - in /cfe/trunk: lib/CodeGen/TargetInfo.cpp test/CodeGenCXX/thiscall-struct-return.cpp
Nico Weber
thakis at chromium.org
Tue Feb 21 19:32:14 PST 2012
On Tue, Feb 21, 2012 at 7:04 PM, Aaron Ballman <aaron at aaronballman.com> wrote:
> Author: aaronballman
> Date: Tue Feb 21 21:04:13 2012
> New Revision: 151122
>
> URL: http://llvm.org/viewvc/llvm-project?rev=151122&view=rev
> Log:
> Adding support for Microsoft's thiscall calling convention. Clang side of the patch.
>
> Added:
> cfe/trunk/test/CodeGenCXX/thiscall-struct-return.cpp (with props)
> Modified:
> cfe/trunk/lib/CodeGen/TargetInfo.cpp
>
> Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=151122&r1=151121&r2=151122&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
> +++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Tue Feb 21 21:04:13 2012
> @@ -424,7 +424,8 @@
> return (Size == 8 || Size == 16 || Size == 32 || Size == 64);
> }
>
> - static bool shouldReturnTypeInRegister(QualType Ty, ASTContext &Context);
> + static bool shouldReturnTypeInRegister(QualType Ty, ASTContext &Context,
> + unsigned callingConvention);
>
> /// getIndirectResult - Give a source type \arg Ty, return a suitable result
> /// such that the argument will be passed in memory.
> @@ -435,11 +436,13 @@
>
> public:
>
> - ABIArgInfo classifyReturnType(QualType RetTy) const;
> + ABIArgInfo classifyReturnType(QualType RetTy,
> + unsigned callingConvention) const;
> ABIArgInfo classifyArgumentType(QualType RetTy) const;
>
> virtual void computeInfo(CGFunctionInfo &FI) const {
> - FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
> + FI.getReturnInfo() = classifyReturnType(FI.getReturnType(),
> + FI.getCallingConvention());
> for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
> it != ie; ++it)
> it->info = classifyArgumentType(it->type);
> @@ -485,7 +488,8 @@
> /// shouldReturnTypeInRegister - Determine if the given type should be
> /// passed in a register (for the Darwin ABI).
> bool X86_32ABIInfo::shouldReturnTypeInRegister(QualType Ty,
> - ASTContext &Context) {
> + ASTContext &Context,
> + unsigned callingConvention) {
> uint64_t Size = Context.getTypeSize(Ty);
>
> // Type must be register sized.
> @@ -510,7 +514,8 @@
>
> // Arrays are treated like records.
> if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty))
> - return shouldReturnTypeInRegister(AT->getElementType(), Context);
> + return shouldReturnTypeInRegister(AT->getElementType(), Context,
> + callingConvention);
>
> // Otherwise, it must be a record type.
> const RecordType *RT = Ty->getAs<RecordType>();
> @@ -518,6 +523,13 @@
>
> // FIXME: Traverse bases here too.
>
> + // 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()) {
> + return false;
> + }
> +
> // Structure types are passed in register if all fields would be
> // passed in a register.
> for (RecordDecl::field_iterator i = RT->getDecl()->field_begin(),
> @@ -529,14 +541,15 @@
> continue;
>
> // Check fields recursively.
> - if (!shouldReturnTypeInRegister(FD->getType(), Context))
> + if (!shouldReturnTypeInRegister(FD->getType(), Context,
> + callingConvention))
> return false;
> }
> -
> return true;
> }
>
> -ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy) const {
> +ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
> + unsigned callingConvention) const {
> if (RetTy->isVoidType())
> return ABIArgInfo::getIgnore();
>
> @@ -583,7 +596,8 @@
>
> // Small structures which are register sized are generally returned
> // in a register.
> - if (X86_32ABIInfo::shouldReturnTypeInRegister(RetTy, getContext())) {
> + if (X86_32ABIInfo::shouldReturnTypeInRegister(RetTy, getContext(),
> + callingConvention)) {
> uint64_t Size = getContext().getTypeSize(RetTy);
>
> // As a special-case, if the struct is a "single-element" struct, and
>
> Added: cfe/trunk/test/CodeGenCXX/thiscall-struct-return.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/thiscall-struct-return.cpp?rev=151122&view=auto
> ==============================================================================
> --- cfe/trunk/test/CodeGenCXX/thiscall-struct-return.cpp (added)
> +++ cfe/trunk/test/CodeGenCXX/thiscall-struct-return.cpp Tue Feb 21 21:04:13 2012
> @@ -0,0 +1,41 @@
> +// For MSVC ABI compatibility, all structures returned by value using the
> +// thiscall calling convention must use the hidden parameter.
> +//
> +// RUN: %clang_cc1 -triple i386-PC-Win32 %s -fms-compatibility -O0 -emit-llvm -o - | FileCheck %s
> +
> +// This structure would normally be returned via EAX
> +struct S {
> + int i;
> +};
> +
> +// This structure would normally be returned via EAX/EDX
> +struct M {
> + int i;
> + int j;
> +};
> +
> +class C {
> +public:
> + C() {}
> +
> + struct S __attribute__((thiscall)) Small() const {
> + struct S s = { 0 };
> + return s;
> + }
> +
> + struct M __attribute__((thiscall)) Medium() const {
> + struct M m = { 0 };
> + return m;
> + }
> +};
> +
> +// CHECK: define void @_Z4testv()
> +void test( void ) {
> +// CHECK: call void @_ZN1CC1Ev(%class.C* %c)
> + C c;
> +
> +// CHECK: call x86_thiscallcc void @_ZNK1C5SmallEv(%struct.S* sret %tmp, %class.C* %c)
> + (void)c.Small();
> +// CHECK: call x86_thiscallcc void @_ZNK1C6MediumEv(%struct.M* sret %tmp1, %class.C* %c)
> + (void)c.Medium();
> +}
>
> Propchange: cfe/trunk/test/CodeGenCXX/thiscall-struct-return.cpp
> ------------------------------------------------------------------------------
> svn:eol-style = native
I think I was told once that clang prefers no svn:eol-style property
on its files.
Nico
More information about the cfe-commits
mailing list