[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
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index 8f4b047..25d0c5b 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -237,6 +237,18 @@
     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 @@
   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 @@
         continue;
     }
 
+    if (TagDecl *TD = dyn_cast<TagDecl>(D))
+      if (!TD->isFreeStanding())
+        continue;
+
     RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
     if (CompRes == RangeBefore)
       continue;