[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;
diff --git a/tools/libclang/CIndexHigh.cpp b/tools/libclang/CIndexHigh.cpp
index b5a05ea..0b36af3 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 @@
                            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 @@
                         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();
 }