aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/DeclObjC.h6
-rw-r--r--include/clang/Sema/Sema.h8
-rw-r--r--lib/AST/DeclObjC.cpp21
-rw-r--r--lib/Sema/SemaExprMember.cpp3
-rw-r--r--lib/Sema/SemaExprObjC.cpp72
-rw-r--r--lib/Sema/SemaStmt.cpp2
-rw-r--r--test/SemaObjC/getter-setter-defined-in-category-of-parent.m26
-rw-r--r--test/SemaObjC/property-impl-misuse.m4
8 files changed, 59 insertions, 83 deletions
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index 0b3e56e6e3..4229fd3c0d 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -939,9 +939,13 @@ public:
}
ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName);
- // Lookup a method in the classes implementation hierarchy.
+ /// \brief Lookup a method in the classes implementation hierarchy.
ObjCMethodDecl *lookupPrivateMethod(const Selector &Sel, bool Instance=true);
+ ObjCMethodDecl *lookupPrivateClassMethod(const Selector &Sel) {
+ return lookupPrivateMethod(Sel, false);
+ }
+
SourceLocation getEndOfDefinitionLoc() const {
if (!hasDefinition())
return getLocation();
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 9675e08e4a..bce285d897 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -6107,14 +6107,6 @@ public:
AttributeList *AttrList, tok::ObjCKeywordKind MethodImplKind,
bool isVariadic, bool MethodDefinition);
- // Helper method for ActOnClassMethod/ActOnInstanceMethod.
- // Will search "local" class/category implementations for a method decl.
- // Will also search in class's root looking for instance method.
- // Returns 0 if no method is found.
- ObjCMethodDecl *LookupPrivateClassMethod(Selector Sel,
- ObjCInterfaceDecl *CDecl);
- ObjCMethodDecl *LookupPrivateInstanceMethod(Selector Sel,
- ObjCInterfaceDecl *ClassDecl);
ObjCMethodDecl *LookupMethodInQualifiedType(Selector Sel,
const ObjCObjectPointerType *OPT,
bool IsInstance);
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index 39f09063e9..cbd15240b1 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -363,6 +363,9 @@ ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel,
return NULL;
}
+// Will search "local" class/category implementations for a method decl.
+// If failed, then we search in class's root for an instance method.
+// Returns 0 if no method is found.
ObjCMethodDecl *ObjCInterfaceDecl::lookupPrivateMethod(
const Selector &Sel,
bool Instance) {
@@ -377,7 +380,23 @@ ObjCMethodDecl *ObjCInterfaceDecl::lookupPrivateMethod(
if (ObjCImplementationDecl *ImpDecl = getImplementation())
Method = Instance ? ImpDecl->getInstanceMethod(Sel)
: ImpDecl->getClassMethod(Sel);
-
+
+ // Look through local category implementations associated with the class.
+ if (!Method)
+ Method = Instance ? getCategoryInstanceMethod(Sel)
+ : getCategoryClassMethod(Sel);
+
+ // Before we give up, check if the selector is an instance method.
+ // But only in the root. This matches gcc's behavior and what the
+ // runtime expects.
+ if (!Instance && !Method && !getSuperClass()) {
+ Method = lookupInstanceMethod(Sel);
+ // Look through local category implementations associated
+ // with the root class.
+ if (!Method)
+ Method = lookupPrivateMethod(Sel, true);
+ }
+
if (!Method && getSuperClass())
return getSuperClass()->lookupPrivateMethod(Sel, Instance);
return Method;
diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp
index d5e83ce8ae..79973b352f 100644
--- a/lib/Sema/SemaExprMember.cpp
+++ b/lib/Sema/SemaExprMember.cpp
@@ -1366,9 +1366,6 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr,
// methods.
Setter = IFace->lookupPrivateMethod(SetterSel, false);
}
- // Look through local category implementations associated with the class.
- if (!Setter)
- Setter = IFace->getCategoryClassMethod(SetterSel);
if (Setter && DiagnoseUseOfDecl(Setter, MemberLoc))
return ExprError();
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index 1cdacdec89..31dfae9055 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -1247,57 +1247,6 @@ bool Sema::isSelfExpr(Expr *receiver) {
return false;
}
-// Helper method for ActOnClassMethod/ActOnInstanceMethod.
-// Will search "local" class/category implementations for a method decl.
-// If failed, then we search in class's root for an instance method.
-// Returns 0 if no method is found.
-ObjCMethodDecl *Sema::LookupPrivateClassMethod(Selector Sel,
- ObjCInterfaceDecl *ClassDecl) {
- ObjCMethodDecl *Method = 0;
- // lookup in class and all superclasses
- while (ClassDecl && !Method) {
- if (ObjCImplementationDecl *ImpDecl = ClassDecl->getImplementation())
- Method = ImpDecl->getClassMethod(Sel);
-
- // Look through local category implementations associated with the class.
- if (!Method)
- Method = ClassDecl->getCategoryClassMethod(Sel);
-
- // Before we give up, check if the selector is an instance method.
- // But only in the root. This matches gcc's behaviour and what the
- // runtime expects.
- if (!Method && !ClassDecl->getSuperClass()) {
- Method = ClassDecl->lookupInstanceMethod(Sel);
- // Look through local category implementations associated
- // with the root class.
- if (!Method)
- Method = LookupPrivateInstanceMethod(Sel, ClassDecl);
- }
-
- ClassDecl = ClassDecl->getSuperClass();
- }
- return Method;
-}
-
-ObjCMethodDecl *Sema::LookupPrivateInstanceMethod(Selector Sel,
- ObjCInterfaceDecl *ClassDecl) {
- if (!ClassDecl->hasDefinition())
- return 0;
-
- ObjCMethodDecl *Method = 0;
- while (ClassDecl && !Method) {
- // If we have implementations in scope, check "private" methods.
- if (ObjCImplementationDecl *ImpDecl = ClassDecl->getImplementation())
- Method = ImpDecl->getInstanceMethod(Sel);
-
- // Look through local category implementations associated with the class.
- if (!Method)
- Method = ClassDecl->getCategoryInstanceMethod(Sel);
- ClassDecl = ClassDecl->getSuperClass();
- }
- return Method;
-}
-
/// LookupMethodInType - Look up a method in an ObjCObjectType.
ObjCMethodDecl *Sema::LookupMethodInObjectType(Selector sel, QualType type,
bool isInstance) {
@@ -1309,13 +1258,8 @@ ObjCMethodDecl *Sema::LookupMethodInObjectType(Selector sel, QualType type,
// Okay, look for "private" methods declared in any
// @implementations we've seen.
- if (isInstance) {
- if (ObjCMethodDecl *method = LookupPrivateInstanceMethod(sel, iface))
- return method;
- } else {
- if (ObjCMethodDecl *method = LookupPrivateClassMethod(sel, iface))
- return method;
- }
+ if (ObjCMethodDecl *method = iface->lookupPrivateMethod(sel, isInstance))
+ return method;
}
// Check qualifiers.
@@ -1489,9 +1433,6 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
if (!Getter)
Getter = IFace->lookupPrivateMethod(Sel);
- // Look through local category implementations associated with the class.
- if (!Getter)
- Getter = IFace->getCategoryInstanceMethod(Sel);
if (Getter) {
// Check if we can reference this property.
if (DiagnoseUseOfDecl(Getter, MemberLoc))
@@ -1513,9 +1454,6 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
// methods.
Setter = IFace->lookupPrivateMethod(SetterSel);
}
- // Look through local category implementations associated with the class.
- if (!Setter)
- Setter = IFace->getCategoryInstanceMethod(SetterSel);
if (Setter && DiagnoseUseOfDecl(Setter, MemberLoc))
return ExprError();
@@ -2010,7 +1948,7 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo,
// If we have an implementation in scope, check "private" methods.
if (!Method)
- Method = LookupPrivateClassMethod(Sel, Class);
+ Method = Class->lookupPrivateClassMethod(Sel);
if (Method && DiagnoseUseOfDecl(Method, Loc))
return ExprError();
@@ -2207,7 +2145,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
Method = ClassDecl->lookupClassMethod(Sel);
if (!Method)
- Method = LookupPrivateClassMethod(Sel, ClassDecl);
+ Method = ClassDecl->lookupPrivateClassMethod(Sel);
}
if (Method && DiagnoseUseOfDecl(Method, Loc))
return ExprError();
@@ -2280,7 +2218,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
if (!Method) {
// If we have implementations in scope, check "private" methods.
- Method = LookupPrivateInstanceMethod(Sel, ClassDecl);
+ Method = ClassDecl->lookupPrivateMethod(Sel);
if (!Method && getLangOpts().ObjCAutoRefCount) {
Diag(Loc, diag::err_arc_may_not_respond)
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 9affe9823a..4612930d45 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -1481,7 +1481,7 @@ Sema::CheckObjCForCollectionOperand(SourceLocation forLoc, Expr *collection) {
// If there's an interface, look in both the public and private APIs.
if (iface) {
method = iface->lookupInstanceMethod(selector);
- if (!method) method = LookupPrivateInstanceMethod(selector, iface);
+ if (!method) method = iface->lookupPrivateMethod(selector);
}
// Also check protocol qualifiers.
diff --git a/test/SemaObjC/getter-setter-defined-in-category-of-parent.m b/test/SemaObjC/getter-setter-defined-in-category-of-parent.m
new file mode 100644
index 0000000000..71c3237425
--- /dev/null
+++ b/test/SemaObjC/getter-setter-defined-in-category-of-parent.m
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
+
+@interface MyParent {
+ int X;
+}
+@end
+@implementation MyParent
+@end
+
+@interface MyParent(AA) {
+}
+@end
+@implementation MyParent (AA)
+- (void) setX: (int)in {X = in - 2;}
+- (int) X {return X;}
+@end
+
+@interface MyClass : MyParent
+@end
+@implementation MyClass
+@end
+
+int foo(MyClass *o) {
+ o.X = 2;
+ return o.X;
+} \ No newline at end of file
diff --git a/test/SemaObjC/property-impl-misuse.m b/test/SemaObjC/property-impl-misuse.m
index a5e1dd6b90..939909e9b2 100644
--- a/test/SemaObjC/property-impl-misuse.m
+++ b/test/SemaObjC/property-impl-misuse.m
@@ -30,8 +30,8 @@
@synthesize gradientStyle = _gradientStyle;
- (void)setGradientStyle:(id)value { }
-+ (void)_componentCellWithRepresentedObject {
- self.gradientStyle; // expected-error {{property 'gradientStyle' not found on object of type 'Class'}}
++ (id)_componentCellWithRepresentedObject {
+ return self.gradientStyle;
}
@end