diff options
author | John McCall <rjmccall@apple.com> | 2010-05-26 22:34:26 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-05-26 22:34:26 +0000 |
commit | 23f6626262895d5307e2398e3377dc38c978ea43 (patch) | |
tree | 8b1567291e5ed1bd2a79b4c5958a02582a651293 /clang/lib/CodeGen/CGCall.cpp | |
parent | 084bcb1322e5e8f5e71bd2e8eab1ae541e9aeaff (diff) | |
download | bcm5719-llvm-23f6626262895d5307e2398e3377dc38c978ea43.tar.gz bcm5719-llvm-23f6626262895d5307e2398e3377dc38c978ea43.zip |
Correctly pass aggregates by reference when emitting thunks.
llvm-svn: 104778
Diffstat (limited to 'clang/lib/CodeGen/CGCall.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGCall.cpp | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 0d6a70c64d4..73cee3c10d2 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -862,6 +862,36 @@ void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI, } } +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); |