#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".
///
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<NamedDecl*, 1, bool> 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<Stmt*, Type*> BaseExprOrSuperType;
+ /// the location of the 'super' keyword. When it's an interface,
+ /// this is that interface.
+ SourceLocation ReceiverLoc;
+ llvm::PointerUnion3<Stmt*, Type*, ObjCInterfaceDecl*> Receiver;
public:
ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
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<ObjCPropertyDecl>(PropertyOrGetter.getPointer());
+ }
+
+ ObjCMethodDecl *getImplicitPropertyGetter() const {
+ assert(isImplicitProperty());
+ return cast_or_null<ObjCMethodDecl>(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<Expr>(BaseExprOrSuperType.get<Stmt*>());
+ return cast<Expr>(Receiver.get<Stmt*>());
}
Expr *getBase() {
- return cast<Expr>(BaseExprOrSuperType.get<Stmt*>());
+ return cast<Expr>(Receiver.get<Stmt*>());
}
SourceLocation getLocation() const { return IdLoc; }
- SourceLocation getSuperLocation() const { return SuperLoc; }
- QualType getSuperType() const {
- Type *t = BaseExprOrSuperType.get<Type*>();
- return QualType(t, 0);
+ SourceLocation getReceiverLocation() const { return ReceiverLoc; }
+ QualType getSuperReceiverType() const {
+ return QualType(Receiver.get<Type*>(), 0);
+ }
+ ObjCInterfaceDecl *getClassReceiver() const {
+ return Receiver.get<ObjCInterfaceDecl*>();
}
- bool isSuperReceiver() const { return BaseExprOrSuperType.is<Type*>(); }
+ bool isObjectReceiver() const { return Receiver.is<Stmt*>(); }
+ bool isSuperReceiver() const { return Receiver.is<Type*>(); }
+ bool isClassReceiver() const { return Receiver.is<ObjCInterfaceDecl*>(); }
virtual SourceRange getSourceRange() const {
- return SourceRange(
- (BaseExprOrSuperType.is<Stmt*>() ? getBase()->getLocStart()
- : getSuperLocation()),
- IdLoc);
+ return SourceRange((isObjectReceiver() ? getBase()->getLocStart()
+ : getReceiverLocation()),
+ IdLoc);
}
static bool classof(const Stmt *T) {
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<Expr>(Base); }
- Expr *getBase() { return cast_or_null<Expr>(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
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, { })
def ObjCProtocolExpr : DStmt<Expr>;
def ObjCIvarRefExpr : DStmt<Expr>;
def ObjCPropertyRefExpr : DStmt<Expr>;
-def ObjCImplicitSetterGetterRefExpr : DStmt<Expr>;
def ObjCIsaExpr : DStmt<Expr>;
// Clang Extensions.
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,
return false;
}
- case ObjCImplicitSetterGetterRefExprClass: { // Dot syntax for message send.
-#if 0
- const ObjCImplicitSetterGetterRefExpr *Ref =
- cast<ObjCImplicitSetterGetterRefExpr>(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.
// specs.
case ObjCMessageExprClass:
case ObjCPropertyRefExprClass:
- case ObjCImplicitSetterGetterRefExprClass:
return CT_Can;
// Many other things have subexpressions, so we have to test those.
// 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<ObjCPropertyRefExpr>(E) &&
- !isa<ObjCImplicitSetterGetterRefExpr>(E))
+ if (!isa<ObjCPropertyRefExpr>(E))
return false;
}
// ObjCPropertyRefExpr
Stmt::child_iterator ObjCPropertyRefExpr::child_begin()
{
- if (BaseExprOrSuperType.is<Stmt*>()) {
+ if (Receiver.is<Stmt*>()) {
// Hack alert!
- return reinterpret_cast<Stmt**> (&BaseExprOrSuperType);
+ return reinterpret_cast<Stmt**> (&Receiver);
}
return child_iterator();
}
Stmt::child_iterator ObjCPropertyRefExpr::child_end()
-{ return BaseExprOrSuperType.is<Stmt*>() ?
- reinterpret_cast<Stmt**> (&BaseExprOrSuperType)+1 :
+{ return Receiver.is<Stmt*>() ?
+ reinterpret_cast<Stmt**> (&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; }
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.
Cl::Kinds K = ClassifyInternal(Ctx, Op);
if (K != Cl::CL_LValue) return K;
- if (isa<ObjCPropertyRefExpr>(Op) ||
- isa<ObjCImplicitSetterGetterRefExpr>(Op))
+ if (isa<ObjCPropertyRefExpr>(Op))
return Cl::CL_SubObjCPropertySetting;
return Cl::CL_LValue;
}
return Cl::CL_LValue;
// ObjC property accesses are not lvalues, but get special treatment.
Expr *Base = E->getBase()->IgnoreParens();
- if (isa<ObjCPropertyRefExpr>(Base) ||
- isa<ObjCImplicitSetterGetterRefExpr>(Base))
+ if (isa<ObjCPropertyRefExpr>(Base))
return Cl::CL_SubObjCPropertySetting;
return ClassifyInternal(Ctx, Base);
}
if (E->isArrow())
return Cl::CL_LValue;
Expr *Base = E->getBase()->IgnoreParenImpCasts();
- if (isa<ObjCPropertyRefExpr>(Base) ||
- isa<ObjCImplicitSetterGetterRefExpr>(Base))
+ if (isa<ObjCPropertyRefExpr>(Base))
return Cl::CL_SubObjCPropertySetting;
return ClassifyInternal(Ctx, E->getBase());
}
// Assignment to a property in ObjC is an implicit setter access. But a
// setter might not exist.
- if (const ObjCImplicitSetterGetterRefExpr *Expr =
- dyn_cast<ObjCImplicitSetterGetterRefExpr>(E)) {
- if (Expr->getSetterMethod() == 0)
+ if (const ObjCPropertyRefExpr *Expr = dyn_cast<ObjCPropertyRefExpr>(E)) {
+ if (Expr->isImplicitProperty() && Expr->getImplicitPropertySetter() == 0)
return Cl::CM_NoSetterProperty;
}
// Records with any const fields (recursively) are not modifiable.
if (const RecordType *R = CT->getAs<RecordType>()) {
- assert((isa<ObjCImplicitSetterGetterRefExpr>(E) ||
- isa<ObjCPropertyRefExpr>(E) ||
+ assert((isa<ObjCPropertyRefExpr>(E) ||
!Ctx.getLangOptions().CPlusPlus) &&
"C++ struct assignment should be resolved by the "
"copy assignment operator.");
case Expr::ObjCProtocolExprClass:
case Expr::ObjCIvarRefExprClass:
case Expr::ObjCPropertyRefExprClass:
- case Expr::ObjCImplicitSetterGetterRefExprClass:
case Expr::ObjCIsaExprClass:
case Expr::ShuffleVectorExprClass:
case Expr::BlockExprClass:
void VisitObjCSelectorExpr(ObjCSelectorExpr *Node);
void VisitObjCProtocolExpr(ObjCProtocolExpr *Node);
void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node);
- void VisitObjCImplicitSetterGetterRefExpr(
- ObjCImplicitSetterGetterRefExpr *Node);
void VisitObjCIvarRefExpr(ObjCIvarRefExpr *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";
}
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) {
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());
}
}
if (BinaryOperator* BO = dyn_cast<BinaryOperator>(S))
if (BO->isAssignmentOp())
if (ObjCPropertyRefExpr* PRE =
- dyn_cast<ObjCPropertyRefExpr>(BO->getLHS()->IgnoreParenCasts()))
- if (PRE->getProperty() == PD)
+ dyn_cast<ObjCPropertyRefExpr>(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
case Stmt::ObjCAtFinallyStmtClass:
case Stmt::ObjCAtTryStmtClass:
case Stmt::ObjCEncodeExprClass:
- case Stmt::ObjCImplicitSetterGetterRefExprClass:
case Stmt::ObjCIsaExprClass:
case Stmt::ObjCPropertyRefExprClass:
case Stmt::ObjCProtocolExprClass:
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
Expr* LHS = B->getLHS()->IgnoreParens();
Expr* RHS = B->getRHS()->IgnoreParens();
- // FIXME: Add proper support for ObjCImplicitSetterGetterRefExpr.
- if (isa<ObjCImplicitSetterGetterRefExpr>(LHS)) {
- Visit(RHS, Pred, Dst);
- return;
- }
-
if (B->isAssignmentOp())
VisitLValue(LHS, Pred, Tmp1);
else
if (PE->isSuperReceiver())
Info.NeedsObjCSelf = true;
}
- else if (const ObjCImplicitSetterGetterRefExpr *IE =
- dyn_cast<ObjCImplicitSetterGetterRefExpr>(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<CXXThisExpr>(S))
Info.CXXThisRef = cast<CXXThisExpr>(S);
}
return EmitObjCIvarRefLValue(cast<ObjCIvarRefExpr>(E));
case Expr::ObjCPropertyRefExprClass:
return EmitObjCPropertyRefLValue(cast<ObjCPropertyRefExpr>(E));
- case Expr::ObjCImplicitSetterGetterRefExprClass:
- return EmitObjCKVCRefLValue(cast<ObjCImplicitSetterGetterRefExpr>(E));
case Expr::StmtExprClass:
return EmitStmtExprLValue(cast<StmtExpr>(E));
case Expr::UnaryOperatorClass:
const PointerType *PTy =
BaseExpr->getType()->getAs<PointerType>();
BaseQuals = PTy->getPointeeType().getQualifiers();
- } else if (isa<ObjCPropertyRefExpr>(BaseExpr->IgnoreParens()) ||
- isa<ObjCImplicitSetterGetterRefExpr>(
- BaseExpr->IgnoreParens())) {
- RValue RV = EmitObjCPropertyGet(BaseExpr);
+ } else if (ObjCPropertyRefExpr *PRE
+ = dyn_cast<ObjCPropertyRefExpr>(BaseExpr->IgnoreParens())) {
+ RValue RV = EmitObjCPropertyGet(PRE);
BaseValue = RV.getAggregateAddr();
BaseQuals = BaseExpr->getType().getQualifiers();
} else {
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);
}
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) {
EmitAggLoadOfLValue(E);
}
void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E);
- void VisitObjCImplicitSetterGetterRefExpr(ObjCImplicitSetterGetterRefExpr *E);
void VisitConditionalOperator(const ConditionalOperator *CO);
void VisitChooseExpr(const ChooseExpr *CE);
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());
ComplexPairTy VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
return EmitLoadOfLValue(E);
}
- ComplexPairTy VisitObjCImplicitSetterGetterRefExpr(
- ObjCImplicitSetterGetterRefExpr *E) {
- return EmitLoadOfLValue(E);
- }
ComplexPairTy VisitObjCMessageExpr(ObjCMessageExpr *E) {
return CGF.EmitObjCMessageExpr(E).getComplexVal();
}
Value *VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
return EmitLoadOfLValue(E);
}
- Value *VisitObjCImplicitSetterGetterRefExpr(
- ObjCImplicitSetterGetterRefExpr *E) {
- return EmitLoadOfLValue(E);
- }
Value *VisitObjCMessageExpr(ObjCMessageExpr *E) {
return CGF.EmitObjCMessageExpr(E).getScalarVal();
}
}
-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<ObjCPropertyRefExpr>(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<ObjCImplicitSetterGetterRefExpr>(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,
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<ObjCPropertyRefExpr>(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<ObjCImplicitSetterGetterRefExpr>(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){
namespace clang {
class ObjCPropertyRefExpr;
- class ObjCImplicitSetterGetterRefExpr;
namespace CodeGen {
class CGBitFieldInfo;
// Obj-C property reference expression
const ObjCPropertyRefExpr *PropertyRefExpr;
-
- // ObjC 'implicit' property reference expression
- const ObjCImplicitSetterGetterRefExpr *KVCRefExpr;
};
// 'const' is unused here
}
// '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,
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;
}
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);
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);
case Expr::CompoundLiteralExprClass:
case Expr::ExtVectorElementExprClass:
case Expr::ObjCEncodeExprClass:
- case Expr::ObjCImplicitSetterGetterRefExprClass:
case Expr::ObjCIsaExprClass:
case Expr::ObjCIvarRefExprClass:
case Expr::ObjCMessageExprClass:
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<ObjCPropertyRefExpr>(BinOp->getLHS())) {
- ObjCPropertyDecl *PDecl = PropRefExpr->getProperty();
- OMD = PDecl->getSetterMethodDecl();
- Ty = PDecl->getType();
- Sel = PDecl->getSetterName();
+ if (ObjCPropertyRefExpr *PropRefExpr =
+ dyn_cast<ObjCPropertyRefExpr>(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<ObjCImplicitSetterGetterRefExpr>(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();
}
}
SourceLocation SuperLocation;
if (ObjCPropertyRefExpr *PropRefExpr =
dyn_cast<ObjCPropertyRefExpr>(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<ObjCImplicitSetterGetterRefExpr>(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();
}
}
PropParentMap = new ParentMap(CurrentBody);
Stmt *Parent = PropParentMap->getParent(PropOrGetterRefExpr);
- if (Parent && (isa<ObjCPropertyRefExpr>(Parent) ||
- isa<ObjCImplicitSetterGetterRefExpr>(Parent))) {
+ if (Parent && isa<ObjCPropertyRefExpr>(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;
if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) {
if (BinOp->isAssignmentOp()) {
- if (isa<ObjCPropertyRefExpr>(BinOp->getLHS()) ||
- isa<ObjCImplicitSetterGetterRefExpr>(BinOp->getLHS()))
- PropSetters[BinOp->getLHS()] = BinOp;
+ if (isa<ObjCPropertyRefExpr>(BinOp->getLHS()))
+ PropSetters[BinOp->getLHS()] = BinOp;
}
}
}
// setter messaging. This involvs the RHS too. Do not attempt to rewrite
// RHS again.
if (Expr *Exp = dyn_cast<Expr>(S))
- if (isa<ObjCPropertyRefExpr>(Exp) ||
- isa<ObjCImplicitSetterGetterRefExpr>(Exp)) {
+ if (isa<ObjCPropertyRefExpr>(Exp)) {
if (PropSetters[Exp]) {
++CI;
continue;
if (ObjCEncodeExpr *AtEncode = dyn_cast<ObjCEncodeExpr>(S))
return RewriteAtEncode(AtEncode);
- if (isa<ObjCPropertyRefExpr>(S) || isa<ObjCImplicitSetterGetterRefExpr>(S)) {
+ if (isa<ObjCPropertyRefExpr>(S)) {
Expr *PropOrImplicitRefExpr = dyn_cast<Expr>(S);
assert(PropOrImplicitRefExpr && "Property or implicit setter/getter is null");
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);
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));
}
}
static bool IsReadonlyProperty(Expr *E, Sema &S) {
if (E->getStmtClass() == Expr::ObjCPropertyRefExprClass) {
const ObjCPropertyRefExpr* PropExpr = cast<ObjCPropertyRefExpr>(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;
}
void Sema::ConvertPropertyAssignment(Expr *LHS, Expr *&RHS, QualType& LHSTy) {
bool copyInit = false;
- if (const ObjCImplicitSetterGetterRefExpr *OISGE =
- dyn_cast<ObjCImplicitSetterGetterRefExpr>(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<ObjCPropertyRefExpr>(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<ObjCPropertyRefExpr>(LHS) &&
- LHSTy->isRecordType());
if (copyInit) {
InitializedEntity Entity =
InitializedEntity::InitializeParameter(Context, LHSTy);
BinaryOperatorKind Opc,
Expr *lhs, Expr *rhs) {
if (getLangOptions().CPlusPlus &&
- ((!isa<ObjCImplicitSetterGetterRefExpr>(lhs) &&
- !isa<ObjCPropertyRefExpr>(lhs))
- || rhs->isTypeDependent() || Opc != BO_Assign) &&
+ (!isa<ObjCPropertyRefExpr>(lhs)
+ || rhs->isTypeDependent() || Opc != BO_Assign) &&
(lhs->getType()->isOverloadableType() ||
rhs->getType()->isOverloadableType())) {
// Find all of the overloaded operators visible from this
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));
}
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));
// 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<ObjCImplicitSetterGetterRefExpr>(E))
- DiagID = diag::warn_unused_property_expr;
-
if (const CXXExprWithTemporaries *Temps = dyn_cast<CXXExprWithTemporaries>(E))
E = Temps->getSubExpr();
-
+
+ E = E->IgnoreParens();
if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
if (E->getType()->isVoidType())
return;
return;
}
}
- }
- else if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E)) {
+ } else if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E)) {
const ObjCMethodDecl *MD = ME->getMethodDecl();
if (MD && MD->getAttr<WarnUnusedResultAttr>()) {
Diag(Loc, diag::warn_unused_call) << R1 << R2 << "warn_unused_result";
return;
}
+ } else if (isa<ObjCPropertyRefExpr>(E)) {
+ DiagID = diag::warn_unused_property_expr;
} else if (const CXXFunctionalCastExpr *FC
= dyn_cast<CXXFunctionalCastExpr>(E)) {
if (isa<CXXConstructExpr>(FC->getSubExpr()) ||
/*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.
template<typename Derived>
ExprResult
TreeTransform<Derived>::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.
if (!getDerived().AlwaysRebuild() &&
Base.get() == E->getBase())
return SemaRef.Owned(E);
-
- return getDerived().RebuildObjCPropertyRefExpr(Base.get(), E->getProperty(),
- E->getLocation());
-}
-template<typename Derived>
-ExprResult
-TreeTransform<Derived>::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<typename Derived>
void VisitObjCProtocolExpr(ObjCProtocolExpr *E);
void VisitObjCIvarRefExpr(ObjCIvarRefExpr *E);
void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E);
- void VisitObjCImplicitSetterGetterRefExpr(
- ObjCImplicitSetterGetterRefExpr *E);
void VisitObjCMessageExpr(ObjCMessageExpr *E);
void VisitObjCIsaExpr(ObjCIsaExpr *E);
void ASTStmtReader::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
VisitExpr(E);
- E->setProperty(cast<ObjCPropertyDecl>(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<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++]));
+ ObjCMethodDecl *Setter =
+ cast<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++]));
+ E->setImplicitProperty(Getter, Setter);
+ } else {
+ E->setExplicitProperty(
+ cast<ObjCPropertyDecl>(Reader.GetDecl(Record[Idx++])));
}
- else
- E->setBase(Reader.ReadSubExpr());
-}
-
-void ASTStmtReader::VisitObjCImplicitSetterGetterRefExpr(
- ObjCImplicitSetterGetterRefExpr *E) {
- VisitExpr(E);
- E->setGetterMethod(
- cast_or_null<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++])));
- E->setSetterMethod(
- cast_or_null<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++])));
- E->setInterfaceDecl(
- cast_or_null<ObjCInterfaceDecl>(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<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
+ break;
+ }
}
void ASTStmtReader::VisitObjCMessageExpr(ObjCMessageExpr *E) {
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,
void VisitObjCProtocolExpr(ObjCProtocolExpr *E);
void VisitObjCIvarRefExpr(ObjCIvarRefExpr *E);
void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E);
- void VisitObjCImplicitSetterGetterRefExpr(
- ObjCImplicitSetterGetterRefExpr *E);
void VisitObjCMessageExpr(ObjCMessageExpr *E);
void VisitObjCIsaExpr(ObjCIsaExpr *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());
if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
return RE->getDecl();
if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E))
- return PRE->getProperty();
+ return PRE->isExplicitProperty() ? PRE->getExplicitProperty() : 0;
if (CallExpr *CE = dyn_cast<CallExpr>(E))
return getDeclFromExpr(CE->getCallee());
case Stmt::ObjCEncodeExprClass:
case Stmt::ObjCSelectorExprClass:
case Stmt::ObjCProtocolExprClass:
- case Stmt::ObjCImplicitSetterGetterRefExprClass:
case Stmt::ObjCIsaExprClass:
case Stmt::ShuffleVectorExprClass:
case Stmt::BlockExprClass:
case Stmt::CXXConstructExprClass:
case Stmt::CXXTemporaryObjectExprClass:
// FIXME: CXXUnresolvedConstructExpr
- // FIXME: ObjCImplicitSetterGetterRefExpr?
K = CXCursor_CallExpr;
break;