From 940d97bf277b866b33cc8d739d37b85a8f11935b Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Fri, 1 Jul 2016 19:10:54 +0000 Subject: [PATCH] [libclang] Sync-up the way top-level decls in an ASTUnit are handled with how decls in a DeclContext are handled. rdar://19775013 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@274378 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/Index/properties-class-extensions.m | 2 +- tools/libclang/CIndex.cpp | 74 ++++++++++++++---------- tools/libclang/CursorVisitor.h | 3 + 3 files changed, 46 insertions(+), 33 deletions(-) diff --git a/test/Index/properties-class-extensions.m b/test/Index/properties-class-extensions.m index 0fa0ecba6b..7af6553fbd 100644 --- a/test/Index/properties-class-extensions.m +++ b/test/Index/properties-class-extensions.m @@ -70,7 +70,7 @@ // CHECK-NOT: properties-class-extensions.m:16:25: ObjCInstanceMethodDecl=bar:16:25 Extent=[16:25 - 16:28] // CHECK: properties-class-extensions.m:19:26: ObjCInstanceMethodDecl=setBar::19:26 Extent=[19:26 - 19:29] // CHECK: properties-class-extensions.m:19:26: ParmDecl=bar:19:26 (Definition) Extent=[19:26 - 19:29] -// CHECK: properties-class-extensions.m:24:8: ObjCInterfaceDecl=Rdar8467189_Bar:24:8 Extent=[24:1 - 24:23] +// CHECK-NOT: properties-class-extensions.m:24:8: ObjCInterfaceDecl=Rdar8467189_Bar:24:8 // CHECK: properties-class-extensions.m:24:8: ObjCClassRef=Rdar8467189_Bar:24:8 Extent=[24:8 - 24:23] // CHECK: properties-class-extensions.m:25:11: ObjCProtocolDecl=Rdar8467189_FooProtocol:25:11 (Definition) Extent=[25:1 - 27:5] // CHECK: properties-class-extensions.m:26:39: ObjCPropertyDecl=Rdar8467189_Bar:26:39 [readonly,] Extent=[26:1 - 26:54] diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index 4d1cfb1165..3623d53d2c 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -523,8 +523,10 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) { for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(), TLEnd = CXXUnit->top_level_end(); TL != TLEnd; ++TL) { - if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true)) - return true; + const Optional V = handleDeclForVisitation(*TL); + if (!V.hasValue()) + continue; + return V.getValue(); } } else if (VisitDeclContext( CXXUnit->getASTContext().getTranslationUnitDecl())) @@ -621,42 +623,50 @@ bool CursorVisitor::VisitDeclContext(DeclContext *DC) { Decl *D = *I; if (D->getLexicalDeclContext() != DC) continue; - CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest); - - // Ignore synthesized ivars here, otherwise if we have something like: - // @synthesize prop = _prop; - // and '_prop' is not declared, we will encounter a '_prop' ivar before - // encountering the 'prop' synthesize declaration and we will think that - // we passed the region-of-interest. - if (ObjCIvarDecl *ivarD = dyn_cast(D)) { - if (ivarD->getSynthesize()) - continue; - } - - // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol - // declarations is a mismatch with the compiler semantics. - if (Cursor.kind == CXCursor_ObjCInterfaceDecl) { - ObjCInterfaceDecl *ID = cast(D); - if (!ID->isThisDeclarationADefinition()) - Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU); - - } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) { - ObjCProtocolDecl *PD = cast(D); - if (!PD->isThisDeclarationADefinition()) - Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU); - } - - const Optional &V = shouldVisitCursor(Cursor); + const Optional V = handleDeclForVisitation(D); if (!V.hasValue()) continue; - if (!V.getValue()) - return false; - if (Visit(Cursor, true)) - return true; + return V.getValue(); } return false; } +Optional CursorVisitor::handleDeclForVisitation(const Decl *D) { + CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest); + + // Ignore synthesized ivars here, otherwise if we have something like: + // @synthesize prop = _prop; + // and '_prop' is not declared, we will encounter a '_prop' ivar before + // encountering the 'prop' synthesize declaration and we will think that + // we passed the region-of-interest. + if (auto *ivarD = dyn_cast(D)) { + if (ivarD->getSynthesize()) + return None; + } + + // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol + // declarations is a mismatch with the compiler semantics. + if (Cursor.kind == CXCursor_ObjCInterfaceDecl) { + auto *ID = cast(D); + if (!ID->isThisDeclarationADefinition()) + Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU); + + } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) { + auto *PD = cast(D); + if (!PD->isThisDeclarationADefinition()) + Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU); + } + + const Optional V = shouldVisitCursor(Cursor); + if (!V.hasValue()) + return None; + if (!V.getValue()) + return false; + if (Visit(Cursor, true)) + return true; + return None; +} + bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) { llvm_unreachable("Translation units are visited directly by Visit()"); } diff --git a/tools/libclang/CursorVisitor.h b/tools/libclang/CursorVisitor.h index 356251d425..a2dfaeedcc 100644 --- a/tools/libclang/CursorVisitor.h +++ b/tools/libclang/CursorVisitor.h @@ -265,6 +265,9 @@ public: bool RunVisitorWorkList(VisitorWorkList &WL); void EnqueueWorkList(VisitorWorkList &WL, const Stmt *S); LLVM_ATTRIBUTE_NOINLINE bool Visit(const Stmt *S); + +private: + Optional handleDeclForVisitation(const Decl *D); }; } -- 2.40.0