diff options
Diffstat (limited to 'tools/libclang/CXCursor.cpp')
-rw-r--r-- | tools/libclang/CXCursor.cpp | 63 |
1 files changed, 44 insertions, 19 deletions
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> |