diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2012-04-10 21:01:03 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2012-04-10 21:01:03 +0000 |
commit | 15f4c9819d172139c0b37e8a68767ea4fc03e5b6 (patch) | |
tree | b1a179073ae5f3b5f54fb36e5ccdb21615143c41 /tools/libclang | |
parent | e19f86edab8fb3c2c1e99e0e9815b6058504df9b (diff) |
[libclang] For clang_getOverriddenCursors make sure to report overridden objc methods
for methods in categories of super classes. rdar://11220358
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@154436 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/libclang')
-rw-r--r-- | tools/libclang/CIndex.cpp | 2 | ||||
-rw-r--r-- | tools/libclang/CXCursor.cpp | 52 |
2 files changed, 38 insertions, 16 deletions
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index 1896132fa0..eafb867eb2 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -5535,6 +5535,8 @@ void clang_getOverriddenCursors(CXCursor cursor, *num_overridden = 0; if (!overridden || !num_overridden) return; + if (!clang_isDeclaration(cursor.kind)) + return; SmallVector<CXCursor, 8> Overridden; cxcursor::getOverriddenCursors(cursor, Overridden); diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp index 0533c84a57..8371a4f273 100644 --- a/tools/libclang/CXCursor.cpp +++ b/tools/libclang/CXCursor.cpp @@ -786,14 +786,11 @@ CXTranslationUnit cxcursor::getCursorTU(CXCursor Cursor) { 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 @@ static void CollectOverriddenMethods(CXTranslationUnit TU, // 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 @@ static void CollectOverriddenMethods(CXTranslationUnit TU, 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 @@ void cxcursor::getOverriddenCursors(CXCursor cursor, CollectOverriddenMethods(TU, ID, Method, overridden); } else { - CollectOverriddenMethods(TU, Method->getDeclContext(), Method, overridden); + CollectOverriddenMethods(TU, + dyn_cast_or_null<ObjCContainerDecl>(Method->getDeclContext()), + Method, overridden); } } |