diff options
-rw-r--r-- | lib/CodeGen/CGCall.cpp | 3 | ||||
-rw-r--r-- | lib/CodeGen/CGCall.h | 4 | ||||
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 65 | ||||
-rw-r--r-- | lib/CodeGen/CGObjC.cpp | 11 | ||||
-rw-r--r-- | lib/CodeGen/CGObjCGNU.cpp | 9 | ||||
-rw-r--r-- | lib/CodeGen/CGObjCMac.cpp | 8 | ||||
-rw-r--r-- | lib/CodeGen/CGObjCRuntime.h | 9 | ||||
-rw-r--r-- | lib/CodeGen/CGValue.h | 5 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 14 |
9 files changed, 60 insertions, 68 deletions
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index d342ef0af3..a3a330e5e0 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -102,8 +102,7 @@ void CGFunctionInfo::constructParamAttrList(ParamAttrListType &PAL) const { /***/ -CGCallInfo::CGCallInfo(QualType _ResultType, - const llvm::SmallVector<std::pair<llvm::Value*, QualType>, 16> &_Args) +CGCallInfo::CGCallInfo(QualType _ResultType, const CallArgList &_Args) : ResultType(_ResultType), Args(_Args) { ArgTypes.push_back(ResultType); diff --git a/lib/CodeGen/CGCall.h b/lib/CodeGen/CGCall.h index b4e8d1f6da..78a83a8791 100644 --- a/lib/CodeGen/CGCall.h +++ b/lib/CodeGen/CGCall.h @@ -17,6 +17,8 @@ #include "clang/AST/Type.h" +#include "CGValue.h" + namespace llvm { class Function; struct ParamAttrsWithIndex; @@ -36,7 +38,7 @@ namespace CodeGen { /// CallArgList - Type for representing both the value and type of /// arguments in a call. - typedef llvm::SmallVector<std::pair<llvm::Value*, QualType>, 16> CallArgList; + typedef llvm::SmallVector<std::pair<RValue, QualType>, 16> CallArgList; /// CGFunctionInfo - Class to encapsulate the information about a /// function definition. diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 8a978160d0..1c10171194 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -57,6 +57,17 @@ RValue CodeGenFunction::EmitAnyExpr(const Expr *E, llvm::Value *AggLoc, return RValue::getAggregate(AggLoc); } +/// EmitAnyExprToTemp - Similary to EmitAnyExpr(), however, the result +/// will always be accessible even if no aggregate location is +/// provided. +RValue CodeGenFunction::EmitAnyExprToTemp(const Expr *E, llvm::Value *AggLoc, + bool isAggLocVolatile) { + if (!AggLoc && hasAggregateLLVMType(E->getType()) && + !E->getType()->isAnyComplexType()) + AggLoc = CreateTempAlloca(ConvertType(E->getType()), "agg.tmp"); + return EmitAnyExpr(E, AggLoc, isAggLocVolatile); +} + /// getAccessedFieldNo - Given an encoded value and a result number, return /// the input field number being accessed. unsigned CodeGenFunction::getAccessedFieldNo(unsigned Idx, @@ -840,48 +851,12 @@ RValue CodeGenFunction::EmitCallExpr(llvm::Value *Callee, QualType FnType, CallArgList Args; for (CallExpr::const_arg_iterator I = ArgBeg; I != ArgEnd; ++I) - EmitCallArg(*I, Args); + Args.push_back(std::make_pair(EmitAnyExprToTemp(*I), + I->getType())); return EmitCall(Callee, ResultType, Args); } -// FIXME: Merge the following two functions. -void CodeGenFunction::EmitCallArg(RValue RV, QualType Ty, - CallArgList &Args) { - llvm::Value *ArgValue; - - if (RV.isScalar()) { - ArgValue = RV.getScalarVal(); - } else if (RV.isComplex()) { - // Make a temporary alloca to pass the argument. - ArgValue = CreateTempAlloca(ConvertType(Ty)); - StoreComplexToAddr(RV.getComplexVal(), ArgValue, false); - } else { - ArgValue = RV.getAggregateAddr(); - } - - Args.push_back(std::make_pair(ArgValue, Ty)); -} - -void CodeGenFunction::EmitCallArg(const Expr *E, CallArgList &Args) { - QualType ArgTy = E->getType(); - llvm::Value *ArgValue; - - if (!hasAggregateLLVMType(ArgTy)) { - // Scalar argument is passed by-value. - ArgValue = EmitScalarExpr(E); - } else if (ArgTy->isAnyComplexType()) { - // Make a temporary alloca to pass the argument. - ArgValue = CreateTempAlloca(ConvertType(ArgTy)); - EmitComplexExprIntoAddr(E, ArgValue, false); - } else { - ArgValue = CreateTempAlloca(ConvertType(ArgTy)); - EmitAggExpr(E, ArgValue, false); - } - - Args.push_back(std::make_pair(ArgValue, E->getType())); -} - RValue CodeGenFunction::EmitCall(llvm::Value *Callee, QualType ResultType, const CallArgList &CallArgs) { @@ -898,8 +873,18 @@ RValue CodeGenFunction::EmitCall(llvm::Value *Callee, } for (CallArgList::const_iterator I = CallArgs.begin(), E = CallArgs.end(); - I != E; ++I) - Args.push_back(I->first); + I != E; ++I) { + RValue RV = I->first; + if (RV.isScalar()) { + Args.push_back(RV.getScalarVal()); + } else if (RV.isComplex()) { + // Make a temporary alloca to pass the argument. + Args.push_back(CreateTempAlloca(ConvertType(I->second))); + StoreComplexToAddr(RV.getComplexVal(), Args.back(), false); + } else { + Args.push_back(RV.getAggregateAddr()); + } + } llvm::CallInst *CI = Builder.CreateCall(Callee,&Args[0],&Args[0]+Args.size()); CGCallInfo CallInfo(ResultType, CallArgs); diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index 8660d96443..7242d01adb 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -83,7 +83,7 @@ RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) { CallArgList Args; for (CallExpr::const_arg_iterator i = E->arg_begin(), e = E->arg_end(); i != e; ++i) - EmitCallArg(*i, Args); + Args.push_back(std::make_pair(EmitAnyExprToTemp(*i), (*i)->getType())); if (isSuperMessage) { // super is only valid in an Objective-C method @@ -268,7 +268,7 @@ void CodeGenFunction::EmitObjCPropertySet(const ObjCPropertyRefExpr *E, } CallArgList Args; - EmitCallArg(Src, E->getType(), Args); + Args.push_back(std::make_pair(Src, E->getType())); CGM.getObjCRuntime().GenerateMessageSend(*this, getContext().VoidTy, S, EmitScalarExpr(E->getBase()), false, Args); @@ -316,15 +316,16 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S) llvm::Value *Collection = EmitScalarExpr(S.getCollection()); CallArgList Args; - Args.push_back(std::make_pair(StatePtr, + Args.push_back(std::make_pair(RValue::get(StatePtr), getContext().getPointerType(StateTy))); - Args.push_back(std::make_pair(ItemsPtr, + Args.push_back(std::make_pair(RValue::get(ItemsPtr), getContext().getPointerType(ItemsTy))); const llvm::Type *UnsignedLongLTy = ConvertType(getContext().UnsignedLongTy); llvm::Constant *Count = llvm::ConstantInt::get(UnsignedLongLTy, NumItems); - Args.push_back(std::make_pair(Count, getContext().UnsignedLongTy)); + Args.push_back(std::make_pair(RValue::get(Count), + getContext().UnsignedLongTy)); RValue CountRV = CGM.getObjCRuntime().GenerateMessageSend(*this, diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp index 4d69aed816..2bbbb46cd0 100644 --- a/lib/CodeGen/CGObjCGNU.cpp +++ b/lib/CodeGen/CGObjCGNU.cpp @@ -28,6 +28,7 @@ #include "llvm/Target/TargetData.h" #include <map> using namespace clang; +using namespace CodeGen; using llvm::dyn_cast; // The version of the runtime that this class targets. Must match the version @@ -281,9 +282,9 @@ CGObjCGNU::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, // Call the method CallArgList ActualArgs; - ActualArgs.push_back(std::make_pair(Receiver, + ActualArgs.push_back(std::make_pair(RValue::get(Receiver), CGF.getContext().getObjCIdType())); - ActualArgs.push_back(std::make_pair(cmd, + ActualArgs.push_back(std::make_pair(RValue::get(cmd), CGF.getContext().getObjCSelType())); ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end()); return CGF.EmitCall(imp, ResultType, ActualArgs); @@ -328,9 +329,9 @@ CGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF, // Call the method. CallArgList ActualArgs; - ActualArgs.push_back(std::make_pair(Receiver, + ActualArgs.push_back(std::make_pair(RValue::get(Receiver), CGF.getContext().getObjCIdType())); - ActualArgs.push_back(std::make_pair(cmd, + ActualArgs.push_back(std::make_pair(RValue::get(cmd), CGF.getContext().getObjCSelType())); ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end()); return CGF.EmitCall(imp, ResultType, ActualArgs); diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index 3922ae66a3..26e8c5f5b6 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -26,6 +26,7 @@ #include <sstream> using namespace clang; +using namespace CodeGen; namespace { @@ -438,7 +439,7 @@ CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, const ObjCInterfaceDecl *Class, llvm::Value *Receiver, bool IsClassMessage, - const CallArgList &CallArgs) { + const CodeGen::CallArgList &CallArgs) { // Create and init a super structure; this is a (receiver, class) // pair we will pass to objc_msgSendSuper. llvm::Value *ObjCSuper = @@ -493,8 +494,9 @@ CodeGen::RValue CGObjCMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF, bool IsSuper, const CallArgList &CallArgs) { CallArgList ActualArgs; - ActualArgs.push_back(std::make_pair(Arg0, Arg0Ty)); - ActualArgs.push_back(std::make_pair(EmitSelector(CGF.Builder, Sel), + ActualArgs.push_back(std::make_pair(RValue::get(Arg0), Arg0Ty)); + ActualArgs.push_back(std::make_pair(RValue::get(EmitSelector(CGF.Builder, + Sel)), CGF.getContext().getObjCSelType())); ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end()); diff --git a/lib/CodeGen/CGObjCRuntime.h b/lib/CodeGen/CGObjCRuntime.h index 4bc293afac..7b00725f23 100644 --- a/lib/CodeGen/CGObjCRuntime.h +++ b/lib/CodeGen/CGObjCRuntime.h @@ -21,6 +21,7 @@ #include <string> #include "CGValue.h" +#include "CGCall.h" namespace llvm { class Constant; @@ -31,9 +32,9 @@ namespace llvm { } namespace clang { - namespace CodeGen { - class CodeGenFunction; - } +namespace CodeGen { + class CodeGenFunction; +} class ObjCCategoryImplDecl; class ObjCImplementationDecl; @@ -43,8 +44,6 @@ namespace clang { class ObjCProtocolDecl; class Selector; - typedef llvm::SmallVector<std::pair<llvm::Value*, QualType>, 16> CallArgList; - namespace CodeGen { class CodeGenModule; diff --git a/lib/CodeGen/CGValue.h b/lib/CodeGen/CGValue.h index bc9a15fe9f..fae473f866 100644 --- a/lib/CodeGen/CGValue.h +++ b/lib/CodeGen/CGValue.h @@ -17,6 +17,11 @@ #include "clang/AST/Type.h" +namespace llvm { + class Constant; + class Value; +} + namespace clang { class ObjCPropertyRefExpr; diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index c38171a5f5..3d14aed4bd 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -175,6 +175,12 @@ public: RValue EmitAnyExpr(const Expr *E, llvm::Value *AggLoc = 0, bool isAggLocVolatile = false); + /// EmitAnyExprToTemp - Similary to EmitAnyExpr(), however, the result + /// will always be accessible even if no aggregate location is + /// provided. + RValue EmitAnyExprToTemp(const Expr *E, llvm::Value *AggLoc = 0, + bool isAggLocVolatile = false); + /// isDummyBlock - Return true if BB is an empty basic block /// with no predecessors. static bool isDummyBlock(const llvm::BasicBlock *BB); @@ -308,14 +314,6 @@ public: // Scalar Expression Emission //===--------------------------------------------------------------------===// - /// EmitCallArg - Emit the given expression and append the result - /// onto the given Args list. - void EmitCallArg(const Expr *E, CallArgList &Args); - - /// EmitCallArg - Append the appropriate call argument for the given - /// rvalue and type onto the Args list. - void EmitCallArg(RValue RV, QualType Ty, CallArgList &Args); - /// EmitCall - Generate a call of the given function, expecting the /// given result type, and using the given argument list which /// specifies both the LLVM arguments and the types they were |