diff options
-rw-r--r-- | include/clang-c/Index.h | 11 | ||||
-rw-r--r-- | test/Index/annotate-tokens.m | 2 | ||||
-rw-r--r-- | test/Index/file-refs.m | 10 | ||||
-rw-r--r-- | test/Index/local-symbols.m | 2 | ||||
-rw-r--r-- | test/Index/overrides.m | 21 | ||||
-rw-r--r-- | test/Index/usrs.m | 12 | ||||
-rw-r--r-- | tools/libclang/CXCursor.cpp | 63 |
7 files changed, 79 insertions, 42 deletions
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index fd7a9f3a01..d05510e281 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -2219,11 +2219,12 @@ CINDEX_LINKAGE CXCursor clang_getCursorLexicalParent(CXCursor cursor); * 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 diff --git a/test/Index/annotate-tokens.m b/test/Index/annotate-tokens.m index f9ddc655c2..424dec8e00 100644 --- a/test/Index/annotate-tokens.m +++ b/test/Index/annotate-tokens.m @@ -271,7 +271,7 @@ static Rdar8595462_A * Rdar8595462_staticVar; // 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) diff --git a/test/Index/file-refs.m b/test/Index/file-refs.m index 583826700d..684d87884e 100644 --- a/test/Index/file-refs.m +++ b/test/Index/file-refs.m @@ -55,14 +55,14 @@ void test2(Sub *s, id<Prot1> p) { // 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 @@ void test2(Sub *s, id<Prot1> p) { // 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] diff --git a/test/Index/local-symbols.m b/test/Index/local-symbols.m index 01c8305c2a..0e70b7c89b 100644 --- a/test/Index/local-symbols.m +++ b/test/Index/local-symbols.m @@ -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] diff --git a/test/Index/overrides.m b/test/Index/overrides.m index 2197aaaa36..e43d498c9a 100644 --- a/test/Index/overrides.m +++ b/test/Index/overrides.m @@ -14,6 +14,7 @@ @interface A - (void)method; +- (void)protoMethod; + (void)methodWithParam:(int)param; @end @@ -27,9 +28,19 @@ + (void)methodWithParam:(int)param { } @end +@protocol P4 <P3> +- (void)protoMethod; +@end + +@interface B(cat) <P4> +- (void)protoMethod; +@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] diff --git a/test/Index/usrs.m b/test/Index/usrs.m index ecf0d2302b..cfc055626a 100644 --- a/test/Index/usrs.m +++ b/test/Index/usrs.m @@ -189,7 +189,7 @@ int test_multi_declaration(void) { // 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 @@ int test_multi_declaration(void) { // 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 @@ int test_multi_declaration(void) { // 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 @@ int test_multi_declaration(void) { // 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] diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp index ac8cf28880..a141af3c2b 100644 --- a/tools/libclang/CXCursor.cpp +++ b/tools/libclang/CXCursor.cpp @@ -794,16 +794,21 @@ static void CollectOverriddenMethods(CXTranslationUnit TU, 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 @@ static void CollectOverriddenMethods(CXTranslationUnit TU, 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 @@ static void CollectOverriddenMethods(CXTranslationUnit TU, 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 @@ void cxcursor::getOverriddenCursors(CXCursor cursor, 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> |