]> granicus.if.org Git - clang/commitdiff
Any property declared in a class extension might have user
authorFariborz Jahanian <fjahanian@apple.com>
Fri, 10 Dec 2010 23:36:33 +0000 (23:36 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Fri, 10 Dec 2010 23:36:33 +0000 (23:36 +0000)
declared setter or getter in current class extension or one
of the other class extensions. Mark them as synthesized as
property will be synthesized when property with same name is
seen in the @implementation. This prevents bogus warning
about unimplemented methods to be issued for these methods.
Fixes // rdar://8747333

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@121597 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDeclObjC.cpp
lib/Sema/SemaObjCProperty.cpp
test/SemaObjC/property-in-class-extension.m

index 57c19222924463f6e9a56a31dbb1418287393325..a7014f6755bc801096423f94846c389a600a5df2 100644 (file)
@@ -1522,8 +1522,29 @@ void Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd,
 
     // Compare protocol properties with those in category
     CompareProperties(C, C);
-    if (C->IsClassExtension())
-      DiagnoseClassExtensionDupMethods(C, C->getClassInterface());
+    if (C->IsClassExtension()) {
+      ObjCInterfaceDecl *CCPrimary = C->getClassInterface();
+      DiagnoseClassExtensionDupMethods(C, CCPrimary);
+      for (ObjCContainerDecl::prop_iterator I = C->prop_begin(),
+           E = C->prop_end(); I != E; ++I) {
+        // Any property declared in a class extension might have user
+        // declared setter or getter in current class extension or one
+        // of the other class extensions. Mark them as synthesized as
+        // property will be synthesized when property with same name is
+        // seen in the @implementation.
+        for (const ObjCCategoryDecl *ClsExtDecl =
+             CCPrimary->getFirstClassExtension();
+             ClsExtDecl; ClsExtDecl = ClsExtDecl->getNextClassExtension()) {
+          if (ObjCMethodDecl *GetterMethod =
+              ClsExtDecl->getInstanceMethod((*I)->getGetterName()))
+            GetterMethod->setSynthesized(true);
+          if (!(*I)->isReadOnly())
+            if (ObjCMethodDecl *SetterMethod =
+                ClsExtDecl->getInstanceMethod((*I)->getSetterName()))
+              SetterMethod->setSynthesized(true);
+        }        
+      }
+    }
   }
   if (ObjCContainerDecl *CDecl = dyn_cast<ObjCContainerDecl>(ClassDecl)) {
     if (CDecl->getIdentifier())
index 9fc6853e462805222ef1640569cd12b68064df81..aa934d8e9c5882f645740769799539f0fd0122f1 100644 (file)
@@ -111,6 +111,7 @@ Sema::HandlePropertyInClassExtension(Scope *S, ObjCCategoryDecl *CDecl,
   
   // Create a new ObjCPropertyDecl with the DeclContext being
   // the class extension.
+  // FIXME. We should really be using CreatePropertyDecl for this.
   ObjCPropertyDecl *PDecl =
     ObjCPropertyDecl::Create(Context, DC, FD.D.getIdentifierLoc(),
                              PropertyId, AtLoc, T);
@@ -118,7 +119,9 @@ Sema::HandlePropertyInClassExtension(Scope *S, ObjCCategoryDecl *CDecl,
     PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly);
   if (Attributes & ObjCDeclSpec::DQ_PR_readwrite)
     PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readwrite);
-
+  // Set setter/getter selector name. Needed later.
+  PDecl->setGetterName(GetterSel);
+  PDecl->setSetterName(SetterSel);
   DC->addDecl(PDecl);
 
   // We need to look in the @interface to see if the @property was
index af68a43f02cbc637808e1a8d3c88b4389f1fb7c1..0f0c88401553eaf3aad0c32bc1e104712037ea16 100644 (file)
@@ -12,4 +12,28 @@ void FUNC () {
     foo.bar = 0; // expected-error {{assigning to property with 'readonly' attribute not allowed}}
 }
 
+// rdar://8747333
+@class NSObject;
+
+@interface rdar8747333  {
+@private
+    NSObject *_bar;
+    NSObject *_baz;
+}
+- (NSObject *)baz;
+@end
+
+@interface rdar8747333 ()
+- (NSObject *)bar;
+@end
+
+@interface rdar8747333 ()
+@property (readwrite, assign) NSObject *bar;
+@property (readwrite, assign) NSObject *baz;
+@end
+
+@implementation rdar8747333
+@synthesize bar = _bar;
+@synthesize baz = _baz;
+@end