[cfe-commits] r59878 - in /cfe/trunk: include/clang/AST/Expr.h include/clang/AST/ExprObjC.h include/clang/Basic/DiagnosticKinds.def lib/AST/Expr.cpp lib/AST/StmtSerialization.cpp lib/Sema/SemaExpr.cpp test/SemaObjC/property-error-readonly-assign.m

Fariborz Jahanian fjahanian at apple.com
Sat Nov 22 12:25:51 PST 2008


Author: fjahanian
Date: Sat Nov 22 14:25:50 2008
New Revision: 59878

URL: http://llvm.org/viewvc/llvm-project?rev=59878&view=rev
Log:
Support for implicit property assignment. Error assigning to
'implicit' property with no 'setter'.

Modified:
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/include/clang/AST/ExprObjC.h
    cfe/trunk/include/clang/Basic/DiagnosticKinds.def
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/lib/AST/StmtSerialization.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/test/SemaObjC/property-error-readonly-assign.m

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

==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Sat Nov 22 14:25:50 2008
@@ -104,7 +104,8 @@
     MLV_ConstQualified,
     MLV_ArrayType,
     MLV_NotBlockQualified,
-    MLV_ReadonlyProperty
+    MLV_ReadonlyProperty,
+    MLV_NoSetterProperty
   };
   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=59878&r1=59877&r2=59878&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/ExprObjC.h (original)
+++ cfe/trunk/include/clang/AST/ExprObjC.h Sat Nov 22 14:25:50 2008
@@ -251,17 +251,15 @@
 public:
   ObjCKVCRefExpr(ObjCMethodDecl *getter,
                  QualType t, 
+                 ObjCMethodDecl *setter,
                  SourceLocation l, Expr *base)
-    : Expr(ObjCKVCRefExprClass, t), Setter(0), 
+    : Expr(ObjCKVCRefExprClass, t), Setter(setter),
       Getter(getter), Loc(l), Base(base) {
     }
   
   ObjCMethodDecl *getGetterMethod() const {
       return Getter;
   }
-  void setSetterMethod(ObjCMethodDecl *setter) {
-    Setter = setter;
-  }
   ObjCMethodDecl *getSetterMethod() const {
     return Setter;
   }

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

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Sat Nov 22 14:25:50 2008
@@ -543,6 +543,9 @@
      "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(error_nosetter_property_assignment, ERROR,
+     "setter method is needed to assign to object using property"
+     " assignment syntax")
 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=59878&r1=59877&r2=59878&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Sat Nov 22 14:25:50 2008
@@ -557,6 +557,12 @@
         return MLV_ReadonlyProperty;
     }
   }
+  // Assigning to an 'implicit' property?
+  if (getStmtClass() == ObjCKVCRefExprClass) {
+    const ObjCKVCRefExpr* KVCExpr = cast<ObjCKVCRefExpr>(this);
+    if (KVCExpr->getSetterMethod() == 0)
+      return MLV_NoSetterProperty;
+  }
   return MLV_Valid;    
 }
 

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

==============================================================================
--- cfe/trunk/lib/AST/StmtSerialization.cpp (original)
+++ cfe/trunk/lib/AST/StmtSerialization.cpp Sat Nov 22 14:25:50 2008
@@ -1173,7 +1173,7 @@
                                            ASTContext& C) {
   SourceLocation Loc = SourceLocation::ReadVal(D);
   QualType T = QualType::ReadVal(D);
-  ObjCKVCRefExpr* dr = new ObjCKVCRefExpr(NULL,T,Loc,0);
+  ObjCKVCRefExpr* dr = new ObjCKVCRefExpr(NULL,T,NULL,Loc,0);
   D.ReadPtr(dr->Setter,false);
   D.ReadPtr(dr->Getter,false);
   return dr;

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat Nov 22 14:25:50 2008
@@ -1090,6 +1090,20 @@
   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,
@@ -1198,9 +1212,30 @@
     }
     if (Getter) {
       // If we found a getter then this may be a valid dot-reference, we
-      // will look for the matching setter, if it is needed. But we don't
-      // know this yet.
-      return new ObjCKVCRefExpr(Getter, Getter->getResultType(), 
+      // will look for the matching setter, in case it is needed.
+      IdentifierInfo *SetterName = constructSetterName(PP.getIdentifierTable(),
+                                                       &Member);
+      Selector SetterSel = PP.getSelectorTable().getUnarySelector(SetterName);
+      ObjCMethodDecl *Setter = IFace->lookupInstanceMethod(SetterSel);
+      if (!Setter) {
+        // If this reference is in an @implementation, also check for 'private' 
+        // methods.
+        if (ObjCMethodDecl *CurMeth = getCurMethodDecl())
+          if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
+            if (ObjCImplementationDecl *ImpDecl = 
+                  ObjCImplementations[ClassDecl->getIdentifier()])
+              Setter = ImpDecl->getInstanceMethod(SetterSel);
+      }
+      // Look through local category implementations associated with the class.
+      if (!Setter) {
+        for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Setter; i++) {
+          if (ObjCCategoryImpls[i]->getClassInterface() == IFace)
+            Setter = ObjCCategoryImpls[i]->getInstanceMethod(SetterSel);
+        }
+      }
+      
+      // FIXME: we must check that the setter has property type.      
+      return new ObjCKVCRefExpr(Getter, Getter->getResultType(), Setter,
                                 MemberLoc, BaseExpr);
     }
   }
@@ -2522,6 +2557,9 @@
   case Expr::MLV_ReadonlyProperty:
     Diag = diag::error_readonly_property_assignment;
     break;
+  case Expr::MLV_NoSetterProperty:
+    Diag = diag::error_nosetter_property_assignment;
+    break;
   }
 
   if (NeedType)

Modified: cfe/trunk/test/SemaObjC/property-error-readonly-assign.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/property-error-readonly-assign.m?rev=59878&r1=59877&r2=59878&view=diff

==============================================================================
--- cfe/trunk/test/SemaObjC/property-error-readonly-assign.m (original)
+++ cfe/trunk/test/SemaObjC/property-error-readonly-assign.m Sat Nov 22 14:25:50 2008
@@ -6,8 +6,16 @@
 @property int ok;
 @end
 
-void f0(A *a) {
+ at interface B
+ -(void) setOk:(int)arg;
+ -(int) x;
+ -(int) ok;
+ at end
+
+void f0(A *a, B* b) {
   a.x = 10;  // expected-error {{assigning to property with 'readonly' attribute not allowed}}
   a.ok = 20;
+  b.x = 10;  // expected-error {{setter method is needed to assign to object using property assignment syntax}}
+  b.ok = 20;
 }
 





More information about the cfe-commits mailing list