diff options
-rw-r--r-- | include/clang/Sema/Sema.h | 3 | ||||
-rw-r--r-- | lib/Sema/SemaObjCProperty.cpp | 69 | ||||
-rw-r--r-- | test/SemaObjC/property-deprecated-warning.m | 14 |
3 files changed, 50 insertions, 36 deletions
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 2a6d4bbe88..6823e45ecb 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -2317,7 +2317,8 @@ public: /// PropertyIfSetterOrGetter - Looks up the property if named declaration /// is a setter or getter method backing a property. - ObjCPropertyDecl *PropertyIfSetterOrGetter(NamedDecl *D); + ObjCPropertyDecl *PropertyIfSetterOrGetter(const NamedDecl *D, + bool CheckOverrides = true); /// Called by ActOnProperty to handle \@property declarations in /// class extensions. diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp index 8364c07b99..64dfa5677a 100644 --- a/lib/Sema/SemaObjCProperty.cpp +++ b/lib/Sema/SemaObjCProperty.cpp @@ -1576,44 +1576,43 @@ ObjCPropertyDecl *Sema::LookupPropertyDecl(const ObjCContainerDecl *CDecl, /// PropertyIfSetterOrGetter - Looks up the property if named declaration /// is a setter or getter method backing a property. -ObjCPropertyDecl *Sema::PropertyIfSetterOrGetter(NamedDecl *D) { - if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D)) { +ObjCPropertyDecl *Sema::PropertyIfSetterOrGetter(const NamedDecl *D, + bool CheckOverrides) { + const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D); + if (!Method) + return 0; + + if (Method->isPropertyAccessor()) { + const ObjCContainerDecl *Container = + cast<ObjCContainerDecl>(Method->getParent()); + Selector Sel = Method->getSelector(); - IdentifierInfo *Id = 0; - if (Sel.getNumArgs() == 0) - Id = Sel.getIdentifierInfoForSlot(0); - else if (Sel.getNumArgs() == 1) { - StringRef str = Sel.getNameForSlot(0); - if (str.startswith("set")) { - str = str.substr(3); - char front = str.front(); - front = islower(front) ? toupper(front) : tolower(front); - SmallString<100> PropertyName = str; - PropertyName[0] = front; - Id = &PP.getIdentifierTable().get(PropertyName); - } - } - if (Id) { - if (isa<ObjCInterfaceDecl>(Method->getDeclContext())) { - const ObjCInterfaceDecl *IDecl = Method->getClassInterface(); - while (IDecl) { - ObjCPropertyDecl *PDecl = - LookupPropertyDecl(cast<ObjCContainerDecl>(IDecl), Id); - if (PDecl) - return PDecl; - for (ObjCCategoryDecl *Category = IDecl->getCategoryList(); - Category; Category = Category->getNextClassCategory()) - if ((PDecl = - LookupPropertyDecl(cast<ObjCContainerDecl>(Category), Id))) - return PDecl; - IDecl = IDecl->getSuperClass(); - } - } else if (ObjCPropertyDecl *PDecl = - LookupPropertyDecl( - cast<ObjCContainerDecl>(Method->getDeclContext()), Id)) - return PDecl; + bool IsGetter = (Sel.isUnarySelector()); + + for (ObjCContainerDecl::prop_iterator I = Container->prop_begin(), + E = Container->prop_end(); + I != E; ++I) { + Selector NextSel = IsGetter ? (*I)->getGetterName() + : (*I)->getSetterName(); + if (NextSel == Sel) + return *I; } + + return 0; } + + if (!CheckOverrides) + return 0; + + typedef SmallVector<const ObjCMethodDecl *, 8> OverridesTy; + OverridesTy Overrides; + Method->getOverriddenMethods(Overrides); + for (OverridesTy::const_iterator I = Overrides.begin(), E = Overrides.end(); + I != E; ++I) { + if (ObjCPropertyDecl *Prop = PropertyIfSetterOrGetter(*I, false)) + return Prop; + } + return 0; } diff --git a/test/SemaObjC/property-deprecated-warning.m b/test/SemaObjC/property-deprecated-warning.m index b3c662074f..3e6ffe0672 100644 --- a/test/SemaObjC/property-deprecated-warning.m +++ b/test/SemaObjC/property-deprecated-warning.m @@ -2,6 +2,8 @@ // RUN: %clang_cc1 -x objective-c++ -fsyntax-only -triple thumbv6-apple-ios3.0 -verify -Wno-objc-root-class %s // rdar://12324295 +typedef signed char BOOL; + @protocol P @property(nonatomic,assign) id ptarget __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{property 'ptarget' is declared deprecated here}} @end @@ -36,3 +38,15 @@ [self setPtarget: (id)0]; // expected-warning {{setPtarget:' is deprecated: first deprecated in iOS 3.0}} } @end + + +@interface CustomAccessorNames +@property(getter=isEnabled,assign) BOOL enabled __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{method 'isEnabled' declared here}} expected-note {{property 'enabled' is declared deprecated here}} + +@property(setter=setNewDelegate:,assign) id delegate __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{method 'setNewDelegate:' declared here}} expected-note {{property 'delegate' is declared deprecated here}} +@end + +void testCustomAccessorNames(CustomAccessorNames *obj) { + if ([obj isEnabled]) // expected-warning {{'isEnabled' is deprecated: first deprecated in iOS 3.0}} + [obj setNewDelegate:0]; // expected-warning {{'setNewDelegate:' is deprecated: first deprecated in iOS 3.0}} +} |