]> granicus.if.org Git - clang/commitdiff
For ObjCPropertyDecls in class extensions, use the class extension as the lexical...
authorTed Kremenek <kremenek@apple.com>
Tue, 21 Sep 2010 18:28:43 +0000 (18:28 +0000)
committerTed Kremenek <kremenek@apple.com>
Tue, 21 Sep 2010 18:28:43 +0000 (18:28 +0000)
ObjCMethodDecls.  Further, use the location of the new property declaration as the location of new ObjCMethodDecls
(if they didn't previously exist).

This fixes more of the issues reported in <rdar://problem/7410145>.

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

include/clang/Sema/Sema.h
lib/Sema/SemaObjCProperty.cpp
test/Index/properties-class-extensions.m

index af0174965f440bf28f127d7bb69e8ad5bef78a92..a45437762c79c4887717e332da7df7094b63caaa 100644 (file)
@@ -3672,7 +3672,19 @@ public:
   void CheckObjCPropertyAttributes(Decl *PropertyPtrTy,
                                    SourceLocation Loc,
                                    unsigned &Attributes);
-  void ProcessPropertyDecl(ObjCPropertyDecl *property, ObjCContainerDecl *DC);
+
+  /// Process the specified property declaration and create decls for the
+  /// setters and getters as needed.
+  /// \param property The property declaration being processed
+  /// \param DC The semantic container for the property
+  /// \param redeclaredProperty Declaration for property if redeclared 
+  ///        in class extension.
+  /// \param lexicalDC Container for redeclaredProperty.
+  void ProcessPropertyDecl(ObjCPropertyDecl *property,
+                           ObjCContainerDecl *DC,
+                           ObjCPropertyDecl *redeclaredProperty = 0,
+                           ObjCContainerDecl *lexicalDC = 0);
+
   void DiagnosePropertyMismatch(ObjCPropertyDecl *Property,
                                 ObjCPropertyDecl *SuperProperty,
                                 const IdentifierInfo *Name);
index 7181d58f7fb07cb389d51fc9d83bd2f684251cf1..a6f251e107f5ade31134b01086b87fd519e98672 100644 (file)
@@ -188,7 +188,7 @@ Sema::HandlePropertyInClassExtension(Scope *S, ObjCCategoryDecl *CDecl,
   }
   *isOverridingProperty = true;
   // Make sure setter decl is synthesized, and added to primary class's list.
-  ProcessPropertyDecl(PIDecl, CCPrimary);
+  ProcessPropertyDecl(PIDecl, CCPrimary, PDecl, CDecl);
   return 0;
 }
 
@@ -1061,7 +1061,10 @@ Sema::AtomicPropertySetterGetterRules (ObjCImplDecl* IMPDecl,
 /// appropriate lookup tables. FIXME: Should reconsider if adding synthesized
 /// methods is the "right" thing to do.
 void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,
-                               ObjCContainerDecl *CD) {
+                               ObjCContainerDecl *CD,
+                               ObjCPropertyDecl *redeclaredProperty,
+                               ObjCContainerDecl *lexicalDC) {
+
   ObjCMethodDecl *GetterMethod, *SetterMethod;
 
   GetterMethod = CD->getInstanceMethod(property->getGetterName());
@@ -1123,19 +1126,22 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,
       // No instance method of same name as property setter name was found.
       // Declare a setter method and add it to the list of methods
       // for this class.
-      SetterMethod = ObjCMethodDecl::Create(Context, property->getLocation(),
-                               property->getLocation(),
-                               property->getSetterName(),
-                               Context.VoidTy, 0, CD, true, false, true,
-                               false,
+      SourceLocation Loc = redeclaredProperty ? 
+        redeclaredProperty->getLocation() :
+        property->getLocation();
+
+      SetterMethod =
+        ObjCMethodDecl::Create(Context, Loc, Loc,
+                               property->getSetterName(), Context.VoidTy, 0,
+                               CD, true, false, true, false,
                                (property->getPropertyImplementation() ==
                                 ObjCPropertyDecl::Optional) ?
-                               ObjCMethodDecl::Optional :
-                               ObjCMethodDecl::Required);
+                                ObjCMethodDecl::Optional :
+                                ObjCMethodDecl::Required);
+
       // Invent the arguments for the setter. We don't bother making a
       // nice name for the argument.
-      ParmVarDecl *Argument = ParmVarDecl::Create(Context, SetterMethod,
-                                                  property->getLocation(),
+      ParmVarDecl *Argument = ParmVarDecl::Create(Context, SetterMethod, Loc,
                                                   property->getIdentifier(),
                                                   property->getType(),
                                                   /*TInfo=*/0,
@@ -1146,7 +1152,7 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,
       CD->addDecl(SetterMethod);
       // FIXME: Eventually this shouldn't be needed, as the lexical context
       // and the real context should be the same.
-      if (DeclContext *lexicalDC = property->getLexicalDeclContext())
+      if (lexicalDC)
         SetterMethod->setLexicalDeclContext(lexicalDC);
     } else
       // A user declared setter will be synthesize when @synthesize of
index 8bca37e7c9de5ae3d2de08f87b0c52131cbc0cac..c7e53552d0123fc7880d15dd2d7c4fdbe0775872 100644 (file)
@@ -3,26 +3,49 @@
 // @interface (where we have a duplicate declaration - to be removed).
 @interface Foo {} @end
 @interface Foo (Cat)
-  @property int a;
+@property int a;
 @end
 @interface Foo ()
-  @property int b;
-  - (void) bar;
+@property int b;
+- (void) bar;
+@end
+
+// Test that 'setter' methods defined by @property in the class extension
+// but not the in @interface are only presented in the class extension.
+@interface Bar  
+@property (readonly) id bar;
+@end
+@interface Bar () 
+@property (readwrite) id bar;
 @end
 
 // RUN: c-index-test -test-load-source local %s | FileCheck %s
 // CHECK: properties-class-extensions.m:4:12: ObjCInterfaceDecl=Foo:4:12 Extent=[4:1 - 4:23]
+// CHECK: properties-class-extensions.m:9:15: ObjCInstanceMethodDecl=setB::9:15 Extent=[9:15 - 9:16]
+// CHECK: properties-class-extensions.m:9:15: ParmDecl=b:9:15 (Definition) Extent=[9:15 - 9:16]
 // CHECK: properties-class-extensions.m:5:12: ObjCCategoryDecl=Cat:5:12 Extent=[5:1 - 7:5]
 // CHECK: properties-class-extensions.m:5:12: ObjCClassRef=Foo:4:12 Extent=[5:12 - 5:15]
-// CHECK: properties-class-extensions.m:6:17: ObjCPropertyDecl=a:6:17 Extent=[6:17 - 6:18]
-// CHECK: properties-class-extensions.m:6:17: ObjCInstanceMethodDecl=a:6:17 Extent=[6:17 - 6:18]
-// CHECK: properties-class-extensions.m:6:17: ObjCInstanceMethodDecl=setA::6:17 Extent=[6:17 - 6:18]
-// CHECK: properties-class-extensions.m:6:17: ParmDecl=a:6:17 (Definition) Extent=[6:17 - 6:18]
+// CHECK: properties-class-extensions.m:6:15: ObjCPropertyDecl=a:6:15 Extent=[6:15 - 6:16]
+// CHECK: properties-class-extensions.m:6:15: ObjCInstanceMethodDecl=a:6:15 Extent=[6:15 - 6:16]
+// CHECK: properties-class-extensions.m:6:15: ObjCInstanceMethodDecl=setA::6:15 Extent=[6:15 - 6:16]
+// CHECK: properties-class-extensions.m:6:15: ParmDecl=a:6:15 (Definition) Extent=[6:15 - 6:16]
 // CHECK: properties-class-extensions.m:8:12: ObjCCategoryDecl=:8:12 Extent=[8:1 - 11:5]
 // CHECK: properties-class-extensions.m:8:12: ObjCClassRef=Foo:4:12 Extent=[8:12 - 8:15]
-// CHECK: properties-class-extensions.m:9:17: ObjCPropertyDecl=b:9:17 Extent=[9:17 - 9:18]
-// CHECK: properties-class-extensions.m:9:17: ObjCInstanceMethodDecl=b:9:17 Extent=[9:17 - 9:18]
-// CHECK: properties-class-extensions.m:9:17: ObjCInstanceMethodDecl=setB::9:17 Extent=[9:17 - 9:18]
-// CHECK: properties-class-extensions.m:9:17: ParmDecl=b:9:17 (Definition) Extent=[9:17 - 9:18]
-// CHECK: properties-class-extensions.m:10:3: ObjCInstanceMethodDecl=bar:10:3 Extent=[10:3 - 10:16]
+// CHECK: properties-class-extensions.m:9:15: ObjCPropertyDecl=b:9:15 Extent=[9:15 - 9:16]
+// CHECK: properties-class-extensions.m:9:15: ObjCInstanceMethodDecl=b:9:15 Extent=[9:15 - 9:16]
+// CHECK: properties-class-extensions.m:9:15: ObjCInstanceMethodDecl=setB::9:15 Extent=[9:15 - 9:16]
+// CHECK: properties-class-extensions.m:9:15: ParmDecl=b:9:15 (Definition) Extent=[9:15 - 9:16]
+// CHECK: properties-class-extensions.m:10:1: ObjCInstanceMethodDecl=bar:10:1 Extent=[10:1 - 10:14]
+// CHECK: properties-class-extensions.m:15:12: ObjCInterfaceDecl=Bar:15:12 Extent=[15:1 - 17:5]
+// CHECK: properties-class-extensions.m:16:25: ObjCPropertyDecl=bar:16:25 Extent=[16:25 - 16:28]
+// CHECK: properties-class-extensions.m:16:22: TypeRef=id:0:0 Extent=[16:22 - 16:24]
+// CHECK: properties-class-extensions.m:16:25: ObjCInstanceMethodDecl=bar:16:25 Extent=[16:25 - 16:28]
+// CHECK: properties-class-extensions.m:18:12: ObjCCategoryDecl=:18:12 Extent=[18:1 - 20:5]
+// CHECK: properties-class-extensions.m:18:12: ObjCClassRef=Bar:15:12 Extent=[18:12 - 18:15]
+// CHECK: properties-class-extensions.m:19:26: ObjCPropertyDecl=bar:19:26 Extent=[19:26 - 19:29]
+// CHECK: properties-class-extensions.m:19:23: TypeRef=id:0:0 Extent=[19:23 - 19:25]
+// CHECK: properties-class-extensions.m:16:25: ObjCInstanceMethodDecl=bar:16:25 Extent=[16:25 - 16:28]
+// CHECK: properties-class-extensions.m:19:26: ObjCInstanceMethodDecl=setBar::19:26 Extent=[19:26 - 19:29]
+// CHECK: properties-class-extensions.m:19:26: ParmDecl=bar:19:26 (Definition) Extent=[19:26 - 19:29]
+