From: John McCall Date: Thu, 2 Dec 2010 01:19:52 +0000 (+0000) Subject: Simplify the ASTs by consolidating ObjCImplicitGetterSetterExpr and ObjCPropertyRefExpr X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=12f78a6741a4cb3d904340f8d3d2714568b50e7a;p=clang Simplify the ASTs by consolidating ObjCImplicitGetterSetterExpr and ObjCPropertyRefExpr into the latter. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@120643 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h index 75e02e768e..c0f4c1b750 100644 --- a/include/clang/AST/ExprObjC.h +++ b/include/clang/AST/ExprObjC.h @@ -14,14 +14,13 @@ #ifndef LLVM_CLANG_AST_EXPROBJC_H #define LLVM_CLANG_AST_EXPROBJC_H +#include "clang/AST/DeclObjC.h" #include "clang/AST/Expr.h" #include "clang/Basic/IdentifierTable.h" namespace clang { class IdentifierInfo; class ASTContext; - class ObjCMethodDecl; - class ObjCPropertyDecl; /// ObjCStringLiteral, used for Objective-C string literals /// i.e. @"foo". @@ -229,17 +228,20 @@ public: /// class ObjCPropertyRefExpr : public Expr { private: - ObjCPropertyDecl *AsProperty; + /// If the bool is true, this is an implicit property reference; the + /// pointer is an (optional) ObjCMethodDecl and Setter may be set. + /// if the bool is false, this is an explicit property reference; + /// the pointer is an ObjCPropertyDecl and Setter is always null. + llvm::PointerIntPair PropertyOrGetter; + ObjCMethodDecl *Setter; + SourceLocation IdLoc; /// \brief When the receiver in property access is 'super', this is - /// the location of the 'super' keyword. - SourceLocation SuperLoc; - - /// \brief When the receiver in property access is 'super', this is - /// the type associated with 'super' keyword. A null type indicates - /// that this is not a 'super' receiver. - llvm::PointerUnion BaseExprOrSuperType; + /// the location of the 'super' keyword. When it's an interface, + /// this is that interface. + SourceLocation ReceiverLoc; + llvm::PointerUnion3 Receiver; public: ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, @@ -247,44 +249,103 @@ public: SourceLocation l, Expr *base) : Expr(ObjCPropertyRefExprClass, t, VK, OK, /*TypeDependent=*/false, base->isValueDependent()), - AsProperty(PD), IdLoc(l), BaseExprOrSuperType(base) { + PropertyOrGetter(PD, false), Setter(0), + IdLoc(l), ReceiverLoc(), Receiver(base) { } ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, ExprValueKind VK, ExprObjectKind OK, SourceLocation l, SourceLocation sl, QualType st) - : Expr(ObjCPropertyRefExprClass, t, VK, OK, - /*TypeDependent=*/false, false), - AsProperty(PD), IdLoc(l), SuperLoc(sl), - BaseExprOrSuperType(st.getTypePtr()) { + : Expr(ObjCPropertyRefExprClass, t, VK, OK, + /*TypeDependent=*/false, false), + PropertyOrGetter(PD, false), Setter(0), + IdLoc(l), ReceiverLoc(sl), Receiver(st.getTypePtr()) { + } + + ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter, + QualType T, ExprValueKind VK, ExprObjectKind OK, + SourceLocation IdLoc, Expr *Base) + : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, + Base->isValueDependent()), + PropertyOrGetter(Getter, true), Setter(Setter), + IdLoc(IdLoc), ReceiverLoc(), Receiver(Base) { + } + + ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter, + QualType T, ExprValueKind VK, ExprObjectKind OK, + SourceLocation IdLoc, + SourceLocation SuperLoc, QualType SuperTy) + : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false), + PropertyOrGetter(Getter, true), Setter(Setter), + IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) { + } + + ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter, + QualType T, ExprValueKind VK, ExprObjectKind OK, + SourceLocation IdLoc, + SourceLocation ReceiverLoc, ObjCInterfaceDecl *Receiver) + : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false), + PropertyOrGetter(Getter, true), Setter(Setter), + IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) { } explicit ObjCPropertyRefExpr(EmptyShell Empty) : Expr(ObjCPropertyRefExprClass, Empty) {} - ObjCPropertyDecl *getProperty() const { return AsProperty; } + bool isImplicitProperty() const { return PropertyOrGetter.getInt(); } + bool isExplicitProperty() const { return !PropertyOrGetter.getInt(); } + + ObjCPropertyDecl *getExplicitProperty() const { + assert(!isImplicitProperty()); + return cast(PropertyOrGetter.getPointer()); + } + + ObjCMethodDecl *getImplicitPropertyGetter() const { + assert(isImplicitProperty()); + return cast_or_null(PropertyOrGetter.getPointer()); + } + + ObjCMethodDecl *getImplicitPropertySetter() const { + assert(isImplicitProperty()); + return Setter; + } + + Selector getGetterSelector() const { + if (isImplicitProperty()) + return getImplicitPropertyGetter()->getSelector(); + return getExplicitProperty()->getGetterName(); + } + + Selector getSetterSelector() const { + if (isImplicitProperty()) + return getImplicitPropertySetter()->getSelector(); + return getExplicitProperty()->getSetterName(); + } const Expr *getBase() const { - return cast(BaseExprOrSuperType.get()); + return cast(Receiver.get()); } Expr *getBase() { - return cast(BaseExprOrSuperType.get()); + return cast(Receiver.get()); } SourceLocation getLocation() const { return IdLoc; } - SourceLocation getSuperLocation() const { return SuperLoc; } - QualType getSuperType() const { - Type *t = BaseExprOrSuperType.get(); - return QualType(t, 0); + SourceLocation getReceiverLocation() const { return ReceiverLoc; } + QualType getSuperReceiverType() const { + return QualType(Receiver.get(), 0); + } + ObjCInterfaceDecl *getClassReceiver() const { + return Receiver.get(); } - bool isSuperReceiver() const { return BaseExprOrSuperType.is(); } + bool isObjectReceiver() const { return Receiver.is(); } + bool isSuperReceiver() const { return Receiver.is(); } + bool isClassReceiver() const { return Receiver.is(); } virtual SourceRange getSourceRange() const { - return SourceRange( - (BaseExprOrSuperType.is() ? getBase()->getLocStart() - : getSuperLocation()), - IdLoc); + return SourceRange((isObjectReceiver() ? getBase()->getLocStart() + : getReceiverLocation()), + IdLoc); } static bool classof(const Stmt *T) { @@ -297,125 +358,22 @@ public: virtual child_iterator child_end(); private: friend class ASTStmtReader; - void setProperty(ObjCPropertyDecl *D) { AsProperty = D; } - void setBase(Expr *base) { BaseExprOrSuperType = base; } - void setLocation(SourceLocation L) { IdLoc = L; } - void setSuperLocation(SourceLocation Loc) { SuperLoc = Loc; } - void setSuperType(QualType T) { BaseExprOrSuperType = T.getTypePtr(); } -}; - -/// ObjCImplicitSetterGetterRefExpr - A dot-syntax expression to access two -/// methods; one to set a value to an 'ivar' (Setter) and the other to access -/// an 'ivar' (Setter). -/// An example for use of this AST is: -/// @code -/// @interface Test { } -/// - (Test *)crash; -/// - (void)setCrash: (Test*)value; -/// @end -/// void foo(Test *p1, Test *p2) -/// { -/// p2.crash = p1.crash; // Uses ObjCImplicitSetterGetterRefExpr AST -/// } -/// @endcode -class ObjCImplicitSetterGetterRefExpr : public Expr { - /// Setter - Setter method user declared for setting its 'ivar' to a value - ObjCMethodDecl *Setter; - /// Getter - Getter method user declared for accessing 'ivar' it controls. - ObjCMethodDecl *Getter; - /// Location of the member in the dot syntax notation. This is location - /// of the getter method. - SourceLocation MemberLoc; - // FIXME: Swizzle these into a single pointer. - Stmt *Base; - ObjCInterfaceDecl *InterfaceDecl; - /// \brief Location of the receiver class in the dot syntax notation - /// used to call a class method setter/getter. - SourceLocation ClassLoc; - - /// \brief When the receiver in dot-syntax expression is 'super', - /// this is the location of the 'super' keyword. - SourceLocation SuperLoc; - - /// \brief When the receiver in dot-syntax expression is 'super', this is - /// the type associated with 'super' keyword. - QualType SuperTy; - -public: - ObjCImplicitSetterGetterRefExpr(ObjCMethodDecl *getter, QualType t, - ExprValueKind VK, ExprObjectKind OK, - ObjCMethodDecl *setter, - SourceLocation l, Expr *base) - : Expr(ObjCImplicitSetterGetterRefExprClass, t, VK, OK, - /*TypeDependent=*/false, base->isValueDependent()), - Setter(setter), Getter(getter), MemberLoc(l), Base(base), - InterfaceDecl(0), ClassLoc(SourceLocation()) {} - - ObjCImplicitSetterGetterRefExpr(ObjCMethodDecl *getter, QualType t, - ExprValueKind VK, ExprObjectKind OK, - ObjCMethodDecl *setter, - SourceLocation l, - SourceLocation sl, - QualType st) - : Expr(ObjCImplicitSetterGetterRefExprClass, t, VK, OK, - /*TypeDependent=*/false, false), - Setter(setter), Getter(getter), MemberLoc(l), - Base(0), InterfaceDecl(0), ClassLoc(SourceLocation()), - SuperLoc(sl), SuperTy(st) { + void setExplicitProperty(ObjCPropertyDecl *D) { + PropertyOrGetter.setPointer(D); + PropertyOrGetter.setInt(false); + Setter = 0; } - - ObjCImplicitSetterGetterRefExpr(ObjCMethodDecl *getter, QualType t, - ExprValueKind VK, ExprObjectKind OK, - ObjCMethodDecl *setter, - SourceLocation l, ObjCInterfaceDecl *C, SourceLocation CL) - : Expr(ObjCImplicitSetterGetterRefExprClass, t, VK, OK, false, false), - Setter(setter), Getter(getter), MemberLoc(l), Base(0), InterfaceDecl(C), - ClassLoc(CL) {} - explicit ObjCImplicitSetterGetterRefExpr(EmptyShell Empty) - : Expr(ObjCImplicitSetterGetterRefExprClass, Empty){} - - ObjCMethodDecl *getGetterMethod() const { return Getter; } - ObjCMethodDecl *getSetterMethod() const { return Setter; } - ObjCInterfaceDecl *getInterfaceDecl() const { return InterfaceDecl; } - void setGetterMethod(ObjCMethodDecl *D) { Getter = D; } - void setSetterMethod(ObjCMethodDecl *D) { Setter = D; } - void setInterfaceDecl(ObjCInterfaceDecl *D) { InterfaceDecl = D; } - - virtual SourceRange getSourceRange() const { - if (isSuperReceiver()) - return SourceRange(getSuperLocation(), MemberLoc); - if (Base) - return SourceRange(getBase()->getLocStart(), MemberLoc); - return SourceRange(ClassLoc, MemberLoc); - } - const Expr *getBase() const { return cast_or_null(Base); } - Expr *getBase() { return cast_or_null(Base); } - void setBase(Expr *base) { Base = base; } - - SourceLocation getLocation() const { return MemberLoc; } - void setLocation(SourceLocation L) { MemberLoc = L; } - SourceLocation getClassLoc() const { return ClassLoc; } - void setClassLoc(SourceLocation L) { ClassLoc = L; } - - SourceLocation getSuperLocation() const { return SuperLoc; } - QualType getSuperType() const { return SuperTy; } - /// \brief When the receiver in dot-syntax expression is 'super', this - /// method returns true if both Base expression and Interface are null. - bool isSuperReceiver() const { return InterfaceDecl == 0 && Base == 0; } - - static bool classof(const Stmt *T) { - return T->getStmtClass() == ObjCImplicitSetterGetterRefExprClass; + void setImplicitProperty(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter) { + PropertyOrGetter.setPointer(Getter); + PropertyOrGetter.setInt(true); + this->Setter = Setter; } - static bool classof(const ObjCImplicitSetterGetterRefExpr *) { return true; } + void setBase(Expr *Base) { Receiver = Base; } + void setSuperReceiver(QualType T) { Receiver = T.getTypePtr(); } + void setClassReceiver(ObjCInterfaceDecl *D) { Receiver = D; } - // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); - -private: - friend class ASTStmtReader; - void setSuperLocation(SourceLocation Loc) { SuperLoc = Loc; } - void setSuperType(QualType T) { SuperTy = T; } + void setLocation(SourceLocation L) { IdLoc = L; } + void setReceiverLocation(SourceLocation Loc) { ReceiverLoc = Loc; } }; /// \brief An expression that sends a message to the given Objective-C diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index f05ab931ec..8c70e114f9 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -1778,7 +1778,6 @@ DEF_TRAVERSE_STMT(ExtVectorElementExpr, { }) DEF_TRAVERSE_STMT(GNUNullExpr, { }) DEF_TRAVERSE_STMT(ImplicitValueInitExpr, { }) DEF_TRAVERSE_STMT(ObjCEncodeExpr, { }) -DEF_TRAVERSE_STMT(ObjCImplicitSetterGetterRefExpr, { }) DEF_TRAVERSE_STMT(ObjCIsaExpr, { }) DEF_TRAVERSE_STMT(ObjCIvarRefExpr, { }) DEF_TRAVERSE_STMT(ObjCMessageExpr, { }) diff --git a/include/clang/Basic/StmtNodes.td b/include/clang/Basic/StmtNodes.td index c9ec0ef148..b837368841 100644 --- a/include/clang/Basic/StmtNodes.td +++ b/include/clang/Basic/StmtNodes.td @@ -120,7 +120,6 @@ def ObjCSelectorExpr : DStmt; def ObjCProtocolExpr : DStmt; def ObjCIvarRefExpr : DStmt; def ObjCPropertyRefExpr : DStmt; -def ObjCImplicitSetterGetterRefExpr : DStmt; def ObjCIsaExpr : DStmt; // Clang Extensions. diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h index 9a0fec7b12..bc3ac7357b 100644 --- a/include/clang/Serialization/ASTBitCodes.h +++ b/include/clang/Serialization/ASTBitCodes.h @@ -853,7 +853,7 @@ namespace clang { EXPR_OBJC_IVAR_REF_EXPR, /// \brief An ObjCPropertyRefExpr record. EXPR_OBJC_PROPERTY_REF_EXPR, - /// \brief An ObjCImplicitSetterGetterRefExpr record. + /// \brief UNUSED EXPR_OBJC_KVC_REF_EXPR, /// \brief An ObjCMessageExpr record. EXPR_OBJC_MESSAGE_EXPR, diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 6e56603c53..265788a081 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -1338,21 +1338,11 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1, return false; } - case ObjCImplicitSetterGetterRefExprClass: { // Dot syntax for message send. -#if 0 - const ObjCImplicitSetterGetterRefExpr *Ref = - cast(this); - // FIXME: We really want the location of the '.' here. - Loc = Ref->getLocation(); - R1 = SourceRange(Ref->getLocation(), Ref->getLocation()); - if (Ref->getBase()) - R2 = Ref->getBase()->getSourceRange(); -#else + case ObjCPropertyRefExprClass: Loc = getExprLoc(); R1 = getSourceRange(); -#endif return true; - } + case StmtExprClass: { // Statement exprs don't logically have side effects themselves, but are // sometimes used in macros in ways that give them a type that is unused. @@ -1635,7 +1625,6 @@ Expr::CanThrowResult Expr::CanThrow(ASTContext &C) const { // specs. case ObjCMessageExprClass: case ObjCPropertyRefExprClass: - case ObjCImplicitSetterGetterRefExprClass: return CT_Can; // Many other things have subexpressions, so we have to test those. @@ -1838,8 +1827,7 @@ bool Expr::isTemporaryObject(ASTContext &C, const CXXRecordDecl *TempTy) const { // Temporaries are by definition pr-values of class type. if (!E->Classify(C).isPRValue()) { // In this context, property reference is a message call and is pr-value. - if (!isa(E) && - !isa(E)) + if (!isa(E)) return false; } @@ -2537,33 +2525,19 @@ Stmt::child_iterator ObjCIvarRefExpr::child_end() { return &Base+1; } // ObjCPropertyRefExpr Stmt::child_iterator ObjCPropertyRefExpr::child_begin() { - if (BaseExprOrSuperType.is()) { + if (Receiver.is()) { // Hack alert! - return reinterpret_cast (&BaseExprOrSuperType); + return reinterpret_cast (&Receiver); } return child_iterator(); } Stmt::child_iterator ObjCPropertyRefExpr::child_end() -{ return BaseExprOrSuperType.is() ? - reinterpret_cast (&BaseExprOrSuperType)+1 : +{ return Receiver.is() ? + reinterpret_cast (&Receiver)+1 : child_iterator(); } -// ObjCImplicitSetterGetterRefExpr -Stmt::child_iterator ObjCImplicitSetterGetterRefExpr::child_begin() { - // If this is accessing a class member or super, skip that entry. - // Technically, 2nd condition is sufficient. But I want to be verbose - if (isSuperReceiver() || !Base) - return child_iterator(); - return &Base; -} -Stmt::child_iterator ObjCImplicitSetterGetterRefExpr::child_end() { - if (isSuperReceiver() || !Base) - return child_iterator(); - return &Base+1; -} - // ObjCIsaExpr Stmt::child_iterator ObjCIsaExpr::child_begin() { return &Base; } Stmt::child_iterator ObjCIsaExpr::child_end() { return &Base+1; } diff --git a/lib/AST/ExprClassification.cpp b/lib/AST/ExprClassification.cpp index 4025f18a3b..e55545e693 100644 --- a/lib/AST/ExprClassification.cpp +++ b/lib/AST/ExprClassification.cpp @@ -104,7 +104,6 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { case Expr::PredefinedExprClass: // Property references are lvalues case Expr::ObjCPropertyRefExprClass: - case Expr::ObjCImplicitSetterGetterRefExprClass: // C++ [expr.typeid]p1: The result of a typeid expression is an lvalue of... case Expr::CXXTypeidExprClass: // Unresolved lookups get classified as lvalues. @@ -195,8 +194,7 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { Cl::Kinds K = ClassifyInternal(Ctx, Op); if (K != Cl::CL_LValue) return K; - if (isa(Op) || - isa(Op)) + if (isa(Op)) return Cl::CL_SubObjCPropertySetting; return Cl::CL_LValue; } @@ -368,8 +366,7 @@ static Cl::Kinds ClassifyMemberExpr(ASTContext &Ctx, const MemberExpr *E) { return Cl::CL_LValue; // ObjC property accesses are not lvalues, but get special treatment. Expr *Base = E->getBase()->IgnoreParens(); - if (isa(Base) || - isa(Base)) + if (isa(Base)) return Cl::CL_SubObjCPropertySetting; return ClassifyInternal(Ctx, Base); } @@ -395,8 +392,7 @@ static Cl::Kinds ClassifyMemberExpr(ASTContext &Ctx, const MemberExpr *E) { if (E->isArrow()) return Cl::CL_LValue; Expr *Base = E->getBase()->IgnoreParenImpCasts(); - if (isa(Base) || - isa(Base)) + if (isa(Base)) return Cl::CL_SubObjCPropertySetting; return ClassifyInternal(Ctx, E->getBase()); } @@ -498,9 +494,8 @@ static Cl::ModifiableType IsModifiable(ASTContext &Ctx, const Expr *E, // Assignment to a property in ObjC is an implicit setter access. But a // setter might not exist. - if (const ObjCImplicitSetterGetterRefExpr *Expr = - dyn_cast(E)) { - if (Expr->getSetterMethod() == 0) + if (const ObjCPropertyRefExpr *Expr = dyn_cast(E)) { + if (Expr->isImplicitProperty() && Expr->getImplicitPropertySetter() == 0) return Cl::CM_NoSetterProperty; } @@ -517,8 +512,7 @@ static Cl::ModifiableType IsModifiable(ASTContext &Ctx, const Expr *E, // Records with any const fields (recursively) are not modifiable. if (const RecordType *R = CT->getAs()) { - assert((isa(E) || - isa(E) || + assert((isa(E) || !Ctx.getLangOptions().CPlusPlus) && "C++ struct assignment should be resolved by the " "copy assignment operator."); diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index f4685933dc..019cfc9b80 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -2506,7 +2506,6 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) { case Expr::ObjCProtocolExprClass: case Expr::ObjCIvarRefExprClass: case Expr::ObjCPropertyRefExprClass: - case Expr::ObjCImplicitSetterGetterRefExprClass: case Expr::ObjCIsaExprClass: case Expr::ShuffleVectorExprClass: case Expr::BlockExprClass: diff --git a/lib/AST/StmtDumper.cpp b/lib/AST/StmtDumper.cpp index 15a8d61c88..6f9a2d574b 100644 --- a/lib/AST/StmtDumper.cpp +++ b/lib/AST/StmtDumper.cpp @@ -172,8 +172,6 @@ namespace { void VisitObjCSelectorExpr(ObjCSelectorExpr *Node); void VisitObjCProtocolExpr(ObjCProtocolExpr *Node); void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node); - void VisitObjCImplicitSetterGetterRefExpr( - ObjCImplicitSetterGetterRefExpr *Node); void VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node); }; } @@ -607,27 +605,19 @@ void StmtDumper::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) { void StmtDumper::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) { DumpExpr(Node); - if (Node->isSuperReceiver()) - OS << " Kind=PropertyRef Property=\"" << Node->getProperty() << '"' - << " super"; - else - OS << " Kind=PropertyRef Property=\"" << Node->getProperty() << '"'; -} - -void StmtDumper::VisitObjCImplicitSetterGetterRefExpr( - ObjCImplicitSetterGetterRefExpr *Node) { - DumpExpr(Node); + if (Node->isImplicitProperty()) { + OS << " Kind=MethodRef Getter=\"" + << Node->getImplicitPropertyGetter()->getSelector().getAsString() + << "\" Setter=\""; + if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter()) + OS << Setter->getSelector().getAsString(); + else + OS << "(null)"; + OS << "\""; + } else { + OS << " Kind=PropertyRef Property=\"" << Node->getExplicitProperty() << '"'; + } - ObjCMethodDecl *Getter = Node->getGetterMethod(); - ObjCMethodDecl *Setter = Node->getSetterMethod(); - OS << " Kind=MethodRef Getter=\"" - << Getter->getSelector().getAsString() - << "\" Setter=\""; - if (Setter) - OS << Setter->getSelector().getAsString(); - else - OS << "(null)"; - OS << "\""; if (Node->isSuperReceiver()) OS << " super"; } diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp index d4791bcd0e..9dfde62deb 100644 --- a/lib/AST/StmtPrinter.cpp +++ b/lib/AST/StmtPrinter.cpp @@ -516,20 +516,10 @@ void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) { OS << "."; } - OS << Node->getProperty()->getName(); -} - -void StmtPrinter::VisitObjCImplicitSetterGetterRefExpr( - ObjCImplicitSetterGetterRefExpr *Node) { - if (Node->isSuperReceiver()) - OS << "super."; - else if (Node->getBase()) { - PrintExpr(Node->getBase()); - OS << "."; - } - if (Node->getGetterMethod()) - OS << Node->getGetterMethod(); - + if (Node->isImplicitProperty()) + OS << Node->getImplicitPropertyGetter()->getSelector().getAsString(); + else + OS << Node->getExplicitProperty()->getName(); } void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) { diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp index d67f5fad6b..7f10bef713 100644 --- a/lib/AST/StmtProfile.cpp +++ b/lib/AST/StmtProfile.cpp @@ -866,22 +866,15 @@ void StmtProfiler::VisitObjCIvarRefExpr(ObjCIvarRefExpr *S) { void StmtProfiler::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *S) { VisitExpr(S); - VisitDecl(S->getProperty()); - if (S->isSuperReceiver()) { - ID.AddBoolean(S->isSuperReceiver()); - VisitType(S->getSuperType()); + if (S->isImplicitProperty()) { + VisitDecl(S->getImplicitPropertyGetter()); + VisitDecl(S->getImplicitPropertySetter()); + } else { + VisitDecl(S->getExplicitProperty()); } -} - -void StmtProfiler::VisitObjCImplicitSetterGetterRefExpr( - ObjCImplicitSetterGetterRefExpr *S) { - VisitExpr(S); - VisitDecl(S->getGetterMethod()); - VisitDecl(S->getSetterMethod()); - VisitDecl(S->getInterfaceDecl()); if (S->isSuperReceiver()) { ID.AddBoolean(S->isSuperReceiver()); - VisitType(S->getSuperType()); + VisitType(S->getSuperReceiverType()); } } diff --git a/lib/Checker/CheckObjCDealloc.cpp b/lib/Checker/CheckObjCDealloc.cpp index 11ddaca9d6..8ee6daa5c8 100644 --- a/lib/Checker/CheckObjCDealloc.cpp +++ b/lib/Checker/CheckObjCDealloc.cpp @@ -76,8 +76,8 @@ static bool scan_ivar_release(Stmt* S, ObjCIvarDecl* ID, if (BinaryOperator* BO = dyn_cast(S)) if (BO->isAssignmentOp()) if (ObjCPropertyRefExpr* PRE = - dyn_cast(BO->getLHS()->IgnoreParenCasts())) - if (PRE->getProperty() == PD) + dyn_cast(BO->getLHS()->IgnoreParenCasts())) + if (PRE->isExplicitProperty() && PRE->getExplicitProperty() == PD) if (BO->getRHS()->isNullPointerConstant(Ctx, Expr::NPC_ValueDependentIsNull)) { // This is only a 'release' if the property kind is not diff --git a/lib/Checker/GRExprEngine.cpp b/lib/Checker/GRExprEngine.cpp index a552447b30..99dcdcff41 100644 --- a/lib/Checker/GRExprEngine.cpp +++ b/lib/Checker/GRExprEngine.cpp @@ -852,7 +852,6 @@ void GRExprEngine::Visit(const Stmt* S, ExplodedNode* Pred, case Stmt::ObjCAtFinallyStmtClass: case Stmt::ObjCAtTryStmtClass: case Stmt::ObjCEncodeExprClass: - case Stmt::ObjCImplicitSetterGetterRefExprClass: case Stmt::ObjCIsaExprClass: case Stmt::ObjCPropertyRefExprClass: case Stmt::ObjCProtocolExprClass: @@ -1221,7 +1220,6 @@ void GRExprEngine::VisitLValue(const Expr* Ex, ExplodedNode* Pred, return; case Stmt::ObjCPropertyRefExprClass: - case Stmt::ObjCImplicitSetterGetterRefExprClass: // FIXME: Property assignments are lvalues, but not really "locations". // e.g.: self.x = something; // Here the "self.x" really can translate to a method call (setter) when @@ -3410,12 +3408,6 @@ void GRExprEngine::VisitBinaryOperator(const BinaryOperator* B, Expr* LHS = B->getLHS()->IgnoreParens(); Expr* RHS = B->getRHS()->IgnoreParens(); - // FIXME: Add proper support for ObjCImplicitSetterGetterRefExpr. - if (isa(LHS)) { - Visit(RHS, Pred, Dst); - return; - } - if (B->isAssignmentOp()) VisitLValue(LHS, Pred, Tmp1); else diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index 8f3e0a6326..b6cd1949cc 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -131,13 +131,6 @@ static void CollectBlockDeclRefInfo(const Stmt *S, CGBlockInfo &Info) { if (PE->isSuperReceiver()) Info.NeedsObjCSelf = true; } - else if (const ObjCImplicitSetterGetterRefExpr *IE = - dyn_cast(S)) { - // Getter/setter uses may also cause implicit super references, - // which we can check for with: - if (IE->isSuperReceiver()) - Info.NeedsObjCSelf = true; - } else if (isa(S)) Info.CXXThisRef = cast(S); } diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 466f55f341..2db6cc8d31 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -549,8 +549,6 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) { return EmitObjCIvarRefLValue(cast(E)); case Expr::ObjCPropertyRefExprClass: return EmitObjCPropertyRefLValue(cast(E)); - case Expr::ObjCImplicitSetterGetterRefExprClass: - return EmitObjCKVCRefLValue(cast(E)); case Expr::StmtExprClass: return EmitStmtExprLValue(cast(E)); case Expr::UnaryOperatorClass: @@ -1569,10 +1567,9 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) { const PointerType *PTy = BaseExpr->getType()->getAs(); BaseQuals = PTy->getPointeeType().getQualifiers(); - } else if (isa(BaseExpr->IgnoreParens()) || - isa( - BaseExpr->IgnoreParens())) { - RValue RV = EmitObjCPropertyGet(BaseExpr); + } else if (ObjCPropertyRefExpr *PRE + = dyn_cast(BaseExpr->IgnoreParens())) { + RValue RV = EmitObjCPropertyGet(PRE); BaseValue = RV.getAggregateAddr(); BaseQuals = BaseExpr->getType().getQualifiers(); } else { @@ -1796,7 +1793,7 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { RValue RV = LV.isPropertyRef() ? EmitLoadOfPropertyRefLValue(LV, QT) : EmitLoadOfKVCRefLValue(LV, QT); - assert(!RV.isScalar() && "EmitCastLValue-scalar cast of property ref"); + assert(RV.isAggregate()); llvm::Value *V = RV.getAggregateAddr(); return MakeAddrLValue(V, QT); } @@ -2107,16 +2104,12 @@ LValue CodeGenFunction::EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E) { LValue CodeGenFunction::EmitObjCPropertyRefLValue(const ObjCPropertyRefExpr *E) { - // This is a special l-value that just issues sends when we load or store - // through it. - return LValue::MakePropertyRef(E, E->getType().getCVRQualifiers()); -} + // This is a special l-value that just issues sends when we load or + // store through it. -LValue CodeGenFunction::EmitObjCKVCRefLValue( - const ObjCImplicitSetterGetterRefExpr *E) { - // This is a special l-value that just issues sends when we load or store - // through it. - return LValue::MakeKVCRef(E, E->getType().getCVRQualifiers()); + if (E->isImplicitProperty()) + return LValue::MakeKVCRef(E, E->getType().getCVRQualifiers()); + return LValue::MakePropertyRef(E, E->getType().getCVRQualifiers()); } LValue CodeGenFunction::EmitStmtExprLValue(const StmtExpr *E) { diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index bd1c43dff5..e19baa97f1 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/lib/CodeGen/CGExprAgg.cpp @@ -115,7 +115,6 @@ public: EmitAggLoadOfLValue(E); } void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E); - void VisitObjCImplicitSetterGetterRefExpr(ObjCImplicitSetterGetterRefExpr *E); void VisitConditionalOperator(const ConditionalOperator *CO); void VisitChooseExpr(const ChooseExpr *CE); @@ -354,12 +353,6 @@ void AggExprEmitter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) { EmitGCMove(E, RV); } -void AggExprEmitter::VisitObjCImplicitSetterGetterRefExpr( - ObjCImplicitSetterGetterRefExpr *E) { - RValue RV = CGF.EmitObjCPropertyGet(E, getReturnValueSlot()); - EmitGCMove(E, RV); -} - void AggExprEmitter::VisitBinComma(const BinaryOperator *E) { CGF.EmitAnyExpr(E->getLHS(), AggValueSlot::ignored(), true); Visit(E->getRHS()); diff --git a/lib/CodeGen/CGExprComplex.cpp b/lib/CodeGen/CGExprComplex.cpp index 26bda79898..5784825d6f 100644 --- a/lib/CodeGen/CGExprComplex.cpp +++ b/lib/CodeGen/CGExprComplex.cpp @@ -113,10 +113,6 @@ public: ComplexPairTy VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) { return EmitLoadOfLValue(E); } - ComplexPairTy VisitObjCImplicitSetterGetterRefExpr( - ObjCImplicitSetterGetterRefExpr *E) { - return EmitLoadOfLValue(E); - } ComplexPairTy VisitObjCMessageExpr(ObjCMessageExpr *E) { return CGF.EmitObjCMessageExpr(E).getComplexVal(); } diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index a46afe6f65..ea23f2d6f2 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -239,10 +239,6 @@ public: Value *VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) { return EmitLoadOfLValue(E); } - Value *VisitObjCImplicitSetterGetterRefExpr( - ObjCImplicitSetterGetterRefExpr *E) { - return EmitLoadOfLValue(E); - } Value *VisitObjCMessageExpr(ObjCMessageExpr *E) { return CGF.EmitObjCMessageExpr(E).getScalarVal(); } diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index 13f4d8f796..095f0cdde5 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -528,36 +528,34 @@ RValue CodeGenFunction::EmitObjCSuperPropertyGet(const Expr *Exp, } -RValue CodeGenFunction::EmitObjCPropertyGet(const Expr *Exp, +RValue CodeGenFunction::EmitObjCPropertyGet(const ObjCPropertyRefExpr *E, ReturnValueSlot Return) { - Exp = Exp->IgnoreParens(); - // FIXME: Split it into two separate routines. - if (const ObjCPropertyRefExpr *E = dyn_cast(Exp)) { - Selector S = E->getProperty()->getGetterName(); - if (E->isSuperReceiver()) - return EmitObjCSuperPropertyGet(E, S, Return); - return CGM.getObjCRuntime(). - GenerateMessageSend(*this, Return, Exp->getType(), S, - EmitScalarExpr(E->getBase()), - CallArgList()); + QualType ResultType; + Selector S; + if (E->isExplicitProperty()) { + const ObjCPropertyDecl *Property = E->getExplicitProperty(); + S = Property->getGetterName(); + ResultType = E->getType(); } else { - const ObjCImplicitSetterGetterRefExpr *KE = - cast(Exp); - Selector S = KE->getGetterMethod()->getSelector(); - llvm::Value *Receiver; - if (KE->getInterfaceDecl()) { - const ObjCInterfaceDecl *OID = KE->getInterfaceDecl(); - Receiver = CGM.getObjCRuntime().GetClass(Builder, OID); - } else if (KE->isSuperReceiver()) - return EmitObjCSuperPropertyGet(KE, S, Return); - else - Receiver = EmitScalarExpr(KE->getBase()); - return CGM.getObjCRuntime(). - GenerateMessageSend(*this, Return, - KE->getGetterMethod()->getResultType(), S, - Receiver, - CallArgList(), KE->getInterfaceDecl()); + const ObjCMethodDecl *Getter = E->getImplicitPropertyGetter(); + S = Getter->getSelector(); + ResultType = Getter->getResultType(); // with reference! } + + if (E->isSuperReceiver()) + return EmitObjCSuperPropertyGet(E, S, Return); + + llvm::Value *Receiver; + const ObjCInterfaceDecl *ReceiverClass = 0; + if (E->isClassReceiver()) { + ReceiverClass = E->getClassReceiver(); + Receiver = CGM.getObjCRuntime().GetClass(Builder, ReceiverClass); + } else { + Receiver = EmitScalarExpr(E->getBase()); + } + return CGM.getObjCRuntime(). + GenerateMessageSend(*this, Return, ResultType, S, + Receiver, CallArgList(), ReceiverClass); } void CodeGenFunction::EmitObjCSuperPropertySet(const Expr *Exp, @@ -581,43 +579,37 @@ void CodeGenFunction::EmitObjCSuperPropertySet(const Expr *Exp, return; } -void CodeGenFunction::EmitObjCPropertySet(const Expr *Exp, +void CodeGenFunction::EmitObjCPropertySet(const ObjCPropertyRefExpr *E, RValue Src) { - // FIXME: Split it into two separate routines. - if (const ObjCPropertyRefExpr *E = dyn_cast(Exp)) { - Selector S = E->getProperty()->getSetterName(); - if (E->isSuperReceiver()) { - EmitObjCSuperPropertySet(E, S, Src); - return; - } - CallArgList Args; - Args.push_back(std::make_pair(Src, E->getType())); - CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(), - getContext().VoidTy, S, - EmitScalarExpr(E->getBase()), - Args); - } else if (const ObjCImplicitSetterGetterRefExpr *E = - dyn_cast(Exp)) { - const ObjCMethodDecl *SetterMD = E->getSetterMethod(); - Selector S = SetterMD->getSelector(); - CallArgList Args; - llvm::Value *Receiver; - if (E->getInterfaceDecl()) { - const ObjCInterfaceDecl *OID = E->getInterfaceDecl(); - Receiver = CGM.getObjCRuntime().GetClass(Builder, OID); - } else if (E->isSuperReceiver()) { - EmitObjCSuperPropertySet(E, S, Src); - return; - } else - Receiver = EmitScalarExpr(E->getBase()); - ObjCMethodDecl::param_iterator P = SetterMD->param_begin(); - Args.push_back(std::make_pair(Src, (*P)->getType())); - CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(), - getContext().VoidTy, S, - Receiver, - Args, E->getInterfaceDecl()); - } else - assert (0 && "bad expression node in EmitObjCPropertySet"); + Selector S = E->getSetterSelector(); + QualType ArgType; + if (E->isImplicitProperty()) { + const ObjCMethodDecl *Setter = E->getImplicitPropertySetter(); + ObjCMethodDecl::param_iterator P = Setter->param_begin(); + ArgType = (*P)->getType(); + } else { + ArgType = E->getType(); + } + + if (E->isSuperReceiver()) { + EmitObjCSuperPropertySet(E, S, Src); + return; + } + + const ObjCInterfaceDecl *ReceiverClass = 0; + llvm::Value *Receiver; + if (E->isClassReceiver()) { + ReceiverClass = E->getClassReceiver(); + Receiver = CGM.getObjCRuntime().GetClass(Builder, ReceiverClass); + } else { + Receiver = EmitScalarExpr(E->getBase()); + } + + CallArgList Args; + Args.push_back(std::make_pair(Src, ArgType)); + CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(), + getContext().VoidTy, S, + Receiver, Args, ReceiverClass); } void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){ diff --git a/lib/CodeGen/CGValue.h b/lib/CodeGen/CGValue.h index bb98c3cb23..2de5750084 100644 --- a/lib/CodeGen/CGValue.h +++ b/lib/CodeGen/CGValue.h @@ -25,7 +25,6 @@ namespace llvm { namespace clang { class ObjCPropertyRefExpr; - class ObjCImplicitSetterGetterRefExpr; namespace CodeGen { class CGBitFieldInfo; @@ -129,9 +128,6 @@ class LValue { // Obj-C property reference expression const ObjCPropertyRefExpr *PropertyRefExpr; - - // ObjC 'implicit' property reference expression - const ObjCImplicitSetterGetterRefExpr *KVCRefExpr; }; // 'const' is unused here @@ -255,9 +251,9 @@ public: } // 'implicit' property ref lvalue - const ObjCImplicitSetterGetterRefExpr *getKVCRefExpr() const { + const ObjCPropertyRefExpr *getKVCRefExpr() const { assert(isKVCRef()); - return KVCRefExpr; + return PropertyRefExpr; } static LValue MakeAddr(llvm::Value *V, QualType T, unsigned Alignment, @@ -321,11 +317,11 @@ public: return R; } - static LValue MakeKVCRef(const ObjCImplicitSetterGetterRefExpr *E, + static LValue MakeKVCRef(const ObjCPropertyRefExpr *E, unsigned CVR) { LValue R; R.LVType = KVCRef; - R.KVCRefExpr = E; + R.PropertyRefExpr = E; R.Initialize(Qualifiers::fromCVRMask(CVR)); return R; } diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 4bb5c595eb..4a58d5b357 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -1460,7 +1460,6 @@ public: LValue EmitObjCMessageExprLValue(const ObjCMessageExpr *E); LValue EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E); LValue EmitObjCPropertyRefLValue(const ObjCPropertyRefExpr *E); - LValue EmitObjCKVCRefLValue(const ObjCImplicitSetterGetterRefExpr *E); LValue EmitStmtExprLValue(const StmtExpr *E); LValue EmitPointerToDataMemberBinaryExpr(const BinaryOperator *E); LValue EmitObjCSelectorLValue(const ObjCSelectorExpr *E); @@ -1545,11 +1544,11 @@ public: llvm::Value *EmitObjCSelectorExpr(const ObjCSelectorExpr *E); RValue EmitObjCMessageExpr(const ObjCMessageExpr *E, ReturnValueSlot Return = ReturnValueSlot()); - RValue EmitObjCPropertyGet(const Expr *E, + RValue EmitObjCPropertyGet(const ObjCPropertyRefExpr *E, ReturnValueSlot Return = ReturnValueSlot()); RValue EmitObjCSuperPropertyGet(const Expr *Exp, const Selector &S, ReturnValueSlot Return = ReturnValueSlot()); - void EmitObjCPropertySet(const Expr *E, RValue Src); + void EmitObjCPropertySet(const ObjCPropertyRefExpr *E, RValue Src); void EmitObjCSuperPropertySet(const Expr *E, const Selector &S, RValue Src); diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp index e9c51e8479..0d4cebf7d5 100644 --- a/lib/CodeGen/Mangle.cpp +++ b/lib/CodeGen/Mangle.cpp @@ -1651,7 +1651,6 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) { case Expr::CompoundLiteralExprClass: case Expr::ExtVectorElementExprClass: case Expr::ObjCEncodeExprClass: - case Expr::ObjCImplicitSetterGetterRefExprClass: case Expr::ObjCIsaExprClass: case Expr::ObjCIvarRefExprClass: case Expr::ObjCMessageExprClass: diff --git a/lib/Rewrite/RewriteObjC.cpp b/lib/Rewrite/RewriteObjC.cpp index 1ecde6a7fa..286ac0f638 100644 --- a/lib/Rewrite/RewriteObjC.cpp +++ b/lib/Rewrite/RewriteObjC.cpp @@ -1230,30 +1230,24 @@ Stmt *RewriteObjC::RewritePropertyOrImplicitSetter(BinaryOperator *BinOp, Expr * SourceLocation SuperLocation; // Synthesize a ObjCMessageExpr from a ObjCPropertyRefExpr or ObjCImplicitSetterGetterRefExpr. // This allows us to reuse all the fun and games in SynthMessageExpr(). - if (ObjCPropertyRefExpr *PropRefExpr = dyn_cast(BinOp->getLHS())) { - ObjCPropertyDecl *PDecl = PropRefExpr->getProperty(); - OMD = PDecl->getSetterMethodDecl(); - Ty = PDecl->getType(); - Sel = PDecl->getSetterName(); + if (ObjCPropertyRefExpr *PropRefExpr = + dyn_cast(BinOp->getLHS())) { + if (PropRefExpr->isExplicitProperty()) { + ObjCPropertyDecl *PDecl = PropRefExpr->getExplicitProperty(); + OMD = PDecl->getSetterMethodDecl(); + Ty = PDecl->getType(); + Sel = PDecl->getSetterName(); + } else { + OMD = PropRefExpr->getImplicitPropertySetter(); + Sel = OMD->getSelector(); + Ty = PropRefExpr->getType(); + } Super = PropRefExpr->isSuperReceiver(); - if (!Super) + if (!Super) { Receiver = PropRefExpr->getBase(); - else { - SuperTy = PropRefExpr->getSuperType(); - SuperLocation = PropRefExpr->getSuperLocation(); - } - } - else if (ObjCImplicitSetterGetterRefExpr *ImplicitRefExpr = - dyn_cast(BinOp->getLHS())) { - OMD = ImplicitRefExpr->getSetterMethod(); - Sel = OMD->getSelector(); - Ty = ImplicitRefExpr->getType(); - Super = ImplicitRefExpr->isSuperReceiver(); - if (!Super) - Receiver = ImplicitRefExpr->getBase(); - else { - SuperTy = ImplicitRefExpr->getSuperType(); - SuperLocation = ImplicitRefExpr->getSuperLocation(); + } else { + SuperTy = PropRefExpr->getSuperReceiverType(); + SuperLocation = PropRefExpr->getReceiverLocation(); } } @@ -1314,29 +1308,22 @@ Stmt *RewriteObjC::RewritePropertyOrImplicitGetter(Expr *PropOrGetterRefExpr) { SourceLocation SuperLocation; if (ObjCPropertyRefExpr *PropRefExpr = dyn_cast(PropOrGetterRefExpr)) { - ObjCPropertyDecl *PDecl = PropRefExpr->getProperty(); - OMD = PDecl->getGetterMethodDecl(); - Ty = PDecl->getType(); - Sel = PDecl->getGetterName(); + if (PropRefExpr->isExplicitProperty()) { + ObjCPropertyDecl *PDecl = PropRefExpr->getExplicitProperty(); + OMD = PDecl->getGetterMethodDecl(); + Ty = PDecl->getType(); + Sel = PDecl->getGetterName(); + } else { + OMD = PropRefExpr->getImplicitPropertyGetter(); + Sel = OMD->getSelector(); + Ty = PropRefExpr->getType(); + } Super = PropRefExpr->isSuperReceiver(); if (!Super) Receiver = PropRefExpr->getBase(); else { - SuperTy = PropRefExpr->getSuperType(); - SuperLocation = PropRefExpr->getSuperLocation(); - } - } - else if (ObjCImplicitSetterGetterRefExpr *ImplicitRefExpr = - dyn_cast(PropOrGetterRefExpr)) { - OMD = ImplicitRefExpr->getGetterMethod(); - Sel = OMD->getSelector(); - Ty = ImplicitRefExpr->getType(); - Super = ImplicitRefExpr->isSuperReceiver(); - if (!Super) - Receiver = ImplicitRefExpr->getBase(); - else { - SuperTy = ImplicitRefExpr->getSuperType(); - SuperLocation = ImplicitRefExpr->getSuperLocation(); + SuperTy = PropRefExpr->getSuperReceiverType(); + SuperLocation = PropRefExpr->getReceiverLocation(); } } @@ -1376,8 +1363,7 @@ Stmt *RewriteObjC::RewritePropertyOrImplicitGetter(Expr *PropOrGetterRefExpr) { PropParentMap = new ParentMap(CurrentBody); Stmt *Parent = PropParentMap->getParent(PropOrGetterRefExpr); - if (Parent && (isa(Parent) || - isa(Parent))) { + if (Parent && isa(Parent)) { // We stash away the ReplacingStmt since actually doing the // replacement/rewrite won't work for nested getters (e.g. obj.p.i) PropGetters[PropOrGetterRefExpr] = ReplacingStmt; @@ -5495,9 +5481,8 @@ void RewriteObjC::CollectPropertySetters(Stmt *S) { if (BinaryOperator *BinOp = dyn_cast(S)) { if (BinOp->isAssignmentOp()) { - if (isa(BinOp->getLHS()) || - isa(BinOp->getLHS())) - PropSetters[BinOp->getLHS()] = BinOp; + if (isa(BinOp->getLHS())) + PropSetters[BinOp->getLHS()] = BinOp; } } } @@ -5539,8 +5524,7 @@ Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) { // setter messaging. This involvs the RHS too. Do not attempt to rewrite // RHS again. if (Expr *Exp = dyn_cast(S)) - if (isa(Exp) || - isa(Exp)) { + if (isa(Exp)) { if (PropSetters[Exp]) { ++CI; continue; @@ -5577,7 +5561,7 @@ Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) { if (ObjCEncodeExpr *AtEncode = dyn_cast(S)) return RewriteAtEncode(AtEncode); - if (isa(S) || isa(S)) { + if (isa(S)) { Expr *PropOrImplicitRefExpr = dyn_cast(S); assert(PropOrImplicitRefExpr && "Property or implicit setter/getter is null"); diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index ac764ab800..c99c491674 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -3538,9 +3538,9 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr, ExprObjectKind OK = (VK == VK_RValue ? OK_Ordinary : OK_ObjCProperty); // FIXME: we must check that the setter has property type. - return Owned(new (Context) ObjCImplicitSetterGetterRefExpr(Getter, - PType, VK, OK, - Setter, MemberLoc, BaseExpr)); + return Owned(new (Context) ObjCPropertyRefExpr(Getter, Setter, + PType, VK, OK, + MemberLoc, BaseExpr)); } return ExprError(Diag(MemberLoc, diag::err_property_not_found) << MemberName << BaseType); @@ -3726,10 +3726,8 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr, VK = VK_RValue; ExprObjectKind OK = (VK == VK_RValue ? OK_Ordinary : OK_ObjCProperty); - return Owned(new (Context) ObjCImplicitSetterGetterRefExpr(OMD, PType, - VK, OK, SMD, - MemberLoc, - BaseExpr)); + return Owned(new (Context) ObjCPropertyRefExpr(OMD, SMD, PType, VK, OK, + MemberLoc, BaseExpr)); } } @@ -6683,17 +6681,18 @@ inline QualType Sema::CheckLogicalOperands( // C99 6.5.[13,14] static bool IsReadonlyProperty(Expr *E, Sema &S) { if (E->getStmtClass() == Expr::ObjCPropertyRefExprClass) { const ObjCPropertyRefExpr* PropExpr = cast(E); - if (ObjCPropertyDecl *PDecl = PropExpr->getProperty()) { - QualType BaseType = PropExpr->isSuperReceiver() ? - PropExpr->getSuperType() : + if (PropExpr->isImplicitProperty()) return false; + + ObjCPropertyDecl *PDecl = PropExpr->getExplicitProperty(); + QualType BaseType = PropExpr->isSuperReceiver() ? + PropExpr->getSuperReceiverType() : PropExpr->getBase()->getType(); - if (const ObjCObjectPointerType *OPT = - BaseType->getAsObjCInterfacePointerType()) - if (ObjCInterfaceDecl *IFace = OPT->getInterfaceDecl()) - if (S.isPropertyReadonly(PDecl, IFace)) - return true; - } + if (const ObjCObjectPointerType *OPT = + BaseType->getAsObjCInterfacePointerType()) + if (ObjCInterfaceDecl *IFace = OPT->getInterfaceDecl()) + if (S.isPropertyReadonly(PDecl, IFace)) + return true; } return false; } @@ -6970,20 +6969,18 @@ static QualType CheckIncrementDecrementOperand(Sema &S, Expr *Op, void Sema::ConvertPropertyAssignment(Expr *LHS, Expr *&RHS, QualType& LHSTy) { bool copyInit = false; - if (const ObjCImplicitSetterGetterRefExpr *OISGE = - dyn_cast(LHS)) { - // If using property-dot syntax notation for assignment, and there is a - // setter, RHS expression is being passed to the setter argument. So, - // type conversion (and comparison) is RHS to setter's argument type. - if (const ObjCMethodDecl *SetterMD = OISGE->getSetterMethod()) { - ObjCMethodDecl::param_iterator P = SetterMD->param_begin(); - LHSTy = (*P)->getType(); + if (const ObjCPropertyRefExpr *PRE = dyn_cast(LHS)) { + if (PRE->isImplicitProperty()) { + // If using property-dot syntax notation for assignment, and there is a + // setter, RHS expression is being passed to the setter argument. So, + // type conversion (and comparison) is RHS to setter's argument type. + if (const ObjCMethodDecl *SetterMD = PRE->getImplicitPropertySetter()) { + ObjCMethodDecl::param_iterator P = SetterMD->param_begin(); + LHSTy = (*P)->getType(); + } } copyInit = (getLangOptions().CPlusPlus && LHSTy->isRecordType()); } - else - copyInit = (getLangOptions().CPlusPlus && isa(LHS) && - LHSTy->isRecordType()); if (copyInit) { InitializedEntity Entity = InitializedEntity::InitializeParameter(Context, LHSTy); @@ -7614,9 +7611,8 @@ ExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *lhs, Expr *rhs) { if (getLangOptions().CPlusPlus && - ((!isa(lhs) && - !isa(lhs)) - || rhs->isTypeDependent() || Opc != BO_Assign) && + (!isa(lhs) + || rhs->isTypeDependent() || Opc != BO_Assign) && (lhs->getType()->isOverloadableType() || rhs->getType()->isOverloadableType())) { // Find all of the overloaded operators visible from this diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index 047236b1bd..46a834a487 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -439,12 +439,14 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, VK = VK_RValue, OK = OK_Ordinary; if (Super) - return Owned(new (Context) ObjCImplicitSetterGetterRefExpr(Getter, PType, - VK, OK, Setter, MemberLoc, - SuperLoc, SuperType)); + return Owned(new (Context) ObjCPropertyRefExpr(Getter, Setter, + PType, VK, OK, + MemberLoc, + SuperLoc, SuperType)); else - return Owned(new (Context) ObjCImplicitSetterGetterRefExpr(Getter, PType, - VK, OK, Setter, MemberLoc, BaseExpr)); + return Owned(new (Context) ObjCPropertyRefExpr(Getter, Setter, + PType, VK, OK, + MemberLoc, BaseExpr)); } @@ -566,9 +568,10 @@ ActOnClassPropertyRefExpr(IdentifierInfo &receiverName, ExprObjectKind OK = (VK == VK_RValue ? OK_Ordinary : OK_ObjCProperty); - return Owned(new (Context) ObjCImplicitSetterGetterRefExpr( - Getter, PType, VK, OK, Setter, - propertyNameLoc, IFace, receiverNameLoc)); + return Owned(new (Context) ObjCPropertyRefExpr(Getter, Setter, + PType, VK, OK, + propertyNameLoc, + receiverNameLoc, IFace)); } return ExprError(Diag(propertyNameLoc, diag::err_property_not_found) << &propertyName << Context.getObjCInterfaceType(IFace)); diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 48d2b47c8a..7fa555e4f9 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -89,13 +89,10 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) { // we might want to make a more specific diagnostic. Check for one of these // cases now. unsigned DiagID = diag::warn_unused_expr; - E = E->IgnoreParens(); - if (isa(E)) - DiagID = diag::warn_unused_property_expr; - if (const CXXExprWithTemporaries *Temps = dyn_cast(E)) E = Temps->getSubExpr(); - + + E = E->IgnoreParens(); if (const CallExpr *CE = dyn_cast(E)) { if (E->getType()->isVoidType()) return; @@ -116,13 +113,14 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) { return; } } - } - else if (const ObjCMessageExpr *ME = dyn_cast(E)) { + } else if (const ObjCMessageExpr *ME = dyn_cast(E)) { const ObjCMethodDecl *MD = ME->getMethodDecl(); if (MD && MD->getAttr()) { Diag(Loc, diag::warn_unused_call) << R1 << R2 << "warn_unused_result"; return; } + } else if (isa(E)) { + DiagID = diag::warn_unused_property_expr; } else if (const CXXFunctionalCastExpr *FC = dyn_cast(E)) { if (isa(FC->getSubExpr()) || diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 5aea3f029d..e0111f1e96 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -1891,39 +1891,20 @@ public: /*TemplateArgs=*/0); } - /// \brief Build a new Objective-C implicit setter/getter reference - /// expression. + /// \brief Build a new Objective-C property reference expression. /// /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildObjCImplicitSetterGetterRefExpr( - ObjCMethodDecl *Getter, - QualType T, - ObjCMethodDecl *Setter, - SourceLocation NameLoc, - Expr *Base, - SourceLocation SuperLoc, - QualType SuperTy, - bool Super) { - // Since these expressions can only be value-dependent, we do not need to - // perform semantic analysis again. - if (Super) - return Owned( - new (getSema().Context) ObjCImplicitSetterGetterRefExpr(Getter, T, - VK_LValue, - OK_Ordinary, - Setter, - NameLoc, - SuperLoc, - SuperTy)); - else - return Owned( - new (getSema().Context) ObjCImplicitSetterGetterRefExpr(Getter, T, - VK_LValue, - OK_Ordinary, - Setter, - NameLoc, - Base)); + /// Subclasses may override this routine to provide different behavior. + ExprResult RebuildObjCPropertyRefExpr(Expr *Base, QualType T, + ObjCMethodDecl *Getter, + ObjCMethodDecl *Setter, + SourceLocation PropertyLoc) { + // Since these expressions can only be value-dependent, we do not + // need to perform semantic analysis again. + return Owned( + new (getSema().Context) ObjCPropertyRefExpr(Getter, Setter, T, + VK_LValue, OK_ObjCProperty, + PropertyLoc, Base)); } /// \brief Build a new Objective-C "isa" expression. @@ -6222,9 +6203,9 @@ TreeTransform::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) { template ExprResult TreeTransform::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) { - // 'super' never changes. Property never changes. Just retain the existing - // expression. - if (E->isSuperReceiver()) + // 'super' and types never change. Property never changes. Just + // retain the existing expression. + if (!E->isObjectReceiver()) return SemaRef.Owned(E); // Transform the base expression. @@ -6238,47 +6219,17 @@ TreeTransform::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) { if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase()) return SemaRef.Owned(E); - - return getDerived().RebuildObjCPropertyRefExpr(Base.get(), E->getProperty(), - E->getLocation()); -} -template -ExprResult -TreeTransform::TransformObjCImplicitSetterGetterRefExpr( - ObjCImplicitSetterGetterRefExpr *E) { - // If this implicit setter/getter refers to super, it cannot have any - // dependent parts. Just retain the existing declaration. - if (E->isSuperReceiver()) - return SemaRef.Owned(E); - - // If this implicit setter/getter refers to class methods, it cannot have any - // dependent parts. Just retain the existing declaration. - if (E->getInterfaceDecl()) - return SemaRef.Owned(E); - - // Transform the base expression. - ExprResult Base = getDerived().TransformExpr(E->getBase()); - if (Base.isInvalid()) - return ExprError(); - - // We don't need to transform the getters/setters; they will never change. - - // If nothing changed, just retain the existing expression. - if (!getDerived().AlwaysRebuild() && - Base.get() == E->getBase()) - return SemaRef.Owned(E); - - return getDerived().RebuildObjCImplicitSetterGetterRefExpr( - E->getGetterMethod(), - E->getType(), - E->getSetterMethod(), - E->getLocation(), - Base.get(), - E->getSuperLocation(), - E->getSuperType(), - E->isSuperReceiver()); - + if (E->isExplicitProperty()) + return getDerived().RebuildObjCPropertyRefExpr(Base.get(), + E->getExplicitProperty(), + E->getLocation()); + + return getDerived().RebuildObjCPropertyRefExpr(Base.get(), + E->getType(), + E->getImplicitPropertyGetter(), + E->getImplicitPropertySetter(), + E->getLocation()); } template diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp index 5aba1f8ada..e61595a6e8 100644 --- a/lib/Serialization/ASTReaderStmt.cpp +++ b/lib/Serialization/ASTReaderStmt.cpp @@ -127,8 +127,6 @@ namespace clang { void VisitObjCProtocolExpr(ObjCProtocolExpr *E); void VisitObjCIvarRefExpr(ObjCIvarRefExpr *E); void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E); - void VisitObjCImplicitSetterGetterRefExpr( - ObjCImplicitSetterGetterRefExpr *E); void VisitObjCMessageExpr(ObjCMessageExpr *E); void VisitObjCIsaExpr(ObjCIsaExpr *E); @@ -849,31 +847,31 @@ void ASTStmtReader::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { void ASTStmtReader::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) { VisitExpr(E); - E->setProperty(cast(Reader.GetDecl(Record[Idx++]))); - E->setLocation(ReadSourceLocation(Record, Idx)); - E->SuperLoc = ReadSourceLocation(Record, Idx); - if (E->isSuperReceiver()) { - QualType T = Reader.GetType(Record[Idx++]); - E->BaseExprOrSuperType = T.getTypePtr(); + bool Implicit = Record[Idx++] != 0; + if (Implicit) { + ObjCMethodDecl *Getter = + cast(Reader.GetDecl(Record[Idx++])); + ObjCMethodDecl *Setter = + cast(Reader.GetDecl(Record[Idx++])); + E->setImplicitProperty(Getter, Setter); + } else { + E->setExplicitProperty( + cast(Reader.GetDecl(Record[Idx++]))); } - else - E->setBase(Reader.ReadSubExpr()); -} - -void ASTStmtReader::VisitObjCImplicitSetterGetterRefExpr( - ObjCImplicitSetterGetterRefExpr *E) { - VisitExpr(E); - E->setGetterMethod( - cast_or_null(Reader.GetDecl(Record[Idx++]))); - E->setSetterMethod( - cast_or_null(Reader.GetDecl(Record[Idx++]))); - E->setInterfaceDecl( - cast_or_null(Reader.GetDecl(Record[Idx++]))); - E->setBase(Reader.ReadSubExpr()); E->setLocation(ReadSourceLocation(Record, Idx)); - E->setClassLoc(ReadSourceLocation(Record, Idx)); - E->SuperLoc = ReadSourceLocation(Record, Idx); - E->SuperTy = Reader.GetType(Record[Idx++]); + E->setReceiverLocation(ReadSourceLocation(Record, Idx)); + switch (Record[Idx++]) { + case 0: + E->setBase(Reader.ReadSubExpr()); + break; + case 1: + E->setSuperReceiver(Reader.GetType(Record[Idx++])); + break; + case 2: + E->setClassReceiver( + cast(Reader.GetDecl(Record[Idx++]))); + break; + } } void ASTStmtReader::VisitObjCMessageExpr(ObjCMessageExpr *E) { @@ -1639,7 +1637,7 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) { S = new (Context) ObjCPropertyRefExpr(Empty); break; case EXPR_OBJC_KVC_REF_EXPR: - S = new (Context) ObjCImplicitSetterGetterRefExpr(Empty); + llvm_unreachable("mismatching AST file"); break; case EXPR_OBJC_MESSAGE_EXPR: S = ObjCMessageExpr::CreateEmpty(*Context, diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp index 4d2fb8a030..2b3f69b6f4 100644 --- a/lib/Serialization/ASTWriterStmt.cpp +++ b/lib/Serialization/ASTWriterStmt.cpp @@ -100,8 +100,6 @@ namespace clang { void VisitObjCProtocolExpr(ObjCProtocolExpr *E); void VisitObjCIvarRefExpr(ObjCIvarRefExpr *E); void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E); - void VisitObjCImplicitSetterGetterRefExpr( - ObjCImplicitSetterGetterRefExpr *E); void VisitObjCMessageExpr(ObjCMessageExpr *E); void VisitObjCIsaExpr(ObjCIsaExpr *E); @@ -828,33 +826,29 @@ void ASTStmtWriter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { void ASTStmtWriter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) { VisitExpr(E); - Writer.AddDeclRef(E->getProperty(), Record); + Record.push_back(E->isImplicitProperty()); + if (E->isImplicitProperty()) { + Writer.AddDeclRef(E->getImplicitPropertyGetter(), Record); + Writer.AddDeclRef(E->getImplicitPropertySetter(), Record); + } else { + Writer.AddDeclRef(E->getExplicitProperty(), Record); + } Writer.AddSourceLocation(E->getLocation(), Record); - Writer.AddSourceLocation(E->getSuperLocation(), Record); - if (E->isSuperReceiver()) - Writer.AddTypeRef(E->getSuperType(), Record); - else + Writer.AddSourceLocation(E->getReceiverLocation(), Record); + if (E->isObjectReceiver()) { + Record.push_back(0); Writer.AddStmt(E->getBase()); + } else if (E->isSuperReceiver()) { + Record.push_back(1); + Writer.AddTypeRef(E->getSuperReceiverType(), Record); + } else { + Record.push_back(2); + Writer.AddDeclRef(E->getClassReceiver(), Record); + } Code = serialization::EXPR_OBJC_PROPERTY_REF_EXPR; } -void ASTStmtWriter::VisitObjCImplicitSetterGetterRefExpr( - ObjCImplicitSetterGetterRefExpr *E) { - VisitExpr(E); - Writer.AddDeclRef(E->getGetterMethod(), Record); - Writer.AddDeclRef(E->getSetterMethod(), Record); - - // NOTE: InterfaceDecl and Base are mutually exclusive. - Writer.AddDeclRef(E->getInterfaceDecl(), Record); - Writer.AddStmt(E->getBase()); - Writer.AddSourceLocation(E->getLocation(), Record); - Writer.AddSourceLocation(E->getClassLoc(), Record); - Writer.AddSourceLocation(E->getSuperLocation(), Record); - Writer.AddTypeRef(E->getSuperType(), Record); - Code = serialization::EXPR_OBJC_KVC_REF_EXPR; -} - void ASTStmtWriter::VisitObjCMessageExpr(ObjCMessageExpr *E) { VisitExpr(E); Record.push_back(E->getNumArgs()); diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index cdd7764016..b22cac0e7d 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -2612,7 +2612,7 @@ static Decl *getDeclFromExpr(Stmt *E) { if (ObjCIvarRefExpr *RE = dyn_cast(E)) return RE->getDecl(); if (ObjCPropertyRefExpr *PRE = dyn_cast(E)) - return PRE->getProperty(); + return PRE->isExplicitProperty() ? PRE->getExplicitProperty() : 0; if (CallExpr *CE = dyn_cast(E)) return getDeclFromExpr(CE->getCallee()); diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp index 841e297b88..c567dd999c 100644 --- a/tools/libclang/CXCursor.cpp +++ b/tools/libclang/CXCursor.cpp @@ -160,7 +160,6 @@ CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent, case Stmt::ObjCEncodeExprClass: case Stmt::ObjCSelectorExprClass: case Stmt::ObjCProtocolExprClass: - case Stmt::ObjCImplicitSetterGetterRefExprClass: case Stmt::ObjCIsaExprClass: case Stmt::ShuffleVectorExprClass: case Stmt::BlockExprClass: @@ -189,7 +188,6 @@ CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent, case Stmt::CXXConstructExprClass: case Stmt::CXXTemporaryObjectExprClass: // FIXME: CXXUnresolvedConstructExpr - // FIXME: ObjCImplicitSetterGetterRefExpr? K = CXCursor_CallExpr; break;