On Tue, Feb 21, 2012 at 7:04 PM, Aaron Ballman <[email protected]> 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 _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
