[cfe-commits] r59874 - in /cfe/trunk: include/clang/AST/Expr.h include/clang/AST/ExprObjC.h include/clang/AST/StmtNodes.def include/clang/Basic/DiagnosticKinds.def lib/AST/Expr.cpp lib/AST/StmtDumper.cpp lib/AST/StmtPrinter.cpp lib/AST/StmtSerialization.cpp lib/Analysis/CheckObjCDealloc.cpp lib/CodeGen/CGExprAgg.cpp lib/CodeGen/CGObjC.cpp lib/CodeGen/CodeGenFunction.h lib/Sema/SemaExpr.cpp

Fariborz Jahanian fjahanian at apple.com
Sat Nov 22 10:39:37 PST 2008


Author: fjahanian
Date: Sat Nov 22 12:39:36 2008
New Revision: 59874

URL: http://llvm.org/viewvc/llvm-project?rev=59874&view=rev
Log:
New AST node to access "implicit" setter/getter using property dor syntax.
Issuing diagnostics when assigning to read-only properties.
This is work in progress.

Modified:
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/include/clang/AST/ExprObjC.h
    cfe/trunk/include/clang/AST/StmtNodes.def
    cfe/trunk/include/clang/Basic/DiagnosticKinds.def
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/lib/AST/StmtDumper.cpp
    cfe/trunk/lib/AST/StmtPrinter.cpp
    cfe/trunk/lib/AST/StmtSerialization.cpp
    cfe/trunk/lib/Analysis/CheckObjCDealloc.cpp
    cfe/trunk/lib/CodeGen/CGExprAgg.cpp
    cfe/trunk/lib/CodeGen/CGObjC.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h
    cfe/trunk/lib/Sema/SemaExpr.cpp

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=59874&r1=59873&r2=59874&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Sat Nov 22 12:39:36 2008
@@ -103,7 +103,8 @@
     MLV_IncompleteType,
     MLV_ConstQualified,
     MLV_ArrayType,
-    MLV_NotBlockQualified
+    MLV_NotBlockQualified,
+    MLV_ReadonlyProperty
   };
   isModifiableLvalueResult isModifiableLvalue(ASTContext &Ctx) const;
   

Modified: cfe/trunk/include/clang/AST/ExprObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprObjC.h?rev=59874&r1=59873&r2=59874&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/ExprObjC.h (original)
+++ cfe/trunk/include/clang/AST/ExprObjC.h Sat Nov 22 12:39:36 2008
@@ -195,68 +195,21 @@
 };
 
 /// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC
-/// property. Note that dot-syntax can also be used to access
-/// "implicit" properties (i.e. methods following the property naming
-/// convention). Additionally, sema is not yet smart enough to know if
-/// a property reference is to a getter or a setter, so the expr must
-/// have access to both methods.
+/// property.
 ///
-// FIXME: Consider splitting these into separate Expr classes.
 class ObjCPropertyRefExpr : public Expr {
-public:
-  enum Kind {
-    PropertyRef, // This expressions references a declared property.
-    MethodRef   // This expressions references methods.
-  };
-
 private:
-  // A dot-syntax reference via methods must always have a getter. We
-  // avoid storing the kind explicitly by relying on this invariant
-  // and assuming this is a MethodRef iff Getter is non-null. Setter
-  // can be null in situations which access a read-only property.
-  union {
-    ObjCPropertyDecl *AsProperty;
-    struct {
-      ObjCMethodDecl *Setter;
-      ObjCMethodDecl *Getter;
-    } AsMethod;
-  } Referent;
+  ObjCPropertyDecl *AsProperty;
   SourceLocation Loc;
   Stmt *Base;
   
 public:
   ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, 
                       SourceLocation l, Expr *base)
-    : Expr(ObjCPropertyRefExprClass, t), Loc(l), Base(base) {
-    Referent.AsMethod.Getter = Referent.AsMethod.Setter = NULL;
-    Referent.AsProperty = PD;
-  }
-  ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
-                      QualType t, 
-                      SourceLocation l, Expr *base)
-    : Expr(ObjCPropertyRefExprClass, t), Loc(l), Base(base) {
-    Referent.AsMethod.Getter = Getter;
-    Referent.AsMethod.Setter = Setter;
-  }
-
-  Kind getKind() const { 
-    return Referent.AsMethod.Getter ? MethodRef : PropertyRef; 
+    : Expr(ObjCPropertyRefExprClass, t), AsProperty(PD), Loc(l), Base(base) {
   }
-
   ObjCPropertyDecl *getProperty() const {
-    assert(getKind() == PropertyRef && 
-           "Cannot get property from an ObjCPropertyRefExpr using methods");
-    return Referent.AsProperty;
-  }
-  ObjCMethodDecl *getGetterMethod() const {
-    assert(getKind() == MethodRef && 
-           "Cannot get method from an ObjCPropertyRefExpr using a property");
-    return Referent.AsMethod.Getter;
-  }
-  ObjCMethodDecl *getSetterMethod() const {
-    assert(getKind() == MethodRef && 
-           "Cannot get method from an ObjCPropertyRefExpr using a property");
-    return Referent.AsMethod.Setter;
+    return AsProperty;
   }
   
   virtual SourceRange getSourceRange() const { 
@@ -281,6 +234,60 @@
   static ObjCPropertyRefExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
 };
 
+/// ObjCKVCRefExpr - A dot-syntax expression to access "implicit" properties 
+/// (i.e. methods following the property naming convention). KVC stands for
+/// Key Value Encoding, a generic concept for accessing or setting a 'Key'
+/// value for an object.
+///
+
+class ObjCKVCRefExpr : public Expr {
+private:
+  
+  ObjCMethodDecl *Setter;
+  ObjCMethodDecl *Getter;
+  SourceLocation Loc;
+  Stmt *Base;
+    
+public:
+  ObjCKVCRefExpr(ObjCMethodDecl *getter,
+                 QualType t, 
+                 SourceLocation l, Expr *base)
+    : Expr(ObjCKVCRefExprClass, t), Setter(0), 
+      Getter(getter), Loc(l), Base(base) {
+    }
+  
+  ObjCMethodDecl *getGetterMethod() const {
+      return Getter;
+  }
+  void setSetterMethod(ObjCMethodDecl *setter) {
+    Setter = setter;
+  }
+  ObjCMethodDecl *getSetterMethod() const {
+    return Setter;
+  }
+    
+  virtual SourceRange getSourceRange() const { 
+    return SourceRange(getBase()->getLocStart(), Loc); 
+  }
+  const Expr *getBase() const { return cast<Expr>(Base); }
+  Expr *getBase() { return cast<Expr>(Base); }
+  void setBase(Expr * base) { Base = base; }
+    
+  SourceLocation getLocation() const { return Loc; }
+    
+  static bool classof(const Stmt *T) { 
+    return T->getStmtClass() == ObjCKVCRefExprClass; 
+  }
+  static bool classof(const ObjCKVCRefExpr *) { return true; }
+    
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+    
+  virtual void EmitImpl(llvm::Serializer& S) const;
+  static ObjCKVCRefExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
+};
+  
 class ObjCMessageExpr : public Expr {
   // SubExprs - The receiver and arguments of the message expression.
   Stmt **SubExprs;

Modified: cfe/trunk/include/clang/AST/StmtNodes.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/StmtNodes.def?rev=59874&r1=59873&r2=59874&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/StmtNodes.def (original)
+++ cfe/trunk/include/clang/AST/StmtNodes.def Sat Nov 22 12:39:36 2008
@@ -115,6 +115,7 @@
 STMT(ObjCProtocolExpr     , Expr)
 STMT(ObjCIvarRefExpr      , Expr)
 STMT(ObjCPropertyRefExpr  , Expr)
+STMT(ObjCKVCRefExpr       , Expr)
 STMT(ObjCSuperExpr        , Expr)
 
 // Clang Extensions.

Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=59874&r1=59873&r2=59874&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Sat Nov 22 12:39:36 2008
@@ -541,6 +541,8 @@
      "@synthesize not allowed in a category's implementation")
 DIAG(error_property_ivar_type, ERROR,
      "type of property '%0'  does not match type of ivar '%1'") 
+DIAG(error_readonly_property_assignment, ERROR,
+     "assigning to property with 'readonly' attribute not allowed")
 DIAG(warn_readonly_property, WARNING,
      "attribute 'readonly' of property '%0' restricts attribute "
      "'readwrite' of property inherited from '%1'")

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=59874&r1=59873&r2=59874&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Sat Nov 22 12:39:36 2008
@@ -463,6 +463,8 @@
     return LV_Valid;
   case ObjCPropertyRefExprClass: // FIXME: check if read-only property.
     return LV_Valid;
+  case ObjCKVCRefExprClass: // FIXME: check if read-only property.
+      return LV_Valid;
   case PredefinedExprClass:
     return LV_Valid;
   case VAArgExprClass:
@@ -545,6 +547,16 @@
     if (!BDR->isByRef() && isa<VarDecl>(BDR->getDecl()))
       return MLV_NotBlockQualified;
   }
+  // Assigning to a readonly property?
+  if (getStmtClass() == ObjCPropertyRefExprClass) {
+    const ObjCPropertyRefExpr* PropExpr = cast<ObjCPropertyRefExpr>(this);
+    if (ObjCPropertyDecl *PDecl = PropExpr->getProperty()) {
+      ObjCPropertyDecl::PropertyAttributeKind Pkind = 
+        PDecl->getPropertyAttributes();
+      if (Pkind == ObjCPropertyDecl::OBJC_PR_readonly)
+        return MLV_ReadonlyProperty;
+    }
+  }
   return MLV_Valid;    
 }
 
@@ -1353,6 +1365,10 @@
 Stmt::child_iterator ObjCPropertyRefExpr::child_begin() { return &Base; }
 Stmt::child_iterator ObjCPropertyRefExpr::child_end() { return &Base+1; }
 
+// ObjCKVCRefExpr
+Stmt::child_iterator ObjCKVCRefExpr::child_begin() { return &Base; }
+Stmt::child_iterator ObjCKVCRefExpr::child_end() { return &Base+1; }
+
 // ObjCSuperExpr
 Stmt::child_iterator ObjCSuperExpr::child_begin() { return child_iterator(); }
 Stmt::child_iterator ObjCSuperExpr::child_end() { return child_iterator(); }

Modified: cfe/trunk/lib/AST/StmtDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtDumper.cpp?rev=59874&r1=59873&r2=59874&view=diff

==============================================================================
--- cfe/trunk/lib/AST/StmtDumper.cpp (original)
+++ cfe/trunk/lib/AST/StmtDumper.cpp Sat Nov 22 12:39:36 2008
@@ -139,6 +139,7 @@
     void VisitObjCSelectorExpr(ObjCSelectorExpr *Node);
     void VisitObjCProtocolExpr(ObjCProtocolExpr *Node);
     void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node);
+    void VisitObjCKVCRefExpr(ObjCKVCRefExpr *Node);
     void VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node);
     void VisitObjCSuperExpr(ObjCSuperExpr *Node);
   };
@@ -470,16 +471,18 @@
 void StmtDumper::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
   DumpExpr(Node);
 
-  if (Node->getKind() == ObjCPropertyRefExpr::MethodRef) {
-    ObjCMethodDecl *Getter = Node->getGetterMethod();
-    ObjCMethodDecl *Setter = Node->getSetterMethod();
-    fprintf(F, " Kind=MethodRef Getter=\"%s\" Setter=\"%s\"", 
-            Getter->getSelector().getName().c_str(),
-            Setter ? Setter->getSelector().getName().c_str() : "(null)");
-  } else {
-    fprintf(F, " Kind=PropertyRef Property=\"%s\"", 
-            Node->getProperty()->getIdentifierName());
-  }
+  fprintf(F, " Kind=PropertyRef Property=\"%s\"", 
+          Node->getProperty()->getIdentifierName());
+}
+
+void StmtDumper::VisitObjCKVCRefExpr(ObjCKVCRefExpr *Node) {
+  DumpExpr(Node);
+  
+  ObjCMethodDecl *Getter = Node->getGetterMethod();
+  ObjCMethodDecl *Setter = Node->getSetterMethod();
+  fprintf(F, " Kind=MethodRef Getter=\"%s\" Setter=\"%s\"", 
+          Getter->getSelector().getName().c_str(),
+          Setter ? Setter->getSelector().getName().c_str() : "(null)");
 }
 
 void StmtDumper::VisitObjCSuperExpr(ObjCSuperExpr *Node) {

Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=59874&r1=59873&r2=59874&view=diff

==============================================================================
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Sat Nov 22 12:39:36 2008
@@ -502,6 +502,14 @@
   // FIXME: OS << Node->getDecl()->getName();
 }
 
+void StmtPrinter::VisitObjCKVCRefExpr(ObjCKVCRefExpr *Node) {
+  if (Node->getBase()) {
+    PrintExpr(Node->getBase());
+    OS << ".";
+  }
+  // FIXME: Setter/Getter names
+}
+
 void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) {
   switch (Node->getIdentType()) {
     default:

Modified: cfe/trunk/lib/AST/StmtSerialization.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtSerialization.cpp?rev=59874&r1=59873&r2=59874&view=diff

==============================================================================
--- cfe/trunk/lib/AST/StmtSerialization.cpp (original)
+++ cfe/trunk/lib/AST/StmtSerialization.cpp Sat Nov 22 12:39:36 2008
@@ -1150,14 +1150,14 @@
 void ObjCPropertyRefExpr::EmitImpl(Serializer& S) const {
   S.Emit(Loc);
   S.Emit(getType());
-  unsigned Kind = getKind();
-  S.Emit(Kind);
-  if (Kind == PropertyRef) {
-    S.EmitPtr(getProperty());
-  } else {
-    S.EmitPtr(getGetterMethod());
-    S.EmitPtr(getSetterMethod());
-  }
+  S.EmitPtr(getProperty());
+}
+
+void ObjCKVCRefExpr::EmitImpl(Serializer& S) const {
+  S.Emit(Loc);
+  S.Emit(getType());
+  S.EmitPtr(getGetterMethod());
+  S.EmitPtr(getSetterMethod());
 }
   
 ObjCPropertyRefExpr* ObjCPropertyRefExpr::CreateImpl(Deserializer& D, 
@@ -1165,13 +1165,17 @@
   SourceLocation Loc = SourceLocation::ReadVal(D);
   QualType T = QualType::ReadVal(D);
   ObjCPropertyRefExpr* dr = new ObjCPropertyRefExpr(NULL,T,Loc,0);
-  unsigned Kind = D.ReadInt();
-  if (Kind == PropertyRef) {
-    D.ReadPtr(dr->Referent.AsProperty,false);
-  } else {
-    D.ReadPtr(dr->Referent.AsMethod.Setter,false);
-    D.ReadPtr(dr->Referent.AsMethod.Getter,false);
-  }
+  D.ReadPtr(dr->AsProperty,false);
+  return dr;
+}
+
+ObjCKVCRefExpr* ObjCKVCRefExpr::CreateImpl(Deserializer& D, 
+                                           ASTContext& C) {
+  SourceLocation Loc = SourceLocation::ReadVal(D);
+  QualType T = QualType::ReadVal(D);
+  ObjCKVCRefExpr* dr = new ObjCKVCRefExpr(NULL,T,Loc,0);
+  D.ReadPtr(dr->Setter,false);
+  D.ReadPtr(dr->Getter,false);
   return dr;
 }
 

Modified: cfe/trunk/lib/Analysis/CheckObjCDealloc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CheckObjCDealloc.cpp?rev=59874&r1=59873&r2=59874&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/CheckObjCDealloc.cpp (original)
+++ cfe/trunk/lib/Analysis/CheckObjCDealloc.cpp Sat Nov 22 12:39:36 2008
@@ -72,8 +72,7 @@
     if (BO->isAssignmentOp())
       if(ObjCPropertyRefExpr* PRE = 
          dyn_cast<ObjCPropertyRefExpr>(BO->getLHS()->IgnoreParenCasts()))
-          if(PRE->getKind() == ObjCPropertyRefExpr::PropertyRef &&
-             PRE->getProperty() == PD)
+          if(PRE->getProperty() == PD)
             if(BO->getRHS()->isNullPointerConstant(Ctx))
               return true;
   

Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=59874&r1=59873&r2=59874&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Sat Nov 22 12:39:36 2008
@@ -87,6 +87,7 @@
     EmitAggLoadOfLValue(E);
   }
   void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E);
+  void VisitObjCKVCRefExpr(ObjCKVCRefExpr *E);
   
   void VisitConditionalOperator(const ConditionalOperator *CO);
   void VisitInitListExpr(InitListExpr *E);
@@ -170,6 +171,18 @@
   CGF.EmitAggregateCopy(DestPtr, RV.getAggregateAddr(), E->getType());
 }
 
+void AggExprEmitter::VisitObjCKVCRefExpr(ObjCKVCRefExpr *E) {
+  RValue RV = CGF.EmitObjCPropertyGet(E);
+  assert(RV.isAggregate() && "Return value must be aggregate value!");
+  
+  // If the result is ignored, don't copy from the value.
+  if (DestPtr == 0)
+    // FIXME: If the source is volatile, we must read from it.
+    return;
+  
+  CGF.EmitAggregateCopy(DestPtr, RV.getAggregateAddr(), E->getType());
+}
+
 void AggExprEmitter::VisitOverloadExpr(const OverloadExpr *E) {
   RValue RV = CGF.EmitCallExpr(E->getFn(), E->arg_begin(),
                                E->arg_end(CGF.getContext()));

Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=59874&r1=59873&r2=59874&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjC.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjC.cpp Sat Nov 22 12:39:36 2008
@@ -278,40 +278,21 @@
   return Builder.CreateLoad(LocalDeclMap[OMD->getSelfDecl()], "self");
 }
 
-RValue CodeGenFunction::EmitObjCPropertyGet(const ObjCPropertyRefExpr *E) {
-  // Determine getter selector.
-  Selector S;
-  if (E->getKind() == ObjCPropertyRefExpr::MethodRef) {
-    S = E->getGetterMethod()->getSelector();
-  } else {
-    S = E->getProperty()->getGetterName();
-  }
+RValue CodeGenFunction::EmitObjCPropertyGet(const Expr *Exp) {
+  if (const ObjCPropertyRefExpr *E = dyn_cast<ObjCPropertyRefExpr>(Exp)) {
+    Selector S = E->getProperty()->getGetterName();
 
-  return CGM.getObjCRuntime().
+    return CGM.getObjCRuntime().
     GenerateMessageSend(*this, E->getType(), S, 
                         EmitScalarExpr(E->getBase()), 
                         false, CallArgList());
+  }
+  assert (0);
 }
 
 void CodeGenFunction::EmitObjCPropertySet(const ObjCPropertyRefExpr *E,
                                           RValue Src) {
-  Selector S;
-  if (E->getKind() == ObjCPropertyRefExpr::MethodRef) {
-    ObjCMethodDecl *Setter = E->getSetterMethod(); 
-    
-    if (Setter) {
-      S = Setter->getSelector();
-    } else {
-      // FIXME: This should be diagnosed by sema.
-      CGM.getDiags().Report(getContext().getFullLoc(E->getLocStart()),
-                            diag::err_typecheck_assign_const)
-        << E->getSourceRange();
-      return;
-    }
-  } else {
-    S = E->getProperty()->getSetterName();
-  }
-
+  Selector S = E->getProperty()->getSetterName();
   CallArgList Args;
   Args.push_back(std::make_pair(Src, E->getType()));
   CGM.getObjCRuntime().GenerateMessageSend(*this, getContext().VoidTy, S, 

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=59874&r1=59873&r2=59874&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Sat Nov 22 12:39:36 2008
@@ -524,7 +524,7 @@
   llvm::Value *EmitObjCStringLiteral(const ObjCStringLiteral *E);
   llvm::Value *EmitObjCSelectorExpr(const ObjCSelectorExpr *E);
   RValue EmitObjCMessageExpr(const ObjCMessageExpr *E);
-  RValue EmitObjCPropertyGet(const ObjCPropertyRefExpr *E);
+  RValue EmitObjCPropertyGet(const Expr *E);
   void EmitObjCPropertySet(const ObjCPropertyRefExpr *E, RValue Src);
 
 

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=59874&r1=59873&r2=59874&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat Nov 22 12:39:36 2008
@@ -1090,20 +1090,6 @@
   return VT; // should never get here (a typedef type should always be found).
 }
 
-/// constructSetterName - Return the setter name for the given
-/// identifier, i.e. "set" + Name where the initial character of Name
-/// has been capitalized.
-// FIXME: Merge with same routine in Parser. But where should this
-// live?
-static IdentifierInfo *constructSetterName(IdentifierTable &Idents,
-                                           const IdentifierInfo *Name) {
-  llvm::SmallString<100> SelectorName;
-  SelectorName = "set";
-  SelectorName.append(Name->getName(), Name->getName()+Name->getLength());
-  SelectorName[3] = toupper(SelectorName[3]);
-  return &Idents.get(&SelectorName[0], &SelectorName[SelectorName.size()]);
-}
-
 Action::ExprResult Sema::
 ActOnMemberReferenceExpr(ExprTy *Base, SourceLocation OpLoc,
                          tok::TokenKind OpKind, SourceLocation MemberLoc,
@@ -1212,27 +1198,10 @@
     }
     if (Getter) {
       // If we found a getter then this may be a valid dot-reference, we
-      // need to also look for the matching setter.
-      IdentifierInfo *SetterName = constructSetterName(PP.getIdentifierTable(),
-                                                       &Member);
-      Selector SetterSel = PP.getSelectorTable().getUnarySelector(SetterName);
-      ObjCMethodDecl *Setter = IFace->lookupInstanceMethod(SetterSel);
-
-      if (!Setter) {
-        if (ObjCMethodDecl *CurMeth = getCurMethodDecl())
-          if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
-            if (ObjCImplementationDecl *ImpDecl = 
-                ObjCImplementations[ClassDecl->getIdentifier()])
-              Setter = ImpDecl->getInstanceMethod(SetterSel);
-      }
-
-      // FIXME: There are some issues here. First, we are not
-      // diagnosing accesses to read-only properties because we do not
-      // know if this is a getter or setter yet. Second, we are
-      // checking that the type of the setter matches the type we
-      // expect.
-      return new ObjCPropertyRefExpr(Getter, Setter, Getter->getResultType(), 
-                                     MemberLoc, BaseExpr);
+      // will look for the matching setter, if it is needed. But we don't
+      // know this yet.
+      return new ObjCKVCRefExpr(Getter, Getter->getResultType(), 
+                                MemberLoc, BaseExpr);
     }
   }
   // Handle properties on qualified "id" protocols.
@@ -2550,6 +2519,9 @@
   case Expr::MLV_NotBlockQualified:
     Diag = diag::err_block_decl_ref_not_modifiable_lvalue;
     break;
+  case Expr::MLV_ReadonlyProperty:
+    Diag = diag::error_readonly_property_assignment;
+    break;
   }
 
   if (NeedType)





More information about the cfe-commits mailing list