[cfe-commits] r151122 - in /cfe/trunk: lib/CodeGen/TargetInfo.cpp test/CodeGenCXX/thiscall-struct-return.cpp

Aaron Ballman aaron at aaronballman.com
Tue Feb 21 19:37:18 PST 2012


On Tue, Feb 21, 2012 at 9:32 PM, Nico Weber <thakis at chromium.org> wrote:
> 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.

Hmm, I may have heard wrong then.  If that's the case, I'll take care
of it.  Confirmation?

~Aaron




More information about the cfe-commits mailing list