diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 46a5f34b2f0a..13490804232d 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -5449,62 +5449,6 @@ CXCursor clang_getCursorLexicalParent(CXCursor cursor) { return clang_getNullCursor(); } -static void CollectOverriddenMethods(DeclContext *Ctx, - ObjCMethodDecl *Method, - SmallVectorImpl &Methods) { - if (!Ctx) - return; - - // If we have a class or category implementation, jump straight to the - // interface. - if (ObjCImplDecl *Impl = dyn_cast(Ctx)) - return CollectOverriddenMethods(Impl->getClassInterface(), Method, Methods); - - ObjCContainerDecl *Container = dyn_cast(Ctx); - if (!Container) - return; - - // Check whether we have a matching method at this level. - if (ObjCMethodDecl *Overridden = Container->getMethod(Method->getSelector(), - Method->isInstanceMethod())) - if (Method != Overridden) { - // We found an override at this level; there is no need to look - // into other protocols or categories. - Methods.push_back(Overridden); - return; - } - - if (ObjCProtocolDecl *Protocol = dyn_cast(Container)) { - for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(), - PEnd = Protocol->protocol_end(); - P != PEnd; ++P) - CollectOverriddenMethods(*P, Method, Methods); - } - - if (ObjCCategoryDecl *Category = dyn_cast(Container)) { - for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(), - PEnd = Category->protocol_end(); - P != PEnd; ++P) - CollectOverriddenMethods(*P, Method, Methods); - } - - if (ObjCInterfaceDecl *Interface = dyn_cast(Container)) { - for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(), - PEnd = Interface->protocol_end(); - P != PEnd; ++P) - CollectOverriddenMethods(*P, Method, Methods); - - for (ObjCCategoryDecl *Category = Interface->getCategoryList(); - Category; Category = Category->getNextClassCategory()) - CollectOverriddenMethods(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(Super, Method, Methods); - } -} - void clang_getOverriddenCursors(CXCursor cursor, CXCursor **overridden, unsigned *num_overridden) { @@ -5515,45 +5459,12 @@ void clang_getOverriddenCursors(CXCursor cursor, if (!overridden || !num_overridden) return; - if (!clang_isDeclaration(cursor.kind)) - return; + SmallVector Overridden; + cxcursor::getOverriddenCursors(cursor, Overridden); - Decl *D = getCursorDecl(cursor); - if (!D) - return; - - // Handle C++ member functions. - CXTranslationUnit TU = getCursorTU(cursor); - if (CXXMethodDecl *CXXMethod = dyn_cast(D)) { - *num_overridden = CXXMethod->size_overridden_methods(); - if (!*num_overridden) - return; - - *overridden = new CXCursor [*num_overridden]; - unsigned I = 0; - for (CXXMethodDecl::method_iterator - M = CXXMethod->begin_overridden_methods(), - MEnd = CXXMethod->end_overridden_methods(); - M != MEnd; (void)++M, ++I) - (*overridden)[I] = MakeCXCursor(const_cast(*M), TU); - return; - } - - ObjCMethodDecl *Method = dyn_cast(D); - if (!Method) - return; - - // Handle Objective-C methods. - SmallVector Methods; - CollectOverriddenMethods(Method->getDeclContext(), Method, Methods); - - if (Methods.empty()) - return; - - *num_overridden = Methods.size(); - *overridden = new CXCursor [Methods.size()]; - for (unsigned I = 0, N = Methods.size(); I != N; ++I) - (*overridden)[I] = MakeCXCursor(Methods[I], TU); + *num_overridden = Overridden.size(); + *overridden = new CXCursor [Overridden.size()]; + std::copy(Overridden.begin(), Overridden.end(), *overridden); } void clang_disposeOverriddenCursors(CXCursor *overridden) { diff --git a/clang/tools/libclang/CXCursor.cpp b/clang/tools/libclang/CXCursor.cpp index 4728b158ddbc..3aec4a2ea90f 100644 --- a/clang/tools/libclang/CXCursor.cpp +++ b/clang/tools/libclang/CXCursor.cpp @@ -702,6 +702,92 @@ CXTranslationUnit cxcursor::getCursorTU(CXCursor Cursor) { return static_cast(Cursor.data[2]); } +static void CollectOverriddenMethods(CXTranslationUnit TU, + DeclContext *Ctx, + ObjCMethodDecl *Method, + SmallVectorImpl &Methods) { + if (!Ctx) + return; + + // If we have a class or category implementation, jump straight to the + // interface. + if (ObjCImplDecl *Impl = dyn_cast(Ctx)) + return CollectOverriddenMethods(TU, Impl->getClassInterface(), + Method, Methods); + + ObjCContainerDecl *Container = dyn_cast(Ctx); + if (!Container) + return; + + // Check whether we have a matching method at this level. + if (ObjCMethodDecl *Overridden = Container->getMethod(Method->getSelector(), + Method->isInstanceMethod())) + if (Method != Overridden) { + // We found an override at this level; there is no need to look + // into other protocols or categories. + Methods.push_back(MakeCXCursor(Overridden, TU)); + return; + } + + if (ObjCProtocolDecl *Protocol = dyn_cast(Container)) { + for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(), + PEnd = Protocol->protocol_end(); + P != PEnd; ++P) + CollectOverriddenMethods(TU, *P, Method, Methods); + } + + if (ObjCCategoryDecl *Category = dyn_cast(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(Container)) { + for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(), + PEnd = Interface->protocol_end(); + P != PEnd; ++P) + CollectOverriddenMethods(TU, *P, Method, Methods); + + for (ObjCCategoryDecl *Category = Interface->getCategoryList(); + 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); + } +} + +void cxcursor::getOverriddenCursors(CXCursor cursor, + SmallVectorImpl &overridden) { + if (!clang_isDeclaration(cursor.kind)) + return; + + Decl *D = getCursorDecl(cursor); + if (!D) + return; + + // Handle C++ member functions. + CXTranslationUnit TU = getCursorTU(cursor); + if (CXXMethodDecl *CXXMethod = dyn_cast(D)) { + for (CXXMethodDecl::method_iterator + M = CXXMethod->begin_overridden_methods(), + MEnd = CXXMethod->end_overridden_methods(); + M != MEnd; ++M) + overridden.push_back(MakeCXCursor(const_cast(*M), TU)); + return; + } + + ObjCMethodDecl *Method = dyn_cast(D); + if (!Method) + return; + + // Handle Objective-C methods. + CollectOverriddenMethods(TU, Method->getDeclContext(), Method, overridden); +} + bool cxcursor::operator==(CXCursor X, CXCursor Y) { return X.kind == Y.kind && X.data[0] == Y.data[0] && X.data[1] == Y.data[1] && X.data[2] == Y.data[2]; diff --git a/clang/tools/libclang/CXCursor.h b/clang/tools/libclang/CXCursor.h index c7051ea2f987..5d9d5683c492 100644 --- a/clang/tools/libclang/CXCursor.h +++ b/clang/tools/libclang/CXCursor.h @@ -191,7 +191,10 @@ Decl *getCursorParentDecl(CXCursor Cursor); ASTContext &getCursorContext(CXCursor Cursor); ASTUnit *getCursorASTUnit(CXCursor Cursor); CXTranslationUnit getCursorTU(CXCursor Cursor); - + +void getOverriddenCursors(CXCursor cursor, + SmallVectorImpl &overridden); + bool operator==(CXCursor X, CXCursor Y); inline bool operator!=(CXCursor X, CXCursor Y) {