]> granicus.if.org Git - clang/commitdiff
implement initial codegen for aggregate return functions. This implements
authorChris Lattner <sabre@nondot.org>
Fri, 10 Aug 2007 17:02:28 +0000 (17:02 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 10 Aug 2007 17:02:28 +0000 (17:02 +0000)
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

CodeGen/CGExpr.cpp
CodeGen/CodeGenFunction.cpp

index 65d03c2d1ea89b01ee7ac8569016edd1942c7a1b..08bd93f22db909852f479647e2de9fe611f44475 100644 (file)
@@ -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);
 }
 
index 8cea3e7aafb50fd5eff0d4e7384814f5b072aa63..389bd05a70d9dc8ce6d1490084879dd8b16d26f5 100644 (file)
@@ -45,7 +45,7 @@ const llvm::Type *CodeGenFunction::ConvertType(QualType T) {
 
 bool CodeGenFunction::hasAggregateLLVMType(QualType T) {
   return !T->isRealType() && !T->isPointerType() && !T->isVoidType() &&
-         !T->isVectorType();
+         !T->isVectorType() && !T->isFunctionType();
 }