summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2012-04-10 21:01:03 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2012-04-10 21:01:03 +0000
commit15f4c9819d172139c0b37e8a68767ea4fc03e5b6 (patch)
treeb1a179073ae5f3b5f54fb36e5ccdb21615143c41 /tools
parente19f86edab8fb3c2c1e99e0e9815b6058504df9b (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')
-rw-r--r--tools/libclang/CIndex.cpp2
-rw-r--r--tools/libclang/CXCursor.cpp52
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);
}
}