]> granicus.if.org Git - clang/commitdiff
Change ObjCIntefaceDecl::lookupMethod() to have optional 'followsSuper' argument.
authorTed Kremenek <kremenek@apple.com>
Sat, 23 Nov 2013 01:01:29 +0000 (01:01 +0000)
committerTed Kremenek <kremenek@apple.com>
Sat, 23 Nov 2013 01:01:29 +0000 (01:01 +0000)
This enables a micro-optimization in protocol conformance checking
to not examine the class hierarchy twice per method.

As part of this change, remove the default arguments from lookupInstanceMethod()
and lookupClassMethod().  It was becoming very redundant.  For clients
needing the default arguments, have them use the full API instead of
these convenience methods.

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

include/clang/AST/DeclObjC.h
lib/AST/DeclObjC.cpp
lib/Sema/SemaDeclObjC.cpp

index 2e760d658e4368f8214582449622c0e686b53b80..eebed07aa9ace4e75aa8dc674469a1c2a670cfe2 100644 (file)
@@ -1141,15 +1141,18 @@ public:
   // Lookup a method. First, we search locally. If a method isn't
   // found, we search referenced protocols and class categories.
   ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance,
-                               bool shallowCategoryLookup= false,
-                               const ObjCCategoryDecl *C= 0) const;
-  ObjCMethodDecl *lookupInstanceMethod(Selector Sel,
-                            bool shallowCategoryLookup = false) const {
-    return lookupMethod(Sel, true/*isInstance*/, shallowCategoryLookup);
+                               bool shallowCategoryLookup = false,
+                               bool followSuper = true,
+                               const ObjCCategoryDecl *C = 0) const;
+
+  /// Lookup an instance method for a given selector.
+  ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const {
+    return lookupMethod(Sel, true/*isInstance*/);
   }
-  ObjCMethodDecl *lookupClassMethod(Selector Sel,
-                     bool shallowCategoryLookup = false) const {
-    return lookupMethod(Sel, false/*isInstance*/, shallowCategoryLookup);
+
+  /// Lookup a class method for a given selector.
+  ObjCMethodDecl *lookupClassMethod(Selector Sel) const {
+    return lookupMethod(Sel, false/*isInstance*/);
   }
   ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName);
 
@@ -1167,7 +1170,9 @@ public:
   ObjCMethodDecl *lookupPropertyAccessor(const Selector Sel,
                                          const ObjCCategoryDecl *Cat) const {
     return lookupMethod(Sel, true/*isInstance*/,
-                        false/*shallowCategoryLookup*/, Cat);
+                        false/*shallowCategoryLookup*/,
+                        true /* followsSuper */,
+                        Cat);
   }
                           
   SourceLocation getEndOfDefinitionLoc() const { 
index 28a651429c9be2714c78916402ba7b9c58d903f1..ca87bb8197f59659766df9bca1ef65f99c1c2474 100644 (file)
@@ -457,9 +457,11 @@ ObjCInterfaceDecl::lookupNestedProtocol(IdentifierInfo *Name) {
 /// When argument category "C" is specified, any implicit method found
 /// in this category is ignored.
 ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel, 
-                                     bool isInstance,
-                                     bool shallowCategoryLookup,
-                                     const ObjCCategoryDecl *C) const {
+                                                bool isInstance,
+                                                bool shallowCategoryLookup,
+                                                bool followSuper,
+                                                const ObjCCategoryDecl *C) const
+{
   // FIXME: Should make sure no callers ever do this.
   if (!hasDefinition())
     return 0;
@@ -470,7 +472,7 @@ ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel,
   if (data().ExternallyCompleted)
     LoadExternalDefinition();
 
-  while (ClassDecl != NULL) {
+  while (ClassDecl) {
     if ((MethodDecl = ClassDecl->getMethod(Sel, isInstance)))
       return MethodDecl;
 
@@ -501,7 +503,11 @@ ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel,
               return MethodDecl;
       }
     }
-  
+
+    if (!followSuper)
+      return NULL;
+
+    // Get the super class (if any).
     ClassDecl = ClassDecl->getSuperClass();
   }
   return NULL;
index 085569611098db272f344599e8e1b09ae7049d4e..95e3b4f4669fc99ca3768910c8283c1d096378d1 100644 (file)
@@ -1664,7 +1664,10 @@ void Sema::CheckProtocolMethodDefs(SourceLocation ImpLoc,
       if (method->getImplementationControl() != ObjCMethodDecl::Optional &&
           !method->isPropertyAccessor() &&
           !InsMap.count(method->getSelector()) &&
-          (!Super || !Super->lookupInstanceMethod(method->getSelector()))) {
+          (!Super || !Super->lookupMethod(method->getSelector(),
+                                          true /* instance */,
+                                          false /* shallowCategory */,
+                                          true /* followsSuper */))) {
             // If a method is not implemented in the category implementation but
             // has been declared in its primary class, superclass,
             // or in one of their protocols, no need to issue the warning. 
@@ -1675,8 +1678,10 @@ void Sema::CheckProtocolMethodDefs(SourceLocation ImpLoc,
             // have been synthesized due to a property declared in the class which
             // uses the protocol.
             if (ObjCMethodDecl *MethodInClass =
-                  IDecl->lookupInstanceMethod(method->getSelector(), 
-                                              true /*shallowCategoryLookup*/))
+                  IDecl->lookupMethod(method->getSelector(),
+                                      true /* instance */,
+                                      true /* shallowCategoryLookup */,
+                                      false /* followSuper */))
               if (C || MethodInClass->isPropertyAccessor())
                 continue;
             unsigned DIAG = diag::warn_unimplemented_protocol_method;
@@ -1695,11 +1700,17 @@ void Sema::CheckProtocolMethodDefs(SourceLocation ImpLoc,
     ObjCMethodDecl *method = *I;
     if (method->getImplementationControl() != ObjCMethodDecl::Optional &&
         !ClsMap.count(method->getSelector()) &&
-        (!Super || !Super->lookupClassMethod(method->getSelector()))) {
+        (!Super || !Super->lookupMethod(method->getSelector(),
+                                        false /* class method */,
+                                        false /* shallowCategoryLookup */,
+                                        true  /* followSuper */))) {
       // See above comment for instance method lookups.
-      if (C && IDecl->lookupClassMethod(method->getSelector(), 
-                                        true /*shallowCategoryLookup*/))
+      if (C && IDecl->lookupMethod(method->getSelector(),
+                                   false /* class */,
+                                   true /* shallowCategoryLookup */,
+                                   false /* followSuper */))
         continue;
+
       unsigned DIAG = diag::warn_unimplemented_protocol_method;
       if (Diags.getDiagnosticLevel(DIAG, ImpLoc) !=
             DiagnosticsEngine::Ignored) {