diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/AST/StmtDumper.cpp | 13 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 18 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExprAgg.cpp | 28 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExprComplex.cpp | 7 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGObjC.cpp | 34 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGObjCGNU.cpp | 24 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGObjCMac.cpp | 30 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGObjCRuntime.h | 6 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 18 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 7 |
10 files changed, 139 insertions, 46 deletions
diff --git a/clang/lib/AST/StmtDumper.cpp b/clang/lib/AST/StmtDumper.cpp index 0ccf2017542..af19b61cd64 100644 --- a/clang/lib/AST/StmtDumper.cpp +++ b/clang/lib/AST/StmtDumper.cpp @@ -136,6 +136,7 @@ namespace { void VisitObjCMessageExpr(ObjCMessageExpr* Node); void VisitObjCSelectorExpr(ObjCSelectorExpr *Node); void VisitObjCProtocolExpr(ObjCProtocolExpr *Node); + void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node); void VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node); }; } @@ -449,6 +450,18 @@ void StmtDumper::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) { fprintf(F, " "); fprintf(F, "%s", Node->getProtocol()->getName()); } + +void StmtDumper::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) { + DumpExpr(Node); + + if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(Node->getDecl())) { + fprintf(F, " MethodDecl=\"%s\"", MD->getSelector().getName().c_str()); + } else { + ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(Node->getDecl()); + fprintf(F, " PropertyDecl=\"%s\"", PD->getName()); + } +} + //===----------------------------------------------------------------------===// // Stmt method implementations //===----------------------------------------------------------------------===// diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index c8aa26155e2..e1893493b06 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -830,6 +830,24 @@ RValue CodeGenFunction::EmitCallExpr(llvm::Value *Callee, QualType FnType, 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; diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index d335ea9c3fb..11eb9fc1157 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -264,14 +264,26 @@ void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) { && "Invalid assignment"); LValue LHS = CGF.EmitLValue(E->getLHS()); - // Codegen the RHS so that it stores directly into the LHS. - CGF.EmitAggExpr(E->getRHS(), LHS.getAddress(), false /*FIXME: VOLATILE LHS*/); - - if (DestPtr == 0) - return; - - // If the result of the assignment is used, copy the RHS there also. - EmitAggregateCopy(DestPtr, LHS.getAddress(), E->getType()); + // We have to special case property setters, otherwise we must have + // a simple lvalue (no aggregates inside vectors, bitfields). + if (LHS.isPropertyRef()) { + // FIXME: Volatility? + llvm::Value *AggLoc = DestPtr; + if (!AggLoc) + AggLoc = CGF.CreateTempAlloca(CGF.ConvertType(E->getRHS()->getType())); + CGF.EmitAggExpr(E->getRHS(), AggLoc, false); + CGF.EmitObjCPropertySet(LHS.getPropertyRefExpr(), + RValue::getAggregate(AggLoc)); + } else { + // Codegen the RHS so that it stores directly into the LHS. + CGF.EmitAggExpr(E->getRHS(), LHS.getAddress(), false /*FIXME: VOLATILE LHS*/); + + if (DestPtr == 0) + return; + + // If the result of the assignment is used, copy the RHS there also. + EmitAggregateCopy(DestPtr, LHS.getAddress(), E->getType()); + } } void AggExprEmitter::VisitConditionalOperator(const ConditionalOperator *E) { diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp index 3e1f695c79e..abd0ca8527e 100644 --- a/clang/lib/CodeGen/CGExprComplex.cpp +++ b/clang/lib/CodeGen/CGExprComplex.cpp @@ -546,6 +546,13 @@ void CodeGenFunction::EmitComplexExprIntoAddr(const Expr *E, Emitter.EmitStoreOfComplex(Val, DestAddr, DestIsVolatile); } +/// StoreComplexToAddr - Store a complex number into the specified address. +void CodeGenFunction::StoreComplexToAddr(ComplexPairTy V, + llvm::Value *DestAddr, + bool DestIsVolatile) { + ComplexExprEmitter(*this).EmitStoreOfComplex(V, DestAddr, DestIsVolatile); +} + /// LoadComplexFromAddr - Load a complex number from the specified address. ComplexPairTy CodeGenFunction::LoadComplexFromAddr(llvm::Value *SrcAddr, bool SrcIsVolatile) { diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp index 2a808f8e059..79b50114b77 100644 --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -86,13 +86,15 @@ RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) { if (isSuperMessage) { // super is only valid in an Objective-C method const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl); - return Runtime.GenerateMessageSendSuper(*this, E, + return Runtime.GenerateMessageSendSuper(*this, E->getType(), + E->getSelector(), OMD->getClassInterface(), Receiver, isClassMessage, Args); } - return Runtime.GenerateMessageSend(*this, E, Receiver, isClassMessage, Args); + return Runtime.GenerateMessageSend(*this, E->getType(), E->getSelector(), + Receiver, isClassMessage, Args); } /// StartObjCMethod - Begin emission of an ObjCMethod. This generates @@ -234,20 +236,28 @@ RValue CodeGenFunction::EmitObjCPropertyGet(const ObjCPropertyRefExpr *E) { S = cast<ObjCPropertyDecl>(E->getDecl())->getGetterName(); } - // FIXME: Improve location information. - SourceLocation Loc = E->getLocation(); - // PropertyRefExprs are always instance messages. - // FIXME: Is there any reason to try and pass the method here? - ObjCMessageExpr GetExpr(const_cast<Expr*>(E->getBase()), - S, E->getType(), 0, Loc, Loc, - 0, 0); - - return EmitObjCMessageExpr(&GetExpr); + return CGM.getObjCRuntime(). + GenerateMessageSend(*this, E->getType(), S, + EmitScalarExpr(E->getBase()), + false, CallArgList()); } void CodeGenFunction::EmitObjCPropertySet(const ObjCPropertyRefExpr *E, RValue Src) { - ErrorUnsupported(E, "Objective-C property setter call"); + Selector S; + if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(E->getDecl())) { + S = PD->getSetterName(); + } else { + // FIXME: How can we have a method decl here? + ErrorUnsupported(E, "Objective-C property setter call"); + return; + } + + CallArgList Args; + EmitCallArg(Src, E->getType(), Args); + CGM.getObjCRuntime().GenerateMessageSend(*this, getContext().VoidTy, S, + EmitScalarExpr(E->getBase()), + false, Args); } CGObjCRuntime::~CGObjCRuntime() {} diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp index e5a5d053314..4565fbfeb0e 100644 --- a/clang/lib/CodeGen/CGObjCGNU.cpp +++ b/clang/lib/CodeGen/CGObjCGNU.cpp @@ -96,13 +96,15 @@ public: virtual llvm::Constant *GenerateConstantString(const std::string &String); virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF, - const ObjCMessageExpr *E, + QualType ResultType, + Selector Sel, llvm::Value *Receiver, bool IsClassMessage, const CallArgList &CallArgs); virtual CodeGen::RValue GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, - const ObjCMessageExpr *E, + QualType ResultType, + Selector Sel, const ObjCInterfaceDecl *Class, llvm::Value *Receiver, bool IsClassMessage, @@ -239,16 +241,17 @@ llvm::Constant *CGObjCGNU::GenerateConstantString(const std::string &Str) { ///should be called. CodeGen::RValue CGObjCGNU::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, - const ObjCMessageExpr *E, + QualType ResultType, + Selector Sel, const ObjCInterfaceDecl *Class, llvm::Value *Receiver, bool IsClassMessage, const CallArgList &CallArgs) { const ObjCInterfaceDecl *SuperClass = Class->getSuperClass(); - const llvm::Type *ReturnTy = CGM.getTypes().ConvertType(E->getType()); + const llvm::Type *ReturnTy = CGM.getTypes().ConvertType(ResultType); // TODO: This should be cached, not looked up every time. llvm::Value *ReceiverClass = GetClass(CGF.Builder, SuperClass); - llvm::Value *cmd = GetSelector(CGF.Builder, E->getSelector()); + llvm::Value *cmd = GetSelector(CGF.Builder, Sel); std::vector<const llvm::Type*> impArgTypes; impArgTypes.push_back(Receiver->getType()); impArgTypes.push_back(SelectorTy); @@ -282,18 +285,19 @@ CGObjCGNU::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, ActualArgs.push_back(std::make_pair(cmd, CGF.getContext().getObjCSelType())); ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end()); - return CGF.EmitCall(imp, E->getType(), ActualArgs); + return CGF.EmitCall(imp, ResultType, ActualArgs); } /// Generate code for a message send expression. CodeGen::RValue CGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF, - const ObjCMessageExpr *E, + QualType ResultType, + Selector Sel, llvm::Value *Receiver, bool IsClassMessage, const CallArgList &CallArgs) { - const llvm::Type *ReturnTy = CGM.getTypes().ConvertType(E->getType()); - llvm::Value *cmd = GetSelector(CGF.Builder, E->getSelector()); + const llvm::Type *ReturnTy = CGM.getTypes().ConvertType(ResultType); + llvm::Value *cmd = GetSelector(CGF.Builder, Sel); // Look up the method implementation. std::vector<const llvm::Type*> impArgTypes; @@ -328,7 +332,7 @@ CGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF, ActualArgs.push_back(std::make_pair(cmd, CGF.getContext().getObjCSelType())); ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end()); - return CGF.EmitCall(imp, E->getType(), ActualArgs); + return CGF.EmitCall(imp, ResultType, ActualArgs); } /// Generates a MethodList. Used in construction of a objc_class and diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 3b4309d8941..ef4196e11fc 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -219,7 +219,8 @@ private: const ObjCInterfaceDecl *ID); CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF, - const ObjCMessageExpr *E, + QualType ResultType, + Selector Sel, llvm::Value *Arg0, QualType Arg0Ty, bool IsSuper, @@ -337,14 +338,16 @@ public: virtual llvm::Constant *GenerateConstantString(const std::string &String); virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF, - const ObjCMessageExpr *E, + QualType ResultType, + Selector Sel, llvm::Value *Receiver, bool IsClassMessage, const CallArgList &CallArgs); virtual CodeGen::RValue GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, - const ObjCMessageExpr *E, + QualType ResultType, + Selector Sel, const ObjCInterfaceDecl *Class, llvm::Value *Receiver, bool IsClassMessage, @@ -428,7 +431,8 @@ llvm::Constant *CGObjCMac::GenerateConstantString(const std::string &String) { /// which class's method should be called. CodeGen::RValue CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, - const ObjCMessageExpr *E, + QualType ResultType, + Selector Sel, const ObjCInterfaceDecl *Class, llvm::Value *Receiver, bool IsClassMessage, @@ -460,34 +464,35 @@ CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, CGF.Builder.CreateStore(Target, CGF.Builder.CreateStructGEP(ObjCSuper, 1)); - return EmitMessageSend(CGF, E, + return EmitMessageSend(CGF, ResultType, Sel, ObjCSuper, ObjCTypes.SuperPtrCTy, true, CallArgs); } /// Generate code for a message send expression. CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF, - const ObjCMessageExpr *E, + QualType ResultType, + Selector Sel, llvm::Value *Receiver, bool IsClassMessage, const CallArgList &CallArgs) { llvm::Value *Arg0 = CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy, "tmp"); - return EmitMessageSend(CGF, E, + return EmitMessageSend(CGF, ResultType, Sel, Arg0, CGF.getContext().getObjCIdType(), false, CallArgs); } CodeGen::RValue CGObjCMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF, - const ObjCMessageExpr *E, + QualType ResultType, + Selector Sel, llvm::Value *Arg0, QualType Arg0Ty, bool IsSuper, const CallArgList &CallArgs) { CallArgList ActualArgs; ActualArgs.push_back(std::make_pair(Arg0, Arg0Ty)); - ActualArgs.push_back(std::make_pair(EmitSelector(CGF.Builder, - E->getSelector()), + ActualArgs.push_back(std::make_pair(EmitSelector(CGF.Builder, Sel), CGF.getContext().getObjCSelType())); ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end()); @@ -496,10 +501,9 @@ CodeGen::RValue CGObjCMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF, // parameter and set the structure return flag. See // getMessageSendFn(). - const llvm::Type *ReturnTy = CGM.getTypes().ConvertType(E->getType()); + const llvm::Type *ReturnTy = CGM.getTypes().ConvertType(ResultType); return CGF.EmitCall(ObjCTypes.getMessageSendFn(IsSuper, ReturnTy), - E->getType(), - ActualArgs); + ResultType, ActualArgs); } llvm::Value *CGObjCMac::GenerateProtocolRef(llvm::IRBuilder<> &Builder, diff --git a/clang/lib/CodeGen/CGObjCRuntime.h b/clang/lib/CodeGen/CGObjCRuntime.h index 54591a331c6..c0044e9a94d 100644 --- a/clang/lib/CodeGen/CGObjCRuntime.h +++ b/clang/lib/CodeGen/CGObjCRuntime.h @@ -81,7 +81,8 @@ public: /// Generate an Objective-C message send operation. virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF, - const ObjCMessageExpr *E, + QualType ResultType, + Selector Sel, llvm::Value *Receiver, bool IsClassMessage, const CallArgList &CallArgs) = 0; @@ -91,7 +92,8 @@ public: /// object. virtual CodeGen::RValue GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, - const ObjCMessageExpr *E, + QualType ResultType, + Selector Sel, const ObjCInterfaceDecl *Class, llvm::Value *Self, bool IsClassMessage, diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index e00c66552f6..c8421e609a5 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -299,8 +299,22 @@ public: // Scalar Expression Emission //===--------------------------------------------------------------------===// + /// CallArgList - Type for representing both the value and type of + /// arguments in a call. typedef llvm::SmallVector<std::pair<llvm::Value*, QualType>, 16> CallArgList; + + /// 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 + /// derived from. RValue EmitCall(llvm::Value *Callee, QualType ResultType, const CallArgList &Args); @@ -366,6 +380,10 @@ public: /// of complex type, storing into the specified Value*. void EmitComplexExprIntoAddr(const Expr *E, llvm::Value *DestAddr, bool DestIsVolatile); + + /// StoreComplexToAddr - Store a complex number into the specified address. + void StoreComplexToAddr(ComplexPairTy V, llvm::Value *DestAddr, + bool DestIsVolatile); /// LoadComplexFromAddr - Load a complex number from the specified address. ComplexPairTy LoadComplexFromAddr(llvm::Value *SrcAddr, bool SrcIsVolatile); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 5169ce13111..ba13e7fe66c 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -869,7 +869,11 @@ ActOnMemberReferenceExpr(ExprTy *Base, SourceLocation OpLoc, // FIXME: The logic for looking up nullary and unary selectors should be // shared with the code in ActOnInstanceMessage. - + + // FIXME: This logic is not correct, we should search for + // properties first. Additionally, the AST node doesn't currently + // have enough information to store the setter argument. +#if 0 // Before we look for explicit property declarations, we check for // nullary methods (which allow '.' notation). Selector Sel = PP.getSelectorTable().getNullarySelector(&Member); @@ -886,6 +890,7 @@ ActOnMemberReferenceExpr(ExprTy *Base, SourceLocation OpLoc, return new ObjCPropertyRefExpr(MD, MD->getResultType(), MemberLoc, BaseExpr); } +#endif // FIXME: Need to deal with setter methods that take 1 argument. E.g.: // @interface NSBundle : NSObject {} |