summaryrefslogtreecommitdiffstats
path: root/clang/tools/libclang/CIndex.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2010-05-18 21:09:07 +0000
committerTed Kremenek <kremenek@apple.com>2010-05-18 21:09:07 +0000
commit49be9e0819a5c05bf82695be28e21f71b8adda3e (patch)
tree064da43255fddbb14eb3e7b521743ce95ab596f6 /clang/tools/libclang/CIndex.cpp
parent6338d1593965bb0bd34ba97ba2e03a9a5be24b0f (diff)
downloadbcm5719-llvm-49be9e0819a5c05bf82695be28e21f71b8adda3e.tar.gz
bcm5719-llvm-49be9e0819a5c05bf82695be28e21f71b8adda3e.zip
Teach CursorVisitor about duplicate ObjCPropertyDecls that can arise because of a current
design limitation in how we handle Objective-C class extensions. This was causing the CursorVisitor to essentially visit an @property twice (once in the @interface, the other in the class extension). Fixes <rdar://problem/7410145>. llvm-svn: 104055
Diffstat (limited to 'clang/tools/libclang/CIndex.cpp')
-rw-r--r--clang/tools/libclang/CIndex.cpp51
1 files changed, 48 insertions, 3 deletions
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 9de7c0b06e8..6ea1619c3dc 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -297,6 +297,7 @@ public:
bool VisitObjCContainerDecl(ObjCContainerDecl *D);
bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND);
bool VisitObjCProtocolDecl(ObjCProtocolDecl *PID);
+ bool VisitObjCPropertyDecl(ObjCPropertyDecl *PD);
bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
bool VisitObjCImplDecl(ObjCImplDecl *D);
bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
@@ -528,7 +529,11 @@ bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
for (DeclContext::decl_iterator
I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) {
- CXCursor Cursor = MakeCXCursor(*I, TU);
+ Decl *D = *I;
+ if (D->getLexicalDeclContext() != DC)
+ continue;
+
+ CXCursor Cursor = MakeCXCursor(D, TU);
if (RegionOfInterest.isValid()) {
SourceRange Range =
@@ -666,6 +671,40 @@ bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
return VisitObjCContainerDecl(PID);
}
+bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
+ // FIXME: This implements a workaround with @property declarations also being
+ // installed in the DeclContext for the @interface. Eventually this code
+ // should be removed.
+ ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
+ if (!CDecl || !CDecl->IsClassExtension())
+ return false;
+
+ ObjCInterfaceDecl *ID = CDecl->getClassInterface();
+ if (!ID)
+ return false;
+
+ IdentifierInfo *PropertyId = PD->getIdentifier();
+ ObjCPropertyDecl *prevDecl =
+ ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
+
+ if (!prevDecl)
+ return false;
+
+ // Visit synthesized methods since they will be skipped when visiting
+ // the @interface.
+ if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
+ if (MD->isSynthesized())
+ if (Visit(MakeCXCursor(MD, TU)))
+ return true;
+
+ if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
+ if (MD->isSynthesized())
+ if (Visit(MakeCXCursor(MD, TU)))
+ return true;
+
+ return false;
+}
+
bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
// Issue callbacks for super class.
if (D->getSuperClass() &&
@@ -2480,8 +2519,14 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
// Adjust the annotated range based specific declarations.
const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
if (cursorK >= CXCursor_FirstDecl && cursorK <= CXCursor_LastDecl) {
- if (const DeclaratorDecl *DD =
- dyn_cast<DeclaratorDecl>(cxcursor::getCursorDecl(cursor))) {
+ Decl *D = cxcursor::getCursorDecl(cursor);
+ // Don't visit synthesized ObjC methods, since they have no syntatic
+ // representation in the source.
+ if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
+ if (MD->isSynthesized())
+ return CXChildVisit_Continue;
+ }
+ if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
if (TypeSourceInfo *TI = DD->getTypeSourceInfo()) {
TypeLoc TL = TI->getTypeLoc();
SourceLocation TLoc = TL.getFullSourceRange().getBegin();
OpenPOWER on IntegriCloud