diff options
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 12 | ||||
-rw-r--r-- | lib/CodeGen/CGExprAgg.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/CGExprScalar.cpp | 11 | ||||
-rw-r--r-- | lib/CodeGen/CGObjC.cpp | 34 | ||||
-rw-r--r-- | lib/CodeGen/CGObjCGNU.cpp | 91 | ||||
-rw-r--r-- | lib/CodeGen/CGObjCMac.cpp | 77 | ||||
-rw-r--r-- | lib/CodeGen/CGObjCRuntime.h | 30 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 13 |
8 files changed, 128 insertions, 144 deletions
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 4a80269230..c5b1f28618 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -776,7 +776,15 @@ RValue CodeGenFunction::EmitCallExpr(llvm::Value *Callee, QualType FnType, // type. FnType = FnType->getAsPointerType()->getPointeeType(); QualType ResultType = FnType->getAsFunctionType()->getResultType(); + return EmitCallExprExt(Callee, ResultType, ArgBeg, ArgEnd, 0, 0); +} +RValue CodeGenFunction::EmitCallExprExt(llvm::Value *Callee, + QualType ResultType, + CallExpr::const_arg_iterator ArgBeg, + CallExpr::const_arg_iterator ArgEnd, + llvm::Value **ExtraArgs, + unsigned NumExtraArgs) { llvm::SmallVector<llvm::Value*, 16> Args; // Handle struct-return functions by passing a pointer to the location that @@ -787,6 +795,8 @@ RValue CodeGenFunction::EmitCallExpr(llvm::Value *Callee, QualType FnType, // FIXME: set the stret attribute on the argument. } + Args.insert(Args.end(), ExtraArgs, ExtraArgs + NumExtraArgs); + for (CallExpr::const_arg_iterator I = ArgBeg; I != ArgEnd; ++I) { QualType ArgTy = I->getType(); @@ -812,7 +822,7 @@ RValue CodeGenFunction::EmitCallExpr(llvm::Value *Callee, QualType FnType, if (hasAggregateLLVMType(ResultType)) ParamAttrList.push_back( llvm::ParamAttrsWithIndex::get(1, llvm::ParamAttr::StructRet)); - unsigned increment = hasAggregateLLVMType(ResultType) ? 2 : 1; + unsigned increment = NumExtraArgs + (hasAggregateLLVMType(ResultType) ? 2 : 1); unsigned i = 0; for (CallExpr::const_arg_iterator I = ArgBeg; I != ArgEnd; ++I, ++i) { diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index 019d7be50c..bc6af1251e 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/lib/CodeGen/CGExprAgg.cpp @@ -202,10 +202,12 @@ void AggExprEmitter::VisitCallExpr(const CallExpr *E) { } void AggExprEmitter::VisitObjCMessageExpr(ObjCMessageExpr *E) { - RValue RV = RValue::getAggregate(CGF.EmitObjCMessageExpr(E)); + RValue RV = CGF.EmitObjCMessageExpr(E); + assert(RV.isAggregate() && "Return value must be aggregate value!"); // If the result is ignored, don't copy from the value. if (DestPtr == 0) + // FIXME: If the source is volatile, we must read from it. return; EmitAggregateCopy(DestPtr, RV.getAggregateAddr(), E->getType()); diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index 8228dd6d84..ddf1421b98 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -131,7 +131,6 @@ public: return llvm::ConstantInt::get(EC->getInitVal()); return EmitLoadOfLValue(E); } - Value *VisitObjCMessageExpr(ObjCMessageExpr *E); Value *VisitObjCSelectorExpr(ObjCSelectorExpr *E); Value *VisitObjCProtocolExpr(ObjCProtocolExpr *E); Value *VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { return EmitLoadOfLValue(E);} @@ -186,7 +185,11 @@ public: Value *VisitCallExpr(const CallExpr *E) { return CGF.EmitCallExpr(E).getScalarVal(); } - + + Value *VisitObjCMessageExpr(ObjCMessageExpr *E) { + return CGF.EmitObjCMessageExpr(E).getScalarVal(); + } + Value *VisitStmtExpr(const StmtExpr *E); // Unary Operators. @@ -466,10 +469,6 @@ Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) { return Builder.CreateShuffleVector(V1, V2, SV, "shuffle"); } -Value *ScalarExprEmitter::VisitObjCMessageExpr(ObjCMessageExpr *E) { - return CGF.EmitObjCMessageExpr(E); -} - Value *ScalarExprEmitter::VisitObjCSelectorExpr(ObjCSelectorExpr *E) { return CGF.EmitObjCSelectorExpr(E); } diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index 5e4b958807..b086f4f10c 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -42,7 +42,7 @@ llvm::Value *CodeGenFunction::EmitObjCProtocolExpr(const ObjCProtocolExpr *E) { } -llvm::Value *CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) { +RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) { // Only the lookup mechanism and first two arguments of the method // implementation vary between runtimes. We can get the receiver and // arguments in generic code. @@ -74,38 +74,14 @@ llvm::Value *CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) { Receiver = EmitScalarExpr(E->getReceiver()); } - // Process the arguments - unsigned ArgC = E->getNumArgs(); - llvm::SmallVector<llvm::Value*, 16> Args; - for (unsigned i = 0; i != ArgC; ++i) { - const Expr *ArgExpr = E->getArg(i); - QualType ArgTy = ArgExpr->getType(); - if (!hasAggregateLLVMType(ArgTy)) { - // Scalar argument is passed by-value. - Args.push_back(EmitScalarExpr(ArgExpr)); - } else if (ArgTy->isAnyComplexType()) { - // Make a temporary alloca to pass the argument. - llvm::Value *DestMem = CreateTempAlloca(ConvertType(ArgTy)); - EmitComplexExprIntoAddr(ArgExpr, DestMem, false); - Args.push_back(DestMem); - } else { - llvm::Value *DestMem = CreateTempAlloca(ConvertType(ArgTy)); - EmitAggExpr(ArgExpr, DestMem, false); - Args.push_back(DestMem); - } - } - if (isSuperMessage) { // super is only valid in an Objective-C method const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl); - return Runtime.GenerateMessageSendSuper(Builder, ConvertType(E->getType()), - OMD->getClassInterface()->getSuperClass(), - Receiver, E->getSelector(), - &Args[0], Args.size()); + return Runtime.GenerateMessageSendSuper(*this, E, + OMD->getClassInterface()->getSuperClass(), + Receiver); } - return Runtime.GenerateMessageSend(Builder, ConvertType(E->getType()), - Receiver, E->getSelector(), - &Args[0], Args.size()); + return Runtime.GenerateMessageSend(*this, E, Receiver); } /// Generate an Objective-C method. An Objective-C method is a C function with diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp index 48c82c12f5..b64f365832 100644 --- a/lib/CodeGen/CGObjCGNU.cpp +++ b/lib/CodeGen/CGObjCGNU.cpp @@ -16,6 +16,7 @@ #include "CGObjCRuntime.h" #include "CodeGenModule.h" +#include "CodeGenFunction.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclObjC.h" @@ -93,19 +94,15 @@ private: public: CGObjCGNU(CodeGen::CodeGenModule &cgm); virtual llvm::Constant *GenerateConstantString(const std::string &String); - virtual llvm::Value *GenerateMessageSend(llvm::IRBuilder<> &Builder, - const llvm::Type *ReturnTy, - llvm::Value *Receiver, - Selector Sel, - llvm::Value** ArgV, - unsigned ArgC); - virtual llvm::Value *GenerateMessageSendSuper(llvm::IRBuilder<> &Builder, - const llvm::Type *ReturnTy, - const ObjCInterfaceDecl *SuperClass, - llvm::Value *Receiver, - Selector Sel, - llvm::Value** ArgV, - unsigned ArgC); + virtual CodeGen::RValue + GenerateMessageSend(CodeGen::CodeGenFunction &CGF, + const ObjCMessageExpr *E, + llvm::Value *Receiver); + virtual CodeGen::RValue + GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, + const ObjCMessageExpr *E, + const ObjCInterfaceDecl *Super, + llvm::Value *Receiver); virtual llvm::Value *GetClass(llvm::IRBuilder<> &Builder, const ObjCInterfaceDecl *OID); virtual llvm::Value *GetSelector(llvm::IRBuilder<> &Builder, Selector Sel); @@ -236,16 +233,15 @@ llvm::Constant *CGObjCGNU::GenerateConstantString(const std::string &Str) { ///Generates a message send where the super is the receiver. This is a message ///send to self with special delivery semantics indicating which class's method ///should be called. -llvm::Value *CGObjCGNU::GenerateMessageSendSuper(llvm::IRBuilder<> &Builder, - const llvm::Type *ReturnTy, - const ObjCInterfaceDecl *SuperClass, - llvm::Value *Receiver, - Selector Sel, - llvm::Value** ArgV, - unsigned ArgC) { +CodeGen::RValue +CGObjCGNU::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, + const ObjCMessageExpr *E, + const ObjCInterfaceDecl *SuperClass, + llvm::Value *Receiver) { + const llvm::Type *ReturnTy = CGM.getTypes().ConvertType(E->getType()); // TODO: This should be cached, not looked up every time. - llvm::Value *ReceiverClass = GetClass(Builder, SuperClass); - llvm::Value *cmd = GetSelector(Builder, Sel); + llvm::Value *ReceiverClass = GetClass(CGF.Builder, SuperClass); + llvm::Value *cmd = GetSelector(CGF.Builder, E->getSelector()); std::vector<const llvm::Type*> impArgTypes; impArgTypes.push_back(Receiver->getType()); impArgTypes.push_back(SelectorTy); @@ -257,10 +253,10 @@ llvm::Value *CGObjCGNU::GenerateMessageSendSuper(llvm::IRBuilder<> &Builder, // Construct the structure used to look up the IMP llvm::StructType *ObjCSuperTy = llvm::StructType::get(Receiver->getType(), IdTy, NULL); - llvm::Value *ObjCSuper = Builder.CreateAlloca(ObjCSuperTy); + llvm::Value *ObjCSuper = CGF.Builder.CreateAlloca(ObjCSuperTy); // FIXME: volatility - Builder.CreateStore(Receiver, Builder.CreateStructGEP(ObjCSuper, 0)); - Builder.CreateStore(ReceiverClass, Builder.CreateStructGEP(ObjCSuper, 1)); + CGF.Builder.CreateStore(Receiver, CGF.Builder.CreateStructGEP(ObjCSuper, 0)); + CGF.Builder.CreateStore(ReceiverClass, CGF.Builder.CreateStructGEP(ObjCSuper, 1)); // Get the IMP llvm::Constant *lookupFunction = @@ -269,25 +265,24 @@ llvm::Value *CGObjCGNU::GenerateMessageSendSuper(llvm::IRBuilder<> &Builder, llvm::PointerType::getUnqual(ObjCSuperTy), SelectorTy, NULL); llvm::Value *lookupArgs[] = {ObjCSuper, cmd}; - llvm::Value *imp = Builder.CreateCall(lookupFunction, lookupArgs, + llvm::Value *imp = CGF.Builder.CreateCall(lookupFunction, lookupArgs, lookupArgs+2); // Call the method - llvm::SmallVector<llvm::Value*, 8> callArgs; - callArgs.push_back(Receiver); - callArgs.push_back(cmd); - callArgs.insert(callArgs.end(), ArgV, ArgV+ArgC); - return Builder.CreateCall(imp, callArgs.begin(), callArgs.end()); + llvm::Value *Args[2]; + Args[0] = Receiver; + Args[1] = cmd; + return CGF.EmitCallExprExt(imp, E->getType(), E->arg_begin(), E->arg_end(), + Args, 2); } /// Generate code for a message send expression. -llvm::Value *CGObjCGNU::GenerateMessageSend(llvm::IRBuilder<> &Builder, - const llvm::Type *ReturnTy, - llvm::Value *Receiver, - Selector Sel, - llvm::Value** ArgV, - unsigned ArgC) { - llvm::Value *cmd = GetSelector(Builder, Sel); +CodeGen::RValue +CGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF, + const ObjCMessageExpr *E, + llvm::Value *Receiver) { + const llvm::Type *ReturnTy = CGM.getTypes().ConvertType(E->getType()); + llvm::Value *cmd = GetSelector(CGF.Builder, E->getSelector()); // Look up the method implementation. std::vector<const llvm::Type*> impArgTypes; @@ -313,22 +308,14 @@ llvm::Value *CGObjCGNU::GenerateMessageSend(llvm::IRBuilder<> &Builder, TheModule.getOrInsertFunction("objc_msg_lookup", llvm::PointerType::getUnqual(impType), Receiver->getType(), SelectorTy, NULL); - llvm::Value *imp = Builder.CreateCall2(lookupFunction, Receiver, cmd); + llvm::Value *imp = CGF.Builder.CreateCall2(lookupFunction, Receiver, cmd); // Call the method. - llvm::SmallVector<llvm::Value*, 16> Args; - if (!ReturnTy->isSingleValueType()) { - llvm::Value *Return = Builder.CreateAlloca(ReturnTy); - Args.push_back(Return); - } - Args.push_back(Receiver); - Args.push_back(cmd); - Args.insert(Args.end(), ArgV, ArgV+ArgC); - if (!ReturnTy->isSingleValueType()) { - Builder.CreateCall(imp, Args.begin(), Args.end()); - return Args[0]; - } - return Builder.CreateCall(imp, Args.begin(), Args.end()); + llvm::Value *Args[2]; + Args[0] = Receiver; + Args[1] = cmd; + return CGF.EmitCallExprExt(imp, E->getType(), E->arg_begin(), E->arg_end(), + Args, 2); } /// Generates a MethodList. Used in construction of a objc_class and diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index ee33385bb0..1ad55491d9 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -297,21 +297,15 @@ public: CGObjCMac(CodeGen::CodeGenModule &cgm); virtual llvm::Constant *GenerateConstantString(const std::string &String); - virtual llvm::Value *GenerateMessageSend(llvm::IRBuilder<> &Builder, - const llvm::Type *ReturnTy, - llvm::Value *Receiver, - Selector Sel, - llvm::Value** ArgV, - unsigned ArgC); - - virtual llvm::Value * - GenerateMessageSendSuper(llvm::IRBuilder<> &Builder, - const llvm::Type *ReturnTy, + virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF, + const ObjCMessageExpr *E, + llvm::Value *Receiver); + + virtual CodeGen::RValue + GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, + const ObjCMessageExpr *E, const ObjCInterfaceDecl *SuperClass, - llvm::Value *Receiver, - Selector Sel, - llvm::Value** ArgV, - unsigned ArgC); + llvm::Value *Receiver); virtual llvm::Value *GetClass(llvm::IRBuilder<> &Builder, const ObjCInterfaceDecl *ID); @@ -422,30 +416,24 @@ llvm::Constant *CGObjCMac::GenerateConstantString(const std::string &String) { /// Generates a message send where the super is the receiver. This is /// a message send to self with special delivery semantics indicating /// which class's method should be called. -llvm::Value * -CGObjCMac::GenerateMessageSendSuper(llvm::IRBuilder<> &Builder, - const llvm::Type *ReturnTy, +CodeGen::RValue +CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, + const ObjCMessageExpr *E, const ObjCInterfaceDecl *SuperClass, - llvm::Value *Receiver, - Selector Sel, - llvm::Value** ArgV, - unsigned ArgC) { + llvm::Value *Receiver) { assert(0 && "Cannot generate message send to super for Mac runtime."); - return 0; + return CodeGen::RValue::get(0); } /// Generate code for a message send expression. -llvm::Value *CGObjCMac::GenerateMessageSend(llvm::IRBuilder<> &Builder, - const llvm::Type *ReturnTy, - llvm::Value *Receiver, - Selector Sel, - llvm::Value** ArgV, - unsigned ArgC) { +CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF, + const ObjCMessageExpr *E, + llvm::Value *Receiver) { + const llvm::Type *ReturnTy = CGM.getTypes().ConvertType(E->getType()); llvm::Function *F = ObjCTypes.getMessageSendFn(); - llvm::Value **Args = new llvm::Value*[ArgC+2]; - Args[0] = Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy, "tmp"); - Args[1] = EmitSelector(Builder, Sel); - std::copy(ArgV, ArgV+ArgC, Args+2); + llvm::Value *Args[2]; + Args[0] = CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy, "tmp"); + Args[1] = EmitSelector(CGF.Builder, E->getSelector()); std::vector<const llvm::Type*> Params; Params.push_back(ObjCTypes.ObjectPtrTy); @@ -455,10 +443,10 @@ llvm::Value *CGObjCMac::GenerateMessageSend(llvm::IRBuilder<> &Builder, true); llvm::Type *PCallFTy = llvm::PointerType::getUnqual(CallFTy); llvm::Constant *C = llvm::ConstantExpr::getBitCast(F, PCallFTy); - llvm::CallInst *CI = Builder.CreateCall(C, - Args, Args+ArgC+2, "tmp"); - delete[] Args; - return Builder.CreateBitCast(CI, ReturnTy, "tmp"); + return CGF.EmitCallExprExt(C, E->getType(), + E->arg_begin(), + E->arg_end(), + Args, 2); } llvm::Value *CGObjCMac::GenerateProtocolRef(llvm::IRBuilder<> &Builder, @@ -1185,7 +1173,7 @@ llvm::Function *CGObjCMac::GenerateMethod(const ObjCMethodDecl *OMD) { i = OMD->param_begin(), e = OMD->param_end(); i != e; ++i) { const llvm::Type *Ty = CGM.getTypes().ConvertType((*i)->getType()); - if (Ty->isFirstClassType()) { + if (Ty->isSingleValueType()) { ArgTys.push_back(Ty); } else { ArgTys.push_back(llvm::PointerType::getUnqual(Ty)); @@ -1203,8 +1191,21 @@ llvm::Function *CGObjCMac::GenerateMethod(const ObjCMethodDecl *OMD) { Name, &CGM.getModule()); - if (useStructRet) + unsigned Offset = 3; // Return plus self and selector implicit args. + if (useStructRet) { Method->addParamAttr(1, llvm::ParamAttr::StructRet); + ++Offset; + } + + // FIXME: This is horrible, we need to be reusing the machinery in + // CodeGenModule.cpp (SetFunctionAttributes). + for (ObjCMethodDecl::param_const_iterator + i = OMD->param_begin(), e = OMD->param_end(); + i != e; ++i, ++Offset) { + const llvm::Type *Ty = CGM.getTypes().ConvertType((*i)->getType()); + if (!Ty->isSingleValueType()) + Method->addParamAttr(Offset, llvm::ParamAttr::ByVal); + } return Method; } diff --git a/lib/CodeGen/CGObjCRuntime.h b/lib/CodeGen/CGObjCRuntime.h index 368e5ae105..4a1acda546 100644 --- a/lib/CodeGen/CGObjCRuntime.h +++ b/lib/CodeGen/CGObjCRuntime.h @@ -20,6 +20,8 @@ #include "llvm/Support/IRBuilder.h" #include <string> +#include "CGValue.h" + namespace llvm { class Constant; class Type; @@ -29,9 +31,14 @@ namespace llvm { } namespace clang { + namespace CodeGen { + class CodeGenFunction; + } + class ObjCCategoryImplDecl; class ObjCImplementationDecl; class ObjCInterfaceDecl; + class ObjCMessageExpr; class ObjCMethodDecl; class ObjCProtocolDecl; class Selector; @@ -70,23 +77,18 @@ public: virtual void GenerateClass(const ObjCImplementationDecl *OID) = 0; /// Generate an Objective-C message send operation. - virtual llvm::Value *GenerateMessageSend(BuilderType &Builder, - const llvm::Type *ReturnTy, - llvm::Value *Receiver, - Selector Sel, - llvm::Value** ArgV, - unsigned ArgC) = 0; + virtual CodeGen::RValue + GenerateMessageSend(CodeGen::CodeGenFunction &CGF, + const ObjCMessageExpr *E, + llvm::Value *Receiver) = 0; /// Generate an Objective-C message send operation to the super /// class. - virtual llvm::Value * - GenerateMessageSendSuper(llvm::IRBuilder<true> &Builder, - const llvm::Type *ReturnTy, - const ObjCInterfaceDecl *SuperClassName, - llvm::Value *Receiver, - Selector Sel, - llvm::Value** ArgV, - unsigned ArgC) = 0; + virtual CodeGen::RValue + GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, + const ObjCMessageExpr *E, + const ObjCInterfaceDecl *SuperClass, + llvm::Value *Receiver) = 0; /// Emit the code to return the named protocol as an object, as in a /// @protocol expression. diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index f13cba2a44..37b242e29e 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -24,13 +24,13 @@ #include <vector> #include <map> +#include "CGValue.h" + namespace llvm { class BasicBlock; class Module; } -#include "CGValue.h" - namespace clang { class ASTContext; class Decl; @@ -286,6 +286,13 @@ public: CallExpr::const_arg_iterator ArgBeg, CallExpr::const_arg_iterator ArgEnd); + RValue EmitCallExprExt(llvm::Value *Callee, + QualType ResultType, + CallExpr::const_arg_iterator ArgBeg, + CallExpr::const_arg_iterator ArgEnd, + llvm::Value **ExtraArgs, + unsigned NumExtraArgs); + RValue EmitBuiltinExpr(unsigned BuiltinID, const CallExpr *E); llvm::Value *EmitX86BuiltinExpr(unsigned BuiltinID, const CallExpr *E); @@ -298,7 +305,7 @@ public: llvm::Value *EmitObjCProtocolExpr(const ObjCProtocolExpr *E); llvm::Value *EmitObjCStringLiteral(const ObjCStringLiteral *E); llvm::Value *EmitObjCSelectorExpr(const ObjCSelectorExpr *E); - llvm::Value *EmitObjCMessageExpr(const ObjCMessageExpr *E); + RValue EmitObjCMessageExpr(const ObjCMessageExpr *E); //===--------------------------------------------------------------------===// |