From e2079cf54ded1eda9e35d215aef6628373368276 Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Wed, 16 Nov 2011 08:58:54 +0000 Subject: [PATCH] [libclang] Make clang_findReferencesInFile use "file-targeted" deserialization and avoid unnecessary deserializations. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@144791 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/Index/targeted-file-refs.c | 59 +++++++++++++++++++++++++++++++++ tools/libclang/CIndex.cpp | 22 ++++++++++++ tools/libclang/CIndexHigh.cpp | 39 +++++----------------- 3 files changed, 90 insertions(+), 30 deletions(-) create mode 100644 test/Index/targeted-file-refs.c diff --git a/test/Index/targeted-file-refs.c b/test/Index/targeted-file-refs.c new file mode 100644 index 0000000000..195cd8604d --- /dev/null +++ b/test/Index/targeted-file-refs.c @@ -0,0 +1,59 @@ + +#include "targeted-top.h" +#include "targeted-preamble.h" + +extern int LocalVar; +int LocalVar; + +// RUN: c-index-test -write-pch %t.h.pch %S/targeted-top.h -Xclang -detailed-preprocessing-record +// RUN: env CINDEXTEST_FAILONERROR=1 c-index-test -file-refs-at=%s:5:17 %s -include %t.h \ +// RUN: -Xclang -error-on-deserialized-decl=NestedVar1 \ +// RUN: -Xclang -error-on-deserialized-decl=TopVar \ +// RUN: | FileCheck %s -check-prefix=LOCAL + +// RUN: env CINDEXTEST_FAILONERROR=1 CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_NO_CACHING=1 \ +// RUN: c-index-test -file-refs-at=%s:5:17 %s -include %t.h \ +// RUN: -Xclang -error-on-deserialized-decl=PreambleVar \ +// RUN: -Xclang -error-on-deserialized-decl=NestedVar1 \ +// RUN: -Xclang -error-on-deserialized-decl=TopVar \ +// RUN: | FileCheck %s -check-prefix=LOCAL + +// LOCAL: VarDecl=LocalVar:5:12 +// LOCAL: VarDecl=LocalVar:5:12 =[5:12 - 5:20] +// LOCAL: VarDecl=LocalVar:6:5 =[6:5 - 6:13] + +// RUN: env CINDEXTEST_FAILONERROR=1 c-index-test -file-refs-at=%S/targeted-top.h:14:7 %s -include %t.h \ +// RUN: -Xclang -error-on-deserialized-decl=NestedVar1 \ +// RUN: | FileCheck %s -check-prefix=TOP + +// RUN: env CINDEXTEST_FAILONERROR=1 CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_NO_CACHING=1 \ +// RUN: c-index-test -file-refs-at=%S/targeted-top.h:14:7 %s -include %t.h \ +// RUN: -Xclang -error-on-deserialized-decl=PreambleVar \ +// RUN: -Xclang -error-on-deserialized-decl=NestedVar1 \ +// RUN: | FileCheck %s -check-prefix=TOP + +// TOP: FieldDecl=x:14:7 (Definition) +// TOP: FieldDecl=x:14:7 (Definition) =[14:7 - 14:8] +// TOP: MemberRefExpr=x:14:7 SingleRefName=[20:13 - 20:14] RefName=[20:13 - 20:14] =[20:13 - 20:14] + +// RUN: env CINDEXTEST_FAILONERROR=1 c-index-test -file-refs-at=%S/targeted-nested1.h:2:16 %s -include %t.h \ +// RUN: -Xclang -error-on-deserialized-decl=TopVar \ +// RUN: | FileCheck %s -check-prefix=NESTED + +// RUN: env CINDEXTEST_FAILONERROR=1 CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_NO_CACHING=1 \ +// RUN: c-index-test -file-refs-at=%S/targeted-nested1.h:2:16 %s -include %t.h \ +// RUN: -Xclang -error-on-deserialized-decl=PreambleVar \ +// RUN: -Xclang -error-on-deserialized-decl=TopVar \ +// RUN: | FileCheck %s -check-prefix=NESTED + +// NESTED: VarDecl=NestedVar1:2:12 +// NESTED: VarDecl=NestedVar1:2:12 =[2:12 - 2:22] + +// RUN: env CINDEXTEST_FAILONERROR=1 CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_NO_CACHING=1 \ +// RUN: c-index-test -file-refs-at=%S/targeted-preamble.h:2:15 %s -include %t.h \ +// RUN: -Xclang -error-on-deserialized-decl=NestedVar1 \ +// RUN: -Xclang -error-on-deserialized-decl=TopVar \ +// RUN: | FileCheck %s -check-prefix=PREAMBLE + +// PREAMBLE: VarDecl=PreambleVar:2:12 +// PREAMBLE: VarDecl=PreambleVar:2:12 =[2:12 - 2:23] diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index 8f4b0471f8..25d0c5b6da 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -237,6 +237,18 @@ void CursorVisitor::visitFileRegion() { visitPreprocessedEntitiesInRegion(); } +static bool isInLexicalContext(Decl *D, DeclContext *DC) { + if (!DC) + return false; + + for (DeclContext *DeclDC = D->getLexicalDeclContext(); + DeclDC; DeclDC = DeclDC->getLexicalParent()) { + if (DeclDC == DC) + return true; + } + return false; +} + void CursorVisitor::visitDeclsFromFileRegion(FileID File, unsigned Offset, unsigned Length) { ASTUnit *Unit = static_cast(TU->TUData); @@ -270,10 +282,16 @@ void CursorVisitor::visitDeclsFromFileRegion(FileID File, assert(!Decls.empty()); bool VisitedAtLeastOnce = false; + DeclContext *CurDC = 0; SmallVector::iterator DIt = Decls.begin(); for (SmallVector::iterator DE = Decls.end(); DIt != DE; ++DIt) { Decl *D = *DIt; + if (isInLexicalContext(D, CurDC)) + continue; + + CurDC = dyn_cast(D); + // We handle forward decls via ObjCClassDecl. if (ObjCInterfaceDecl *InterD = dyn_cast(D)) { if (InterD->isForwardDecl()) @@ -285,6 +303,10 @@ void CursorVisitor::visitDeclsFromFileRegion(FileID File, continue; } + if (TagDecl *TD = dyn_cast(D)) + if (!TD->isFreeStanding()) + continue; + RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range); if (CompRes == RangeBefore) continue; diff --git a/tools/libclang/CIndexHigh.cpp b/tools/libclang/CIndexHigh.cpp index b5a05eaafc..0b36af3c95 100644 --- a/tools/libclang/CIndexHigh.cpp +++ b/tools/libclang/CIndexHigh.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#include "Index_Internal.h" +#include "CursorVisitor.h" #include "CXCursor.h" #include "CXSourceLocation.h" #include "CXTranslationUnit.h" @@ -16,6 +16,7 @@ #include "clang/AST/DeclObjC.h" using namespace clang; +using namespace cxcursor; static void getTopOverriddenMethods(CXTranslationUnit TU, Decl *D, @@ -197,7 +198,6 @@ static void findIdRefsInFile(CXTranslationUnit TU, CXCursor declCursor, CXCursorAndRangeVisitor Visitor) { assert(clang_isDeclaration(declCursor.kind)); ASTUnit *Unit = static_cast(TU->TUData); - ASTContext &Ctx = Unit->getASTContext(); SourceManager &SM = Unit->getSourceManager(); FileID FID = SM.translateFile(File); @@ -211,35 +211,14 @@ static void findIdRefsInFile(CXTranslationUnit TU, CXCursor declCursor, findFileIdRefVisit, &data); return; } - - if (FID == SM.getMainFileID() && !Unit->isMainFileAST()) { - SourceLocation FileLoc = SM.getLocForStartOfFile(FID); - TranslationUnitDecl *TUD = Ctx.getTranslationUnitDecl(); - CXCursor TUCursor = clang_getTranslationUnitCursor(TU); - for (DeclContext::decl_iterator - I = TUD->noload_decls_begin(), E = TUD->noload_decls_end(); - I != E; ++I) { - Decl *D = *I; - - SourceRange R = D->getSourceRange(); - if (R.isInvalid()) - continue; - if (SM.isBeforeInTranslationUnit(R.getEnd(), FileLoc)) - continue; - - if (TagDecl *TD = dyn_cast(D)) - if (!TD->isFreeStanding()) - continue; - - CXCursor CurCursor = cxcursor::MakeCXCursor(D, TU); - findFileIdRefVisit(CurCursor, TUCursor, &data); - clang_visitChildren(CurCursor, findFileIdRefVisit, &data); - } - return; - } - clang_visitChildren(clang_getTranslationUnitCursor(TU), - findFileIdRefVisit, &data); + SourceRange Range(SM.getLocForStartOfFile(FID), SM.getLocForEndOfFile(FID)); + CursorVisitor FindIdRefsVisitor(TU, + findFileIdRefVisit, &data, + /*VisitPreprocessorLast=*/true, + /*VisitIncludedEntities=*/false, + Range); + FindIdRefsVisitor.visitFileRegion(); } -- 2.40.0