diff options
author | Chris Lattner <sabre@nondot.org> | 2007-08-10 17:02:28 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2007-08-10 17:02:28 +0000 |
commit | cc666af7d40826e6863b9baea2e90c0b46f68b1a (patch) | |
tree | 7c15915042761a5803bf7e79f5cfdf2cd2d64a74 /CodeGen/CGExpr.cpp | |
parent | 461766a5c05a90788af05fdc8cf0645599fb042b (diff) |
implement initial codegen for aggregate return functions. This implements
codegen for:
_Complex double bar(int);
void test(_Complex double*);
void test2(int c) {
_Complex double X;
X = bar(1);
test(&X);
}
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@40993 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'CodeGen/CGExpr.cpp')
-rw-r--r-- | CodeGen/CGExpr.cpp | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/CodeGen/CGExpr.cpp b/CodeGen/CGExpr.cpp index 65d03c2d1e..08bd93f22d 100644 --- a/CodeGen/CGExpr.cpp +++ b/CodeGen/CGExpr.cpp @@ -721,7 +721,14 @@ RValue CodeGenFunction::EmitCallExpr(const CallExpr *E) { llvm::SmallVector<llvm::Value*, 16> Args; - // FIXME: Handle struct return. + // Handle struct-return functions by passing a pointer to the location that + // we would like to return into. + if (hasAggregateLLVMType(E->getType())) { + // Create a temporary alloca to hold the result of the call. :( + Args.push_back(CreateTempAlloca(ConvertType(E->getType()))); + // FIXME: set the stret attribute on the argument. + } + for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) { QualType ArgTy = E->getArg(i)->getType(); RValue ArgVal = EmitExpr(E->getArg(i)); @@ -752,8 +759,10 @@ RValue CodeGenFunction::EmitCallExpr(const CallExpr *E) { llvm::Value *V = Builder.CreateCall(Callee, &Args[0], &Args[0]+Args.size()); if (V->getType() != llvm::Type::VoidTy) V->setName("call"); - - // FIXME: Struct return; + else if (hasAggregateLLVMType(E->getType())) + // Struct return. + return RValue::getAggregate(Args[0]); + return RValue::get(V); } |