aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaObjCProperty.cpp
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-10-10 16:42:38 +0000
committerJordan Rose <jordan_rose@apple.com>2012-10-10 16:42:38 +0000
commit9a1f7d8c33304f973a59c68d80c2cce280afb1d4 (patch)
treef3a8fe87db2769838d084d9f3d3364214b0e097d /lib/Sema/SemaObjCProperty.cpp
parent1e4691b9d8e1bdcc8ef62b323969d702c51b3c08 (diff)
Change Sema::PropertyIfSetterOrGetter to make use of isPropertyAccessor.
Old algorithm: 1. See if the name looks like a getter or setter. 2. Use the name to look up a property in the current ObjCContainer and all its protocols. 3. If the current container is an interface, also look in all categories and superclasses (and superclass categories, and so on). New algorithm: 1. See if the method is marked as a property accessor. If so, look through all properties in the current container and find one that has a matching selector. 2. Find all overrides of the method using ObjCMethodDecl's getOverriddenMethods. This collects methods in superclasses and protocols (as well as superclass categories, which isn't really necessary), and checks if THEY are accessors. This part is not done recursively, since getOverriddenMethods is already recursive. This lets us handle getters and setters that do not match the property names. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@165627 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaObjCProperty.cpp')
-rw-r--r--lib/Sema/SemaObjCProperty.cpp69
1 files changed, 34 insertions, 35 deletions
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;
}