diff options
-rw-r--r-- | include/clang/Sema/Sema.h | 14 | ||||
-rw-r--r-- | lib/Sema/SemaObjCProperty.cpp | 30 | ||||
-rw-r--r-- | test/Index/properties-class-extensions.m | 47 |
3 files changed, 66 insertions, 25 deletions
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index af0174965f..a45437762c 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -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); diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp index 7181d58f7f..a6f251e107 100644 --- a/lib/Sema/SemaObjCProperty.cpp +++ b/lib/Sema/SemaObjCProperty.cpp @@ -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 diff --git a/test/Index/properties-class-extensions.m b/test/Index/properties-class-extensions.m index 8bca37e7c9..c7e53552d0 100644 --- a/test/Index/properties-class-extensions.m +++ b/test/Index/properties-class-extensions.m @@ -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] + |