]> granicus.if.org Git - clang/commitdiff
implement passing of complex and aggregates through call args.
authorChris Lattner <sabre@nondot.org>
Thu, 23 Aug 2007 23:43:33 +0000 (23:43 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 23 Aug 2007 23:43:33 +0000 (23:43 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41344 91177308-0d34-0410-b5e6-96231b3b80d8

CodeGen/CGComplexExpr.cpp
CodeGen/CGExpr.cpp
CodeGen/CGStmt.cpp
CodeGen/CodeGenFunction.h

index 90bb078b77c92fb9877b6c6ee2d6a7dc71e98481..1597f8e2c78bee569c822e3b5040845f298bed65 100644 (file)
@@ -314,3 +314,13 @@ ComplexPairTy CodeGenFunction::EmitComplexExpr(const Expr *E) {
   return ComplexExprEmitter(*this).Visit(const_cast<Expr*>(E));
 }
 
+/// EmitComplexExprIntoAddr - Emit the computation of the specified expression
+/// of complex type, storing into the specified Value*.
+void CodeGenFunction::EmitComplexExprIntoAddr(const Expr *E,
+                                              llvm::Value *DestAddr) {
+  assert(E && E->getType()->isComplexType() &&
+         "Invalid complex expression to emit");
+  ComplexExprEmitter Emitter(*this);
+  ComplexPairTy Val = Emitter.Visit(const_cast<Expr*>(E));
+  Emitter.EmitStoreOfComplex(Val, DestAddr, false);
+}
index cbf92f969c9072a99bc6caa081a83610406b7cc4..64067e79ee7b8e951887fbe384caf10e611fbd8f 100644 (file)
@@ -509,6 +509,27 @@ EmitOCUVectorElementExpr(const OCUVectorElementExpr *E) {
 //                             Expression Emission
 //===--------------------------------------------------------------------===//
 
+/// EmitAnyExpr - Emit an expression of any type: scalar, complex, aggregate,
+/// returning an rvalue corresponding to it.  If NeedResult is false, the
+/// result of the expression doesn't need to be generated into memory.
+RValue CodeGenFunction::EmitAnyExpr(const Expr *E, bool NeedResult) {
+  if (!hasAggregateLLVMType(E->getType()))
+    return EmitExpr(E);
+  
+  llvm::Value *DestMem = 0;
+  if (NeedResult)
+    DestMem = CreateTempAlloca(ConvertType(E->getType()));
+  
+  if (!E->getType()->isComplexType()) {
+    EmitAggExpr(E, DestMem, false);
+  } else if (NeedResult)
+    EmitComplexExprIntoAddr(E, DestMem);
+  else
+    EmitComplexExpr(E);
+  
+  return RValue::getAggregate(DestMem);
+}
+
 RValue CodeGenFunction::EmitExpr(const Expr *E) {
   assert(E && !hasAggregateLLVMType(E->getType()) &&
          "Invalid scalar expression to emit");
@@ -693,7 +714,7 @@ RValue CodeGenFunction::EmitCallExpr(const CallExpr *E) {
   
   for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {
     QualType ArgTy = E->getArg(i)->getType();
-    RValue ArgVal = EmitExpr(E->getArg(i));
+    RValue ArgVal = EmitAnyExpr(E->getArg(i));
     
     // If this argument has prototype information, convert it.
     if (ArgTyIt != ArgTyEnd) {
@@ -711,7 +732,6 @@ RValue CodeGenFunction::EmitCallExpr(const CallExpr *E) {
       }
     }
     
-    
     if (ArgVal.isScalar())
       Args.push_back(ArgVal.getVal());
     else  // Pass by-address.  FIXME: Set attribute bit on call.
index c128abcca9ccaa44db46ff7512be9b532be1245a..7b69e515e661f5bb60187c68f8ad6d5777ca898a 100644 (file)
@@ -31,12 +31,7 @@ void CodeGenFunction::EmitStmt(const Stmt *S) {
     // Must be an expression in a stmt context.  Emit the value and ignore the
     // result.
     if (const Expr *E = dyn_cast<Expr>(S)) {
-      if (E->getType()->isComplexType()) {
-        EmitComplexExpr(E);
-      } else if (hasAggregateLLVMType(E->getType()))
-        EmitAggExpr(E, 0, false);  // Emit an aggregate, ignoring the result.
-      else
-        EmitExpr(E);
+      EmitAnyExpr(E, false);
     } else {
       printf("Unimplemented stmt!\n");
       S->dump();
index 95e3656ed3ab63a108f1bc2ce0bff54661dbc5d9..5e2b07bb4b4b306d0c32618a0d7d6981fc4a08a4 100644 (file)
@@ -340,6 +340,11 @@ public:
   RValue EmitCompoundAssignmentResult(const CompoundAssignOperator *E,
                                       LValue LHSLV, RValue ResV);
   
+  /// EmitAnyExpr - Emit an expression of any type: scalar, complex, aggregate,
+  /// returning an rvalue corresponding to it.  If NeedResult is false, the
+  /// result of the expression doesn't need to be generated into memory.
+  RValue EmitAnyExpr(const Expr *E, bool NeedResult = true);
+  
   RValue EmitExpr(const Expr *E);
   RValue EmitIntegerLiteral(const IntegerLiteral *E);
   RValue EmitFloatingLiteral(const FloatingLiteral *E);
@@ -409,8 +414,12 @@ public:
   void EmitAggExpr(const Expr *E, llvm::Value *DestPtr, bool VolatileDest);
   
   /// EmitComplexExpr - Emit the computation of the specified expression of
-  /// complex type, ignoring the result.
+  /// complex type, returning the result.
   ComplexPairTy EmitComplexExpr(const Expr *E);
+  
+  /// EmitComplexExprIntoAddr - Emit the computation of the specified expression
+  /// of complex type, storing into the specified Value*.
+  void EmitComplexExprIntoAddr(const Expr *E, llvm::Value *DestAddr);
 };
 }  // end namespace CodeGen
 }  // end namespace clang