Author: rjmccall Date: Wed May 26 17:34:26 2010 New Revision: 104778 URL: http://llvm.org/viewvc/llvm-project?rev=104778&view=rev Log: Correctly pass aggregates by reference when emitting thunks.
Modified: cfe/trunk/lib/CodeGen/CGCall.cpp cfe/trunk/lib/CodeGen/CGClass.cpp cfe/trunk/lib/CodeGen/CGVTables.cpp cfe/trunk/lib/CodeGen/CodeGenFunction.h cfe/trunk/test/CodeGenCXX/thunks.cpp Modified: cfe/trunk/lib/CodeGen/CGCall.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=104778&r1=104777&r2=104778&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGCall.cpp (original) +++ cfe/trunk/lib/CodeGen/CGCall.cpp Wed May 26 17:34:26 2010 @@ -862,6 +862,36 @@ } } +RValue CodeGenFunction::EmitDelegateCallArg(const VarDecl *Param) { + // StartFunction converted the ABI-lowered parameter(s) into a + // local alloca. We need to turn that into an r-value suitable + // for EmitCall. + llvm::Value *Local = GetAddrOfLocalVar(Param); + + QualType ArgType = Param->getType(); + + // For the most part, we just need to load the alloca, except: + // 1) aggregate r-values are actually pointers to temporaries, and + // 2) references to aggregates are pointers directly to the aggregate. + // I don't know why references to non-aggregates are different here. + if (const ReferenceType *RefType = ArgType->getAs<ReferenceType>()) { + if (hasAggregateLLVMType(RefType->getPointeeType())) + return RValue::getAggregate(Local); + + // Locals which are references to scalars are represented + // with allocas holding the pointer. + return RValue::get(Builder.CreateLoad(Local)); + } + + if (ArgType->isAnyComplexType()) + return RValue::getComplex(LoadComplexFromAddr(Local, /*volatile*/ false)); + + if (hasAggregateLLVMType(ArgType)) + return RValue::getAggregate(Local); + + return RValue::get(EmitLoadOfScalar(Local, false, ArgType)); +} + RValue CodeGenFunction::EmitCallArg(const Expr *E, QualType ArgType) { if (ArgType->isReferenceType()) return EmitReferenceBindingToExpr(E); Modified: cfe/trunk/lib/CodeGen/CGClass.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=104778&r1=104777&r2=104778&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGClass.cpp (original) +++ cfe/trunk/lib/CodeGen/CGClass.cpp Wed May 26 17:34:26 2010 @@ -1137,34 +1137,9 @@ // Explicit arguments. for (; I != E; ++I) { - const VarDecl *Param = I->first; QualType ArgType = Param->getType(); // because we're passing it to itself - - // StartFunction converted the ABI-lowered parameter(s) into a - // local alloca. We need to turn that into an r-value suitable - // for EmitCall. - llvm::Value *Local = GetAddrOfLocalVar(Param); - RValue Arg; - - // For the most part, we just need to load the alloca, except: - // 1) aggregate r-values are actually pointers to temporaries, and - // 2) references to aggregates are pointers directly to the aggregate. - // I don't know why references to non-aggregates are different here. - if (ArgType->isReferenceType()) { - const ReferenceType *RefType = ArgType->getAs<ReferenceType>(); - if (hasAggregateLLVMType(RefType->getPointeeType())) - Arg = RValue::getAggregate(Local); - else - // Locals which are references to scalars are represented - // with allocas holding the pointer. - Arg = RValue::get(Builder.CreateLoad(Local)); - } else { - if (hasAggregateLLVMType(ArgType)) - Arg = RValue::getAggregate(Local); - else - Arg = RValue::get(EmitLoadOfScalar(Local, false, ArgType)); - } + RValue Arg = EmitDelegateCallArg(Param); DelegateArgs.push_back(std::make_pair(Arg, ArgType)); } Modified: cfe/trunk/lib/CodeGen/CGVTables.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTables.cpp?rev=104778&r1=104777&r2=104778&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGVTables.cpp (original) +++ cfe/trunk/lib/CodeGen/CGVTables.cpp Wed May 26 17:34:26 2010 @@ -2641,14 +2641,7 @@ E = MD->param_end(); I != E; ++I) { ParmVarDecl *Param = *I; QualType ArgType = Param->getType(); - - // Load the argument corresponding to this parameter. - RValue Arg; - if (ArgType->isReferenceType() || - (hasAggregateLLVMType(ArgType) && !ArgType->isAnyComplexType())) - Arg = RValue::get(Builder.CreateLoad(LocalDeclMap[Param])); - else - Arg = RValue::get(EmitLoadOfScalar(LocalDeclMap[Param], false, ArgType)); + RValue Arg = EmitDelegateCallArg(Param); CallArgs.push_back(std::make_pair(Arg, ArgType)); } Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=104778&r1=104777&r2=104778&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original) +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Wed May 26 17:34:26 2010 @@ -1302,6 +1302,11 @@ /// EmitCallArg - Emit a single call argument. RValue EmitCallArg(const Expr *E, QualType ArgType); + /// EmitDelegateCallArg - We are performing a delegate call; that + /// is, the current function is delegating to another one. Produce + /// a r-value suitable for passing the given parameter. + RValue EmitDelegateCallArg(const VarDecl *Param); + private: void EmitReturnOfRValue(RValue RV, QualType Ty); Modified: cfe/trunk/test/CodeGenCXX/thunks.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/thunks.cpp?rev=104778&r1=104777&r2=104778&view=diff ============================================================================== --- cfe/trunk/test/CodeGenCXX/thunks.cpp (original) +++ cfe/trunk/test/CodeGenCXX/thunks.cpp Wed May 26 17:34:26 2010 @@ -218,6 +218,24 @@ void testD() { D d; } } +namespace Test8 { + struct NonPOD { ~NonPOD(); int x, y, z; }; + struct A { virtual void foo(); }; + struct B { virtual void bar(NonPOD); }; + struct C : A, B { virtual void bar(NonPOD); static void helper(NonPOD); }; + + // CHECK: define void @_ZN5Test81C6helperENS_6NonPODE([[NONPODTYPE:%.*]]* + void C::helper(NonPOD var) {} + + // CHECK: define void @_ZThn8_N5Test81C3barENS_6NonPODE( + // CHECK-NOT: load [[NONPODTYPE]]* + // CHECK-NOT: memcpy + // CHECK: ret void + void C::bar(NonPOD var) {} +} + +/**** The following has to go at the end of the file ****/ + // This is from Test5: // CHECK: define linkonce_odr void @_ZTv0_n24_N5Test51B1fEv // CHECK: define internal void @_ZThn8_N12_GLOBAL__N_11C1fEv( _______________________________________________ cfe-commits mailing list cfe-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits