]> granicus.if.org Git - clang/commitdiff
Implement FIXME related to <rdar://problem/6496506> Implement class setter/getter...
authorSteve Naroff <snaroff@apple.com>
Wed, 11 Mar 2009 20:12:18 +0000 (20:12 +0000)
committerSteve Naroff <snaroff@apple.com>
Wed, 11 Mar 2009 20:12:18 +0000 (20:12 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66689 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExpr.cpp
test/SemaObjC/newproperty-class-method-1.m

index 95c0baae5696c21c9e57a59a554038a8b4284039..e5a917474fd793ae0c63555021675adaa696733d 100644 (file)
@@ -1957,16 +1957,54 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
     // Also must look for a getter name which uses property syntax.
     Selector Sel = PP.getSelectorTable().getNullarySelector(&Member);
     if (ObjCMethodDecl *MD = getCurMethodDecl()) {
-      ObjCMethodDecl *OMD;
+      ObjCInterfaceDecl *IFace = MD->getClassInterface();
+      ObjCMethodDecl *Getter;
       // FIXME: need to also look locally in the implementation.
-      if ((OMD = MD->getClassInterface()->lookupClassMethod(Sel))) {
+      if ((Getter = IFace->lookupClassMethod(Sel))) {
         // Check the use of this method.
-        if (DiagnoseUseOfDecl(OMD, MemberLoc))
+        if (DiagnoseUseOfDecl(Getter, MemberLoc))
           return ExprError();
+      }
+      // If we found a getter then this may be a valid dot-reference, we
+      // will look for the matching setter, in case it is needed.
+      Selector SetterSel = 
+        SelectorTable::constructSetterName(PP.getIdentifierTable(), 
+                                           PP.getSelectorTable(), &Member);
+      ObjCMethodDecl *Setter = IFace->lookupClassMethod(SetterSel);
+      if (!Setter) {
+        // If this reference is in an @implementation, also check for 'private'
+        // methods.
+        if (ObjCImplementationDecl *ImpDecl =
+            ObjCImplementations[IFace->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]->getClassMethod(SetterSel);
+        }
+      }
 
-        return Owned(new (Context) ObjCMessageExpr(BaseExpr, Sel,
-                        OMD->getResultType(), OMD, OpLoc, MemberLoc, NULL, 0));
+      if (Setter && DiagnoseUseOfDecl(Setter, MemberLoc))
+        return ExprError();
+
+      if (Getter || Setter) {
+        QualType PType;
+
+        if (Getter)
+          PType = Getter->getResultType();
+        else {
+          for (ObjCMethodDecl::param_iterator PI = Setter->param_begin(),
+               E = Setter->param_end(); PI != E; ++PI)
+            PType = (*PI)->getType();
+        }
+        // FIXME: we must check that the setter has property type.
+        return Owned(new (Context) ObjCKVCRefExpr(Getter, PType,
+                                        Setter, MemberLoc, BaseExpr));
       }
+      return ExprError(Diag(MemberLoc, diag::err_property_not_found)
+        << &Member << BaseType);
     }
   }
   
index 177cb3e8fc44fcbd8e63a3ef9044c5d466ed09c7..155955c483f3fcb64eb01e12f1ba5808708149d5 100644 (file)
@@ -22,12 +22,9 @@ int _magicNumber = 0;
 
 + (void) classMeth
 {
-#if 0
-// FIXME: implement.
        self.magicNumber = 10;
        if (self.magicNumber != 10)
          abort ();
-#endif
 }
 @end