From: Chris Lattner Date: Thu, 23 Aug 2007 23:43:33 +0000 (+0000) Subject: implement passing of complex and aggregates through call args. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=23b1cdb0b5e089468bb8475b8ec9287af67b4b59;p=clang implement passing of complex and aggregates through call args. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41344 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/CodeGen/CGComplexExpr.cpp b/CodeGen/CGComplexExpr.cpp index 90bb078b77..1597f8e2c7 100644 --- a/CodeGen/CGComplexExpr.cpp +++ b/CodeGen/CGComplexExpr.cpp @@ -314,3 +314,13 @@ ComplexPairTy CodeGenFunction::EmitComplexExpr(const Expr *E) { return ComplexExprEmitter(*this).Visit(const_cast(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(E)); + Emitter.EmitStoreOfComplex(Val, DestAddr, false); +} diff --git a/CodeGen/CGExpr.cpp b/CodeGen/CGExpr.cpp index cbf92f969c..64067e79ee 100644 --- a/CodeGen/CGExpr.cpp +++ b/CodeGen/CGExpr.cpp @@ -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. diff --git a/CodeGen/CGStmt.cpp b/CodeGen/CGStmt.cpp index c128abcca9..7b69e515e6 100644 --- a/CodeGen/CGStmt.cpp +++ b/CodeGen/CGStmt.cpp @@ -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(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(); diff --git a/CodeGen/CodeGenFunction.h b/CodeGen/CodeGenFunction.h index 95e3656ed3..5e2b07bb4b 100644 --- a/CodeGen/CodeGenFunction.h +++ b/CodeGen/CodeGenFunction.h @@ -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