diff options
author | Ted Kremenek <kremenek@apple.com> | 2010-05-18 21:09:07 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2010-05-18 21:09:07 +0000 |
commit | 49be9e0819a5c05bf82695be28e21f71b8adda3e (patch) | |
tree | 064da43255fddbb14eb3e7b521743ce95ab596f6 /clang/tools/libclang/CIndex.cpp | |
parent | 6338d1593965bb0bd34ba97ba2e03a9a5be24b0f (diff) | |
download | bcm5719-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.cpp | 51 |
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(); |