[cfe-commits] r152270 - in /cfe/trunk: include/clang-c/Index.h test/Index/annotate-tokens.m test/Index/file-refs.m test/Index/local-symbols.m test/Index/overrides.m test/Index/usrs.m tools/libclang/CXCursor.cpp

Argyrios Kyrtzidis akyrtzi at gmail.com
Wed Mar 7 16:20:03 PST 2012


Author: akirtzidis
Date: Wed Mar  7 18:20:03 2012
New Revision: 152270

URL: http://llvm.org/viewvc/llvm-project?rev=152270&view=rev
Log:
[libclang] Enhance clang_getOverriddenCursors.

Basically the current design is:
-for an implementation method, show as overridden the interface method.
  This is not useful, and is inconsistent with the C++ side
-for an interface method, show as overridden the protocols methods (this is desirable)
  and the methods from the categories; methods from categories are not useful
  since they are considered the same method (same USR).
-If there is a protocol method or category method reported, it does not check the
  super class for overridden methods. This is really problematic since
  overridden methods from super class is what we want to give back.

Change clang_getOverriddenCursors to show as overridden any method in the class's
base class, its protocols, or its categories' protocols, that has the same
selector and is of the same kind (class or instance).
If no such method exists, the search continues to the class's superclass,
its protocols, and its categories, and so on. A method from an Objective-C
implementation is considered to override the same methods as its
corresponding method in the interface.

rdar://10967206

Modified:
    cfe/trunk/include/clang-c/Index.h
    cfe/trunk/test/Index/annotate-tokens.m
    cfe/trunk/test/Index/file-refs.m
    cfe/trunk/test/Index/local-symbols.m
    cfe/trunk/test/Index/overrides.m
    cfe/trunk/test/Index/usrs.m
    cfe/trunk/tools/libclang/CXCursor.cpp

Modified: cfe/trunk/include/clang-c/Index.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=152270&r1=152269&r2=152270&view=diff
==============================================================================
--- cfe/trunk/include/clang-c/Index.h (original)
+++ cfe/trunk/include/clang-c/Index.h Wed Mar  7 18:20:03 2012
@@ -2219,11 +2219,12 @@
  * In both Objective-C and C++, a method (aka virtual member function,
  * in C++) can override a virtual method in a base class. For
  * Objective-C, a method is said to override any method in the class's
- * interface (if we're coming from an implementation), its protocols,
- * or its categories, that has the same selector and is of the same
- * kind (class or instance). If no such method exists, the search
- * continues to the class's superclass, its protocols, and its
- * categories, and so on.
+ * base class, its protocols, or its categories' protocols, that has the same
+ * selector and is of the same kind (class or instance).
+ * If no such method exists, the search continues to the class's superclass,
+ * its protocols, and its categories, and so on. A method from an Objective-C
+ * implementation is considered to override the same methods as its
+ * corresponding method in the interface.
  *
  * For C++, a virtual member function overrides any virtual member
  * function with the same signature that occurs in its base

Modified: cfe/trunk/test/Index/annotate-tokens.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/annotate-tokens.m?rev=152270&r1=152269&r2=152270&view=diff
==============================================================================
--- cfe/trunk/test/Index/annotate-tokens.m (original)
+++ cfe/trunk/test/Index/annotate-tokens.m Wed Mar  7 18:20:03 2012
@@ -271,7 +271,7 @@
 // CHECK: Punctuation: ")" [38:12 - 38:13] ObjCInstanceMethodDecl=actionMethod::38:1 (Definition)
 // CHECK: Identifier: "actionMethod" [38:14 - 38:26] ObjCInstanceMethodDecl=actionMethod::38:1 (Definition)
 // CHECK: Punctuation: ":" [38:26 - 38:27] ObjCInstanceMethodDecl=actionMethod::38:1 (Definition)
-// CHECK: Keyword: "in" [38:28 - 38:30] ObjCInstanceMethodDecl=actionMethod::38:1 (Definition) [Overrides @33:1]
+// CHECK: Keyword: "in" [38:28 - 38:30] ObjCInstanceMethodDecl=actionMethod::38:1 (Definition)
 // CHECK: Identifier: "id" [38:31 - 38:33] TypeRef=id:0:0
 // CHECK: Punctuation: ")" [38:33 - 38:34] ParmDecl=arg:38:34 (Definition)
 // CHECK: Identifier: "arg" [38:34 - 38:37] ParmDecl=arg:38:34 (Definition)

Modified: cfe/trunk/test/Index/file-refs.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/file-refs.m?rev=152270&r1=152269&r2=152270&view=diff
==============================================================================
--- cfe/trunk/test/Index/file-refs.m (original)
+++ cfe/trunk/test/Index/file-refs.m Wed Mar  7 18:20:03 2012
@@ -55,14 +55,14 @@
 // RUN:  -file-refs-at=%s:4:10 \
 // CHECK-NEXT: ObjCInstanceMethodDecl=setWithInt:andFloat::4:1
 // CHECK-NEXT: ObjCInstanceMethodDecl=setWithInt:andFloat::4:1 =[4:6 - 4:16]
-// CHECK-NEXT: ObjCInstanceMethodDecl=setWithInt:andFloat::8:1 (Definition) [Overrides @4:1] =[8:6 - 8:16]
+// CHECK-NEXT: ObjCInstanceMethodDecl=setWithInt:andFloat::8:1 (Definition) =[8:6 - 8:16]
 // CHECK-NEXT: ObjCMessageExpr=setWithInt:andFloat::4:1 =[14:8 - 14:18]
 // CHECK-NEXT: ObjCMessageExpr=setWithInt:andFloat::4:1 =[15:8 - 15:18]
 
 // RUN:  -file-refs-at=%s:15:27 \
 // CHECK-NEXT: ObjCMessageExpr=setWithInt:andFloat::4:1
 // CHECK-NEXT: ObjCInstanceMethodDecl=setWithInt:andFloat::4:1 =[4:24 - 4:32]
-// CHECK-NEXT: ObjCInstanceMethodDecl=setWithInt:andFloat::8:1 (Definition) [Overrides @4:1] =[8:24 - 8:32]
+// CHECK-NEXT: ObjCInstanceMethodDecl=setWithInt:andFloat::8:1 (Definition) =[8:24 - 8:32]
 // CHECK-NEXT: ObjCMessageExpr=setWithInt:andFloat::4:1 =[14:21 - 14:29]
 // CHECK-NEXT: ObjCMessageExpr=setWithInt:andFloat::4:1 =[15:22 - 15:30]
 
@@ -76,15 +76,15 @@
 // CHECK-NEXT: ObjCMessageExpr=protMeth:19:1
 // CHECK-NEXT: ObjCInstanceMethodDecl=protMeth:19:1 =[19:8 - 19:16]
 // CHECK-NEXT: ObjCInstanceMethodDecl=protMeth:29:1 [Overrides @19:1] =[29:8 - 29:16]
-// CHECK-NEXT: ObjCInstanceMethodDecl=protMeth:33:1 (Definition) [Overrides @29:1] =[33:8 - 33:16]
+// CHECK-NEXT: ObjCInstanceMethodDecl=protMeth:33:1 (Definition) [Overrides @19:1] =[33:8 - 33:16]
 // CHECK-NEXT: ObjCMessageExpr=protMeth:29:1 =[37:6 - 37:14]
 // CHECK-NEXT: ObjCMessageExpr=protMeth:19:1 =[38:6 - 38:14]
 
 // RUN:  -file-refs-at=%s:33:12 \
-// CHECK-NEXT: ObjCInstanceMethodDecl=protMeth:33:1 (Definition) [Overrides @29:1]
+// CHECK-NEXT: ObjCInstanceMethodDecl=protMeth:33:1 (Definition) [Overrides @19:1]
 // CHECK-NEXT: ObjCInstanceMethodDecl=protMeth:19:1 =[19:8 - 19:16]
 // CHECK-NEXT: ObjCInstanceMethodDecl=protMeth:29:1 [Overrides @19:1] =[29:8 - 29:16]
-// CHECK-NEXT: ObjCInstanceMethodDecl=protMeth:33:1 (Definition) [Overrides @29:1] =[33:8 - 33:16]
+// CHECK-NEXT: ObjCInstanceMethodDecl=protMeth:33:1 (Definition) [Overrides @19:1] =[33:8 - 33:16]
 // CHECK-NEXT: ObjCMessageExpr=protMeth:29:1 =[37:6 - 37:14]
 // CHECK-NEXT: ObjCMessageExpr=protMeth:19:1 =[38:6 - 38:14]
 

Modified: cfe/trunk/test/Index/local-symbols.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/local-symbols.m?rev=152270&r1=152269&r2=152270&view=diff
==============================================================================
--- cfe/trunk/test/Index/local-symbols.m (original)
+++ cfe/trunk/test/Index/local-symbols.m Wed Mar  7 18:20:03 2012
@@ -32,7 +32,7 @@
 // CHECK: local-symbols.m:9:1: ObjCInstanceMethodDecl=bar:9:1 Extent=[9:1 - 9:12]
 // CHECK: local-symbols.m:9:4: TypeRef=id:0:0 Extent=[9:4 - 9:6]
 // CHECK: local-symbols.m:12:17: ObjCImplementationDecl=Foo:12:17 (Definition) Extent=[12:1 - 16:2]
-// CHECK: local-symbols.m:13:1: ObjCInstanceMethodDecl=bar:13:1 (Definition) [Overrides @9:1] Extent=[13:1 - 15:2]
+// CHECK: local-symbols.m:13:1: ObjCInstanceMethodDecl=bar:13:1 (Definition) Extent=[13:1 - 15:2]
 // CHECK: local-symbols.m:13:4: TypeRef=id:0:0 Extent=[13:4 - 13:6]
 // CHECK: local-symbols.m:14:10: UnexposedExpr= Extent=[14:10 - 14:11]
 // CHECK: local-symbols.m:14:10: IntegerLiteral= Extent=[14:10 - 14:11]

Modified: cfe/trunk/test/Index/overrides.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/overrides.m?rev=152270&r1=152269&r2=152270&view=diff
==============================================================================
--- cfe/trunk/test/Index/overrides.m (original)
+++ cfe/trunk/test/Index/overrides.m Wed Mar  7 18:20:03 2012
@@ -14,6 +14,7 @@
 
 @interface A
 - (void)method;
+- (void)protoMethod;
 + (void)methodWithParam:(int)param;
 @end
 
@@ -27,9 +28,19 @@
 + (void)methodWithParam:(int)param { }
 @end
 
+ at protocol P4 <P3>
+- (void)protoMethod;
+ at end
+
+ at interface B(cat) <P4>
+- (void)protoMethod;
+ at end
+
 // RUN: c-index-test -test-load-source local %s | FileCheck %s
-// CHECK: overrides.m:12:1: ObjCInstanceMethodDecl=protoMethod:12:1 [Overrides @3:1] Extent=[12:1 - 12:21]
-// CHECK: overrides.m:21:1: ObjCInstanceMethodDecl=method:21:1 [Overrides @16:1] Extent=[21:1 - 21:16]
-// CHECK: overrides.m:22:1: ObjCInstanceMethodDecl=protoMethod:22:1 [Overrides @12:1, @8:1] Extent=[22:1 - 22:21]
-// CHECK: overrides.m:26:1: ObjCInstanceMethodDecl=method:26:1 (Definition) [Overrides @21:1] Extent=[26:1 - 26:19]
-// CHECK: overrides.m:27:1: ObjCClassMethodDecl=methodWithParam::27:1 (Definition) [Overrides @17:1] Extent=[27:1 - 27:39]
+// CHECK: overrides.m:12:1: ObjCInstanceMethodDecl=protoMethod:12:1 [Overrides @3:1]
+// CHECK: overrides.m:22:1: ObjCInstanceMethodDecl=method:22:1 [Overrides @16:1]
+// CHECK: overrides.m:23:1: ObjCInstanceMethodDecl=protoMethod:23:1 [Overrides @12:1, @8:1, @32:1, @17:1]
+// CHECK: overrides.m:27:1: ObjCInstanceMethodDecl=method:27:1 (Definition) [Overrides @16:1]
+// CHECK: overrides.m:28:1: ObjCClassMethodDecl=methodWithParam::28:1 (Definition) [Overrides @18:1]
+// CHECK: overrides.m:32:1: ObjCInstanceMethodDecl=protoMethod:32:1 [Overrides @8:1]
+// CHECK: overrides.m:36:1: ObjCInstanceMethodDecl=protoMethod:36:1 [Overrides @12:1, @8:1, @32:1, @17:1]

Modified: cfe/trunk/test/Index/usrs.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/usrs.m?rev=152270&r1=152269&r2=152270&view=diff
==============================================================================
--- cfe/trunk/test/Index/usrs.m (original)
+++ cfe/trunk/test/Index/usrs.m Wed Mar  7 18:20:03 2012
@@ -189,7 +189,7 @@
 // CHECK-source: usrs.m:31:15: ObjCInstanceMethodDecl=setD1::31:15 Extent=[31:15 - 31:17]
 // CHECK-source: usrs.m:31:15: ParmDecl=d1:31:15 (Definition) Extent=[31:15 - 31:17]
 // CHECK-source: usrs.m:34:17: ObjCImplementationDecl=Foo:34:17 (Definition) Extent=[34:1 - 45:2]
-// CHECK-source: usrs.m:35:1: ObjCInstanceMethodDecl=godzilla:35:1 (Definition) [Overrides @29:1] Extent=[35:1 - 39:2]
+// CHECK-source: usrs.m:35:1: ObjCInstanceMethodDecl=godzilla:35:1 (Definition) Extent=[35:1 - 39:2]
 // CHECK-source: usrs.m:35:4: TypeRef=id:0:0 Extent=[35:4 - 35:6]
 // CHECK-source: usrs.m:35:17: CompoundStmt= Extent=[35:17 - 39:2]
 // CHECK-source: usrs.m:36:3: DeclStmt= Extent=[36:3 - 36:20]
@@ -200,7 +200,7 @@
 // CHECK-source: usrs.m:38:3: ReturnStmt= Extent=[38:3 - 38:11]
 // CHECK-source: usrs.m:38:10: UnexposedExpr= Extent=[38:10 - 38:11]
 // CHECK-source: usrs.m:38:10: IntegerLiteral= Extent=[38:10 - 38:11]
-// CHECK-source: usrs.m:40:1: ObjCClassMethodDecl=kingkong:40:1 (Definition) [Overrides @30:1] Extent=[40:1 - 43:2]
+// CHECK-source: usrs.m:40:1: ObjCClassMethodDecl=kingkong:40:1 (Definition) Extent=[40:1 - 43:2]
 // CHECK-source: usrs.m:40:4: TypeRef=id:0:0 Extent=[40:4 - 40:6]
 // CHECK-source: usrs.m:40:17: CompoundStmt= Extent=[40:17 - 43:2]
 // CHECK-source: usrs.m:41:3: DeclStmt= Extent=[41:3 - 41:17]
@@ -232,19 +232,19 @@
 // CHECK-source: usrs.m:61:1: ObjCInstanceMethodDecl=meth4:61:1 Extent=[61:1 - 61:14]
 // CHECK-source: usrs.m:61:4: TypeRef=id:0:0 Extent=[61:4 - 61:6]
 // CHECK-source: usrs.m:63:17: ObjCImplementationDecl=CWithExt:63:17 (Definition) Extent=[63:1 - 67:2]
-// CHECK-source: usrs.m:64:1: ObjCInstanceMethodDecl=meth1:64:1 (Definition) [Overrides @52:1] Extent=[64:1 - 64:27]
+// CHECK-source: usrs.m:64:1: ObjCInstanceMethodDecl=meth1:64:1 (Definition) Extent=[64:1 - 64:27]
 // CHECK-source: usrs.m:64:4: TypeRef=id:0:0 Extent=[64:4 - 64:6]
 // CHECK-source: usrs.m:64:14: CompoundStmt= Extent=[64:14 - 64:27]
 // CHECK-source: usrs.m:64:16: ReturnStmt= Extent=[64:16 - 64:24]
 // CHECK-source: usrs.m:64:23: UnexposedExpr= Extent=[64:23 - 64:24]
 // CHECK-source: usrs.m:64:23: IntegerLiteral= Extent=[64:23 - 64:24]
-// CHECK-source: usrs.m:65:1: ObjCInstanceMethodDecl=meth2:65:1 (Definition) [Overrides @55:1] Extent=[65:1 - 65:27]
+// CHECK-source: usrs.m:65:1: ObjCInstanceMethodDecl=meth2:65:1 (Definition) Extent=[65:1 - 65:27]
 // CHECK-source: usrs.m:65:4: TypeRef=id:0:0 Extent=[65:4 - 65:6]
 // CHECK-source: usrs.m:65:14: CompoundStmt= Extent=[65:14 - 65:27]
 // CHECK-source: usrs.m:65:16: ReturnStmt= Extent=[65:16 - 65:24]
 // CHECK-source: usrs.m:65:23: UnexposedExpr= Extent=[65:23 - 65:24]
 // CHECK-source: usrs.m:65:23: IntegerLiteral= Extent=[65:23 - 65:24]
-// CHECK-source: usrs.m:66:1: ObjCInstanceMethodDecl=meth3:66:1 (Definition) [Overrides @58:1] Extent=[66:1 - 66:27]
+// CHECK-source: usrs.m:66:1: ObjCInstanceMethodDecl=meth3:66:1 (Definition) Extent=[66:1 - 66:27]
 // CHECK-source: usrs.m:66:4: TypeRef=id:0:0 Extent=[66:4 - 66:6]
 // CHECK-source: usrs.m:66:14: CompoundStmt= Extent=[66:14 - 66:27]
 // CHECK-source: usrs.m:66:16: ReturnStmt= Extent=[66:16 - 66:24]
@@ -252,7 +252,7 @@
 // CHECK-source: usrs.m:66:23: IntegerLiteral= Extent=[66:23 - 66:24]
 // CHECK-source: usrs.m:68:17: ObjCCategoryImplDecl=Bar:68:17 (Definition) Extent=[68:1 - 70:2]
 // CHECK-source: usrs.m:68:17: ObjCClassRef=CWithExt:51:12 Extent=[68:17 - 68:25]
-// CHECK-source: usrs.m:69:1: ObjCInstanceMethodDecl=meth4:69:1 (Definition) [Overrides @61:1] Extent=[69:1 - 69:27]
+// CHECK-source: usrs.m:69:1: ObjCInstanceMethodDecl=meth4:69:1 (Definition) Extent=[69:1 - 69:27]
 // CHECK-source: usrs.m:69:4: TypeRef=id:0:0 Extent=[69:4 - 69:6]
 // CHECK-source: usrs.m:69:14: CompoundStmt= Extent=[69:14 - 69:27]
 // CHECK-source: usrs.m:69:16: ReturnStmt= Extent=[69:16 - 69:24]

Modified: cfe/trunk/tools/libclang/CXCursor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXCursor.cpp?rev=152270&r1=152269&r2=152270&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CXCursor.cpp (original)
+++ cfe/trunk/tools/libclang/CXCursor.cpp Wed Mar  7 18:20:03 2012
@@ -794,16 +794,21 @@
   if (!Ctx)
     return;
 
-  // If we have a class or category implementation, jump straight to the 
-  // interface.
-  if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(Ctx))
-    return CollectOverriddenMethods(TU, Impl->getClassInterface(),
-                                    Method, Methods);
-  
   ObjCContainerDecl *Container = dyn_cast<ObjCContainerDecl>(Ctx);
   if (!Container)
     return;
 
+  // In categories look for overriden methods from protocols. A method from
+  // 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)) {
+    for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
+                                          PEnd = Category->protocol_end();
+         P != PEnd; ++P)
+      CollectOverriddenMethods(TU, *P, Method, Methods);
+    return;
+  }
+
   // Check whether we have a matching method at this level.
   if (ObjCMethodDecl *Overridden = Container->getMethod(Method->getSelector(),
                                                     Method->isInstanceMethod()))
@@ -821,13 +826,6 @@
       CollectOverriddenMethods(TU, *P, Method, Methods);
   }
 
-  if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
-    for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
-                                          PEnd = Category->protocol_end();
-         P != PEnd; ++P)
-      CollectOverriddenMethods(TU, *P, Method, Methods);
-  }
-
   if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
     for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(),
                                            PEnd = Interface->protocol_end();
@@ -838,10 +836,8 @@
          Category; Category = Category->getNextClassCategory())
       CollectOverriddenMethods(TU, Category, Method, Methods);
 
-    // We only look into the superclass if we haven't found anything yet.
-    if (Methods.empty())
-      if (ObjCInterfaceDecl *Super = Interface->getSuperClass())
-        return CollectOverriddenMethods(TU, Super, Method, Methods);
+    if (ObjCInterfaceDecl *Super = Interface->getSuperClass())
+      return CollectOverriddenMethods(TU, Super, Method, Methods);
   }
 }
 
@@ -869,8 +865,37 @@
   if (!Method)
     return;
 
-  // Handle Objective-C methods.
-  CollectOverriddenMethods(TU, Method->getDeclContext(), Method, overridden);
+  if (ObjCProtocolDecl *
+        ProtD = dyn_cast<ObjCProtocolDecl>(Method->getDeclContext())) {
+    CollectOverriddenMethods(TU, ProtD, Method, overridden);
+
+  } else if (ObjCImplDecl *
+               IMD = dyn_cast<ObjCImplDecl>(Method->getDeclContext())) {
+    ObjCInterfaceDecl *ID = IMD->getClassInterface();
+    if (!ID)
+      return;
+    // Start searching for overridden methods using the method from the
+    // interface as starting point.
+    if (ObjCMethodDecl *IFaceMeth = ID->getMethod(Method->getSelector(),
+                                                  Method->isInstanceMethod()))
+      Method = IFaceMeth;
+    CollectOverriddenMethods(TU, ID, Method, overridden);
+
+  } else if (ObjCCategoryDecl *
+               CatD = dyn_cast<ObjCCategoryDecl>(Method->getDeclContext())) {
+    ObjCInterfaceDecl *ID = CatD->getClassInterface();
+    if (!ID)
+      return;
+    // Start searching for overridden methods using the method from the
+    // interface as starting point.
+    if (ObjCMethodDecl *IFaceMeth = ID->getMethod(Method->getSelector(),
+                                                  Method->isInstanceMethod()))
+      Method = IFaceMeth;
+    CollectOverriddenMethods(TU, ID, Method, overridden);
+
+  } else {
+    CollectOverriddenMethods(TU, Method->getDeclContext(), Method, overridden);
+  }
 }
 
 std::pair<int, SourceLocation>





More information about the cfe-commits mailing list