[cfe-commits] r85836 - in /cfe/trunk: include/clang/AST/DeclObjC.h include/clang/Basic/DiagnosticSemaKinds.td lib/AST/DeclObjC.cpp lib/Sema/SemaDeclObjC.cpp test/SemaObjC/continuation-class-err.m

Fariborz Jahanian fjahanian at apple.com
Mon Nov 2 14:45:15 PST 2009


Author: fjahanian
Date: Mon Nov  2 16:45:15 2009
New Revision: 85836

URL: http://llvm.org/viewvc/llvm-project?rev=85836&view=rev
Log:
Property declared in continuation class can only be used to
change a readonly property declared in the class (and its inherited protocols)
to writable property. (Fixes radar 7350645).

Modified:
    cfe/trunk/include/clang/AST/DeclObjC.h
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/AST/DeclObjC.cpp
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp
    cfe/trunk/test/SemaObjC/continuation-class-err.m

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

==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Mon Nov  2 16:45:15 2009
@@ -347,6 +347,8 @@
   ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const;
 
   ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const;
+  ObjCPropertyDecl *FindPropertyVisibleInPrimaryClass(
+                                            IdentifierInfo *PropertyId) const;
 
   // Marks the end of the container.
   SourceLocation getAtEndLoc() const { return AtEndLoc; }

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=85836&r1=85835&r2=85836&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Nov  2 16:45:15 2009
@@ -264,7 +264,8 @@
     "'copy' attribute must be specified for the block property "
     "when -fobjc-gc-only is specified">;
 def err_use_continuation_class : Error<
-  "attribute of property in continuation class of %0 can only  be 'readwrite'">;
+  "property declaration in continuation class of %0 is to change a 'readonly' "
+  "property to 'readwrite'">;
 def err_continuation_class : Error<"continuation class has no primary class">;
 def err_property_type : Error<"property cannot have array or function type %0">;
 def error_missing_property_context : Error<
@@ -274,7 +275,7 @@
 def error_category_property : Error<
   "property declared in category %0 cannot be implemented in "
   "class implementation">;
-def note_category_property : Note<
+def note_property_declare : Note<
   "property declared here">;
 def error_synthesize_category_decl : Error<
   "@synthesize not allowed in a category's implementation">;

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

==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Mon Nov  2 16:45:15 2009
@@ -118,6 +118,27 @@
   return 0;
 }
 
+/// FindPropertyVisibleInPrimaryClass - Finds declaration of the property
+/// with name 'PropertyId' in the primary class; including those in protocols
+/// (direct or indirect) used by the promary class.
+/// FIXME: Convert to DeclContext lookup...
+///
+ObjCPropertyDecl *
+ObjCContainerDecl::FindPropertyVisibleInPrimaryClass(
+                                            IdentifierInfo *PropertyId) const {
+  assert(isa<ObjCInterfaceDecl>(this) && "FindPropertyVisibleInPrimaryClass");
+  for (prop_iterator I = prop_begin(), E = prop_end(); I != E; ++I)
+    if ((*I)->getIdentifier() == PropertyId)
+      return *I;
+  const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(this);
+  // Look through protocols.
+  for (ObjCInterfaceDecl::protocol_iterator I = OID->protocol_begin(),
+       E = OID->protocol_end(); I != E; ++I)
+    if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
+      return P;
+  return 0;
+}
+
 void ObjCInterfaceDecl::mergeClassExtensionProtocolList(
                               ObjCProtocolDecl *const* ExtList, unsigned ExtNum,
                               ASTContext &C)

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Mon Nov  2 16:45:15 2009
@@ -1893,17 +1893,9 @@
       // handling.
       if ((CCPrimary = CDecl->getClassInterface())) {
         // Find the property in continuation class's primary class only.
-        ObjCPropertyDecl *PIDecl = 0;
         IdentifierInfo *PropertyId = FD.D.getIdentifier();
-        for (ObjCInterfaceDecl::prop_iterator
-               I = CCPrimary->prop_begin(), E = CCPrimary->prop_end();
-             I != E; ++I)
-          if ((*I)->getIdentifier() == PropertyId) {
-            PIDecl = *I;
-            break;
-          }
-
-        if (PIDecl) {
+        if (ObjCPropertyDecl *PIDecl = 
+              CCPrimary->FindPropertyVisibleInPrimaryClass(PropertyId)) {
           // property 'PIDecl's readonly attribute will be over-ridden
           // with continuation class's readwrite property attribute!
           unsigned PIkind = PIDecl->getPropertyAttributes();
@@ -1917,9 +1909,11 @@
             if (Attributes & ObjCDeclSpec::DQ_PR_copy)
               PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy);
             PIDecl->setSetterName(SetterSel);
-          } else
+          } else {
             Diag(AtLoc, diag::err_use_continuation_class)
               << CCPrimary->getDeclName();
+            Diag(PIDecl->getLocation(), diag::note_property_declare);
+          }
           *isOverridingProperty = true;
           // Make sure setter decl is synthesized, and added to primary
           // class's list.
@@ -2051,7 +2045,7 @@
         dyn_cast<ObjCCategoryDecl>(property->getDeclContext())) {
       if (CD->getIdentifier()) {
         Diag(PropertyLoc, diag::error_category_property) << CD->getDeclName();
-        Diag(property->getLocation(), diag::note_category_property);
+        Diag(property->getLocation(), diag::note_property_declare);
         return DeclPtrTy();
       }
     }

Modified: cfe/trunk/test/SemaObjC/continuation-class-err.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/continuation-class-err.m?rev=85836&r1=85835&r2=85836&view=diff

==============================================================================
--- cfe/trunk/test/SemaObjC/continuation-class-err.m (original)
+++ cfe/trunk/test/SemaObjC/continuation-class-err.m Mon Nov  2 16:45:15 2009
@@ -6,10 +6,35 @@
   id _object1;
 }
 @property(readonly) id object;
- at property(readwrite, assign) id object1;
+ at property(readwrite, assign) id object1; // expected-note {{property declared here}}
 @end
 
 @interface ReadOnly ()
 @property(readwrite, copy) id object;	
- at property(readonly) id object1; // expected-error {{attribute of property in continuation class of 'ReadOnly' can only  be 'readwrite'}}
+ at property(readonly) id object1; // expected-error {{property declaration in continuation class of 'ReadOnly' is to change a 'readonly' property to 'readwrite'}}
 @end
+
+ at protocol Proto
+  @property (copy) id fee; // expected-note {{property declared here}}
+ at end
+
+ at protocol Foo<Proto>
+  @property (copy) id foo; // expected-note {{property declared here}}
+ at end
+
+ at interface Bar  <Foo> {
+        id _foo;
+        id _fee;
+}
+ at end
+
+ at interface Bar ()
+ at property (copy) id foo;	// expected-error {{property declaration in continuation class of 'Bar' is to change a 'readonly' property to 'readwrite'}}
+ at property (copy) id fee;	// expected-error {{property declaration in continuation class of 'Bar' is to change a 'readonly' property to 'readwrite'}}
+ at end
+
+ at implementation Bar
+ at synthesize foo = _foo;
+ at synthesize fee = _fee;
+ at end
+





More information about the cfe-commits mailing list