[cfe-commits] r154436 - in /cfe/trunk: test/Index/overrides.m tools/libclang/CIndex.cpp tools/libclang/CXCursor.cpp

Argyrios Kyrtzidis akyrtzi at gmail.com
Tue Apr 10 14:01:03 PDT 2012


Author: akirtzidis
Date: Tue Apr 10 16:01:03 2012
New Revision: 154436

URL: http://llvm.org/viewvc/llvm-project?rev=154436&view=rev
Log:
[libclang] For clang_getOverriddenCursors make sure to report overridden objc methods
for methods in categories of super classes. rdar://11220358

Modified:
    cfe/trunk/test/Index/overrides.m
    cfe/trunk/tools/libclang/CIndex.cpp
    cfe/trunk/tools/libclang/CXCursor.cpp

Modified: cfe/trunk/test/Index/overrides.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/overrides.m?rev=154436&r1=154435&r2=154436&view=diff
==============================================================================
--- cfe/trunk/test/Index/overrides.m (original)
+++ cfe/trunk/test/Index/overrides.m Tue Apr 10 16:01:03 2012
@@ -36,6 +36,20 @@
 - (void)protoMethod;
 @end
 
+ at interface B2
+ at end
+
+ at interface B2(cat)
+-(void)meth;
+ at end
+
+ at interface I2 : B2
+ at end
+
+ at implementation I2
+-(void)meth { }
+ at end
+
 // RUN: c-index-test -test-load-source local %s | FileCheck %s
 // CHECK: overrides.m:12:9: ObjCInstanceMethodDecl=protoMethod:12:9 [Overrides @3:9]
 // CHECK: overrides.m:22:9: ObjCInstanceMethodDecl=method:22:9 [Overrides @16:9]
@@ -44,3 +58,4 @@
 // CHECK: overrides.m:28:9: ObjCClassMethodDecl=methodWithParam::28:9 (Definition) [Overrides @18:9]
 // CHECK: overrides.m:32:9: ObjCInstanceMethodDecl=protoMethod:32:9 [Overrides @8:9]
 // CHECK: overrides.m:36:9: ObjCInstanceMethodDecl=protoMethod:36:9 [Overrides @12:9, @8:9, @32:9, @17:9]
+// CHECK: overrides.m:50:8: ObjCInstanceMethodDecl=meth:50:8 (Definition) [Overrides @43:8]

Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=154436&r1=154435&r2=154436&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Tue Apr 10 16:01:03 2012
@@ -5535,6 +5535,8 @@
     *num_overridden = 0;
   if (!overridden || !num_overridden)
     return;
+  if (!clang_isDeclaration(cursor.kind))
+    return;
 
   SmallVector<CXCursor, 8> Overridden;
   cxcursor::getOverriddenCursors(cursor, Overridden);

Modified: cfe/trunk/tools/libclang/CXCursor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXCursor.cpp?rev=154436&r1=154435&r2=154436&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CXCursor.cpp (original)
+++ cfe/trunk/tools/libclang/CXCursor.cpp Tue Apr 10 16:01:03 2012
@@ -786,14 +786,11 @@
   return static_cast<CXTranslationUnit>(Cursor.data[2]);
 }
 
-static void CollectOverriddenMethods(CXTranslationUnit TU,
-                                     DeclContext *Ctx, 
+static void CollectOverriddenMethodsRecurse(CXTranslationUnit TU,
+                                     ObjCContainerDecl *Container, 
                                      ObjCMethodDecl *Method,
-                                     SmallVectorImpl<CXCursor> &Methods) {
-  if (!Ctx)
-    return;
-
-  ObjCContainerDecl *Container = dyn_cast<ObjCContainerDecl>(Ctx);
+                                     SmallVectorImpl<CXCursor> &Methods,
+                                     bool MovedToSuper) {
   if (!Container)
     return;
 
@@ -801,10 +798,23 @@
   // category is not "overriden" since it is considered as the "same" method
   // (same USR) as the one from the interface.
   if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
+    // Check whether we have a matching method at this category but only if we
+    // are at the super class level.
+    if (MovedToSuper)
+      if (ObjCMethodDecl *
+            Overridden = Container->getMethod(Method->getSelector(),
+                                              Method->isInstanceMethod()))
+        if (Method != Overridden) {
+          // We found an override at this category; there is no need to look
+          // into its protocols.
+          Methods.push_back(MakeCXCursor(Overridden, TU));
+          return;
+        }
+
     for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
                                           PEnd = Category->protocol_end();
          P != PEnd; ++P)
-      CollectOverriddenMethods(TU, *P, Method, Methods);
+      CollectOverriddenMethodsRecurse(TU, *P, Method, Methods, MovedToSuper);
     return;
   }
 
@@ -822,29 +832,37 @@
     for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
                                           PEnd = Protocol->protocol_end();
          P != PEnd; ++P)
-      CollectOverriddenMethods(TU, *P, Method, Methods);
+      CollectOverriddenMethodsRecurse(TU, *P, Method, Methods, MovedToSuper);
   }
 
   if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
     for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(),
                                            PEnd = Interface->protocol_end();
          P != PEnd; ++P)
-      CollectOverriddenMethods(TU, *P, Method, Methods);
+      CollectOverriddenMethodsRecurse(TU, *P, Method, Methods, MovedToSuper);
 
     for (ObjCCategoryDecl *Category = Interface->getCategoryList();
          Category; Category = Category->getNextClassCategory())
-      CollectOverriddenMethods(TU, Category, Method, Methods);
+      CollectOverriddenMethodsRecurse(TU, Category, Method, Methods,
+                                      MovedToSuper);
 
     if (ObjCInterfaceDecl *Super = Interface->getSuperClass())
-      return CollectOverriddenMethods(TU, Super, Method, Methods);
+      return CollectOverriddenMethodsRecurse(TU, Super, Method, Methods,
+                                             /*MovedToSuper=*/true);
   }
 }
 
+static inline void CollectOverriddenMethods(CXTranslationUnit TU,
+                                           ObjCContainerDecl *Container, 
+                                           ObjCMethodDecl *Method,
+                                           SmallVectorImpl<CXCursor> &Methods) {
+  CollectOverriddenMethodsRecurse(TU, Container, Method, Methods,
+                                  /*MovedToSuper=*/false);
+}
+
 void cxcursor::getOverriddenCursors(CXCursor cursor,
                                     SmallVectorImpl<CXCursor> &overridden) { 
-  if (!clang_isDeclaration(cursor.kind))
-    return;
-
+  assert(clang_isDeclaration(cursor.kind));
   Decl *D = getCursorDecl(cursor);
   if (!D)
     return;
@@ -893,7 +911,9 @@
     CollectOverriddenMethods(TU, ID, Method, overridden);
 
   } else {
-    CollectOverriddenMethods(TU, Method->getDeclContext(), Method, overridden);
+    CollectOverriddenMethods(TU,
+                  dyn_cast_or_null<ObjCContainerDecl>(Method->getDeclContext()),
+                  Method, overridden);
   }
 }
 





More information about the cfe-commits mailing list