aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--test/Index/targeted-file-refs.c59
-rw-r--r--tools/libclang/CIndex.cpp22
-rw-r--r--tools/libclang/CIndexHigh.cpp39
3 files changed, 90 insertions, 30 deletions
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<ASTUnit *>(TU->TUData);
@@ -270,10 +282,16 @@ void CursorVisitor::visitDeclsFromFileRegion(FileID File,
assert(!Decls.empty());
bool VisitedAtLeastOnce = false;
+ DeclContext *CurDC = 0;
SmallVector<Decl *, 16>::iterator DIt = Decls.begin();
for (SmallVector<Decl *, 16>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Decl *D = *DIt;
+ if (isInLexicalContext(D, CurDC))
+ continue;
+
+ CurDC = dyn_cast<DeclContext>(D);
+
// We handle forward decls via ObjCClassDecl.
if (ObjCInterfaceDecl *InterD = dyn_cast<ObjCInterfaceDecl>(D)) {
if (InterD->isForwardDecl())
@@ -285,6 +303,10 @@ void CursorVisitor::visitDeclsFromFileRegion(FileID File,
continue;
}
+ if (TagDecl *TD = dyn_cast<TagDecl>(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<ASTUnit*>(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<TagDecl>(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();
}