[cfe-commits] r104778 - in /cfe/trunk: lib/CodeGen/CGCall.cpp lib/CodeGen/CGClass.cpp lib/CodeGen/CGVTables.cpp lib/CodeGen/CodeGenFunction.h test/CodeGenCXX/thunks.cpp
John McCall
rjmccall at apple.com
Wed May 26 15:34:26 PDT 2010
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(
More information about the cfe-commits
mailing list