[libclang] Separate the underlying indexing functionality of libclang and introduce it into the clangIndex library.

It is a general goodness for libclang itself to mostly be a wrapper of functionality provided by the libraries.

llvm-svn: 260760
diff --git a/clang/tools/libclang/CMakeLists.txt b/clang/tools/libclang/CMakeLists.txt
index d7eaca1..d893b5e 100644
--- a/clang/tools/libclang/CMakeLists.txt
+++ b/clang/tools/libclang/CMakeLists.txt
@@ -11,17 +11,14 @@
   CIndexer.cpp
   CXComment.cpp
   CXCursor.cpp
+  CXIndexDataConsumer.cpp
   CXCompilationDatabase.cpp
   CXLoadedDiagnostic.cpp
   CXSourceLocation.cpp
   CXStoredDiagnostic.cpp
   CXString.cpp
   CXType.cpp
-  IndexBody.cpp
-  IndexDecl.cpp
-  IndexTypeSourceInfo.cpp
   Indexing.cpp
-  IndexingContext.cpp
 
   ADDITIONAL_HEADERS
   CIndexDiagnostic.h
diff --git a/clang/tools/libclang/IndexingContext.cpp b/clang/tools/libclang/CXIndexDataConsumer.cpp
similarity index 70%
rename from clang/tools/libclang/IndexingContext.cpp
rename to clang/tools/libclang/CXIndexDataConsumer.cpp
index 7f65412..f6f8e30 100644
--- a/clang/tools/libclang/IndexingContext.cpp
+++ b/clang/tools/libclang/CXIndexDataConsumer.cpp
@@ -1,4 +1,4 @@
-//===- IndexingContext.cpp - Higher level API functions -------------------===//
+//===- CXIndexDataConsumer.cpp - Index data consumer for libclang----------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -7,21 +7,219 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "IndexingContext.h"
+#include "CXIndexDataConsumer.h"
 #include "CIndexDiagnostic.h"
 #include "CXTranslationUnit.h"
 #include "clang/AST/Attr.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DeclVisitor.h"
 #include "clang/Frontend/ASTUnit.h"
 
 using namespace clang;
+using namespace clang::index;
 using namespace cxindex;
 using namespace cxcursor;
 
-IndexingContext::ObjCProtocolListInfo::ObjCProtocolListInfo(
+namespace {
+class IndexingDeclVisitor : public ConstDeclVisitor<IndexingDeclVisitor, bool> {
+  CXIndexDataConsumer &DataConsumer;
+  SourceLocation DeclLoc;
+  const DeclContext *LexicalDC;
+
+public:
+  IndexingDeclVisitor(CXIndexDataConsumer &dataConsumer, SourceLocation Loc,
+                      const DeclContext *lexicalDC)
+    : DataConsumer(dataConsumer), DeclLoc(Loc), LexicalDC(lexicalDC) { }
+
+  bool VisitFunctionDecl(const FunctionDecl *D) {
+    DataConsumer.handleFunction(D);
+    return true;
+  }
+
+  bool VisitVarDecl(const VarDecl *D) {
+    DataConsumer.handleVar(D);
+    return true;
+  }
+
+  bool VisitFieldDecl(const FieldDecl *D) {
+    DataConsumer.handleField(D);
+    return true;
+  }
+
+  bool VisitMSPropertyDecl(const MSPropertyDecl *D) {
+    return true;
+  }
+
+  bool VisitEnumConstantDecl(const EnumConstantDecl *D) {
+    DataConsumer.handleEnumerator(D);
+    return true;
+  }
+
+  bool VisitTypedefNameDecl(const TypedefNameDecl *D) {
+    DataConsumer.handleTypedefName(D);
+    return true;
+  }
+
+  bool VisitTagDecl(const TagDecl *D) {
+    DataConsumer.handleTagDecl(D);
+    return true;
+  }
+
+  bool VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
+    DataConsumer.handleObjCInterface(D);
+    return true;
+  }
+
+  bool VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
+    DataConsumer.handleObjCProtocol(D);
+    return true;
+  }
+
+  bool VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
+    DataConsumer.handleObjCImplementation(D);
+    return true;
+  }
+
+  bool VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
+    DataConsumer.handleObjCCategory(D);
+    return true;
+  }
+
+  bool VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
+    DataConsumer.handleObjCCategoryImpl(D);
+    return true;
+  }
+
+  bool VisitObjCMethodDecl(const ObjCMethodDecl *D) {
+    if (D->getDeclContext() != LexicalDC)
+      DataConsumer.handleSynthesizedObjCMethod(D, DeclLoc, LexicalDC);
+    else
+      DataConsumer.handleObjCMethod(D);
+    return true;
+  }
+
+  bool VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
+    DataConsumer.handleObjCProperty(D);
+    return true;
+  }
+
+  bool VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
+    DataConsumer.handleSynthesizedObjCProperty(D);
+    return true;
+  }
+
+  bool VisitNamespaceDecl(const NamespaceDecl *D) {
+    DataConsumer.handleNamespace(D);
+    return true;
+  }
+
+  bool VisitUsingDecl(const UsingDecl *D) {
+    return true;
+  }
+
+  bool VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
+    return true;
+  }
+
+  bool VisitClassTemplateDecl(const ClassTemplateDecl *D) {
+    DataConsumer.handleClassTemplate(D);
+    return true;
+  }
+
+  bool VisitClassTemplateSpecializationDecl(const
+                                           ClassTemplateSpecializationDecl *D) {
+    DataConsumer.handleTagDecl(D);
+    return true;
+  }
+
+  bool VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
+    DataConsumer.handleFunctionTemplate(D);
+    return true;
+  }
+
+  bool VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) {
+    DataConsumer.handleTypeAliasTemplate(D);
+    return true;
+  }
+
+  bool VisitImportDecl(const ImportDecl *D) {
+    DataConsumer.importedModule(D);
+    return true;
+  }
+};
+}
+
+bool CXIndexDataConsumer::handleDeclOccurence(const Decl *D,
+                                              SymbolRoleSet Roles,
+                                             ArrayRef<SymbolRelation> Relations,
+                                              FileID FID, unsigned Offset,
+                                              ASTNodeInfo ASTNode) {
+  SourceLocation Loc = getASTContext().getSourceManager()
+      .getLocForStartOfFile(FID).getLocWithOffset(Offset);
+
+  if (Roles & (unsigned)SymbolRole::Reference) {
+    const NamedDecl *ND = dyn_cast<NamedDecl>(D);
+    if (!ND)
+      return true;
+
+    if (auto *ObjCID = dyn_cast_or_null<ObjCInterfaceDecl>(ASTNode.OrigD)) {
+      if (!ObjCID->isThisDeclarationADefinition() &&
+          ObjCID->getLocation() == Loc) {
+        // The libclang API treats this as ObjCClassRef declaration.
+        IndexingDeclVisitor(*this, Loc, nullptr).Visit(ObjCID);
+        return true;
+      }
+    }
+
+    CXIdxEntityRefKind Kind = CXIdxEntityRef_Direct;
+    if (Roles & (unsigned)SymbolRole::Implicit) {
+      Kind = CXIdxEntityRef_Implicit;
+    }
+
+    CXCursor Cursor;
+    if (ASTNode.OrigE) {
+      Cursor = cxcursor::MakeCXCursor(ASTNode.OrigE,
+                                      cast<Decl>(ASTNode.ContainerDC),
+                                      getCXTU());
+    } else {
+      const NamedDecl *CursorD = dyn_cast_or_null<NamedDecl>(ASTNode.OrigD);
+      if (!CursorD)
+        CursorD = ND;
+      Cursor = getRefCursor(CursorD, Loc);
+    }
+    handleReference(ND, Loc, Cursor,
+                    dyn_cast_or_null<NamedDecl>(ASTNode.Parent),
+                    ASTNode.ContainerDC, ASTNode.OrigE, Kind);
+
+  } else {
+    const DeclContext *DC = nullptr;
+    for (const auto &SymRel : Relations) {
+      if (SymRel.Roles & (unsigned)SymbolRole::RelationChildOf)
+        DC = dyn_cast<DeclContext>(SymRel.RelatedSymbol);
+    }
+    IndexingDeclVisitor(*this, Loc, DC).Visit(ASTNode.OrigD);
+  }
+
+  return !shouldAbort();
+}
+
+bool CXIndexDataConsumer::handleModuleOccurence(const ImportDecl *ImportD,
+                                                SymbolRoleSet Roles,
+                                                FileID FID,
+                                                unsigned Offset) {
+  IndexingDeclVisitor(*this, SourceLocation(), nullptr).Visit(ImportD);
+  return !shouldAbort();
+}
+
+void CXIndexDataConsumer::finish() {
+  indexDiagnostics();
+}
+
+
+CXIndexDataConsumer::ObjCProtocolListInfo::ObjCProtocolListInfo(
                                     const ObjCProtocolList &ProtList,
-                                    IndexingContext &IdxCtx,
+                                    CXIndexDataConsumer &IdxCtx,
                                     ScratchAlloc &SA) {
   ObjCInterfaceDecl::protocol_loc_iterator LI = ProtList.loc_begin();
   for (ObjCInterfaceDecl::protocol_iterator
@@ -61,7 +259,7 @@
     IBCollInfo.objcClass = nullptr;
 }
 
-AttrListInfo::AttrListInfo(const Decl *D, IndexingContext &IdxCtx)
+AttrListInfo::AttrListInfo(const Decl *D, CXIndexDataConsumer &IdxCtx)
   : SA(IdxCtx), ref_cnt(0) {
 
   if (!D->hasAttrs())
@@ -114,14 +312,14 @@
 }
 
 IntrusiveRefCntPtr<AttrListInfo>
-AttrListInfo::create(const Decl *D, IndexingContext &IdxCtx) {
+AttrListInfo::create(const Decl *D, CXIndexDataConsumer &IdxCtx) {
   ScratchAlloc SA(IdxCtx);
   AttrListInfo *attrs = SA.allocate<AttrListInfo>();
   return new (attrs) AttrListInfo(D, IdxCtx);
 }
 
-IndexingContext::CXXBasesListInfo::CXXBasesListInfo(const CXXRecordDecl *D,
-                                   IndexingContext &IdxCtx,
+CXIndexDataConsumer::CXXBasesListInfo::CXXBasesListInfo(const CXXRecordDecl *D,
+                                   CXIndexDataConsumer &IdxCtx,
                                    ScratchAlloc &SA) {
   for (const auto &Base : D->bases()) {
     BaseEntities.push_back(EntityInfo());
@@ -155,7 +353,7 @@
     CXBases.push_back(&BaseInfos[i]);
 }
 
-SourceLocation IndexingContext::CXXBasesListInfo::getBaseLoc(
+SourceLocation CXIndexDataConsumer::CXXBasesListInfo::getBaseLoc(
                                            const CXXBaseSpecifier &Base) const {
   SourceLocation Loc = Base.getSourceRange().getBegin();
   TypeLoc TL;
@@ -193,16 +391,16 @@
   return buf;
 }
 
-void IndexingContext::setASTContext(ASTContext &ctx) {
+void CXIndexDataConsumer::setASTContext(ASTContext &ctx) {
   Ctx = &ctx;
   cxtu::getASTUnit(CXTU)->setASTContext(&ctx);
 }
 
-void IndexingContext::setPreprocessor(Preprocessor &PP) {
+void CXIndexDataConsumer::setPreprocessor(Preprocessor &PP) {
   cxtu::getASTUnit(CXTU)->setPreprocessor(&PP);
 }
 
-bool IndexingContext::isFunctionLocalDecl(const Decl *D) {
+bool CXIndexDataConsumer::isFunctionLocalDecl(const Decl *D) {
   assert(D);
 
   if (!D->getParentFunctionOrMethod())
@@ -224,13 +422,13 @@
   return true;
 }
 
-bool IndexingContext::shouldAbort() {
+bool CXIndexDataConsumer::shouldAbort() {
   if (!CB.abortQuery)
     return false;
   return CB.abortQuery(ClientData, nullptr);
 }
 
-void IndexingContext::enteredMainFile(const FileEntry *File) {
+void CXIndexDataConsumer::enteredMainFile(const FileEntry *File) {
   if (File && CB.enteredMainFile) {
     CXIdxClientFile idxFile =
       CB.enteredMainFile(ClientData,
@@ -240,7 +438,7 @@
   }
 }
 
-void IndexingContext::ppIncludedFile(SourceLocation hashLoc,
+void CXIndexDataConsumer::ppIncludedFile(SourceLocation hashLoc,
                                      StringRef filename,
                                      const FileEntry *File,
                                      bool isImport, bool isAngled,
@@ -258,7 +456,7 @@
   FileMap[File] = idxFile;
 }
 
-void IndexingContext::importedModule(const ImportDecl *ImportD) {
+void CXIndexDataConsumer::importedModule(const ImportDecl *ImportD) {
   if (!CB.importedASTFile)
     return;
 
@@ -277,7 +475,7 @@
   (void)astFile;
 }
 
-void IndexingContext::importedPCH(const FileEntry *File) {
+void CXIndexDataConsumer::importedPCH(const FileEntry *File) {
   if (!CB.importedASTFile)
     return;
 
@@ -292,21 +490,29 @@
   (void)astFile;
 }
 
-void IndexingContext::startedTranslationUnit() {
+void CXIndexDataConsumer::startedTranslationUnit() {
   CXIdxClientContainer idxCont = nullptr;
   if (CB.startedTranslationUnit)
     idxCont = CB.startedTranslationUnit(ClientData, nullptr);
   addContainerInMap(Ctx->getTranslationUnitDecl(), idxCont);
 }
 
-void IndexingContext::handleDiagnosticSet(CXDiagnostic CXDiagSet) {
+void CXIndexDataConsumer::indexDiagnostics() {
+  if (!hasDiagnosticCallback())
+    return;
+
+  CXDiagnosticSetImpl *DiagSet = cxdiag::lazyCreateDiags(getCXTU());
+  handleDiagnosticSet(DiagSet);
+}
+
+void CXIndexDataConsumer::handleDiagnosticSet(CXDiagnostic CXDiagSet) {
   if (!CB.diagnostic)
     return;
 
   CB.diagnostic(ClientData, CXDiagSet, nullptr);
 }
 
-bool IndexingContext::handleDecl(const NamedDecl *D,
+bool CXIndexDataConsumer::handleDecl(const NamedDecl *D,
                                  SourceLocation Loc, CXCursor Cursor,
                                  DeclInfo &DInfo,
                                  const DeclContext *LexicalDC,
@@ -365,14 +571,14 @@
   return true;
 }
 
-bool IndexingContext::handleObjCContainer(const ObjCContainerDecl *D,
+bool CXIndexDataConsumer::handleObjCContainer(const ObjCContainerDecl *D,
                                           SourceLocation Loc, CXCursor Cursor,
                                           ObjCContainerDeclInfo &ContDInfo) {
   ContDInfo.ObjCContDeclInfo.declInfo = &ContDInfo;
   return handleDecl(D, Loc, Cursor, ContDInfo);
 }
 
-bool IndexingContext::handleFunction(const FunctionDecl *D) {
+bool CXIndexDataConsumer::handleFunction(const FunctionDecl *D) {
   bool isDef = D->isThisDeclarationADefinition();
   bool isContainer = isDef;
   bool isSkipped = false;
@@ -388,31 +594,31 @@
   return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
 }
 
-bool IndexingContext::handleVar(const VarDecl *D) {
+bool CXIndexDataConsumer::handleVar(const VarDecl *D) {
   DeclInfo DInfo(!D->isFirstDecl(), D->isThisDeclarationADefinition(),
                  /*isContainer=*/false);
   return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
 }
 
-bool IndexingContext::handleField(const FieldDecl *D) {
+bool CXIndexDataConsumer::handleField(const FieldDecl *D) {
   DeclInfo DInfo(/*isRedeclaration=*/false, /*isDefinition=*/true,
                  /*isContainer=*/false);
   return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
 }
 
-bool IndexingContext::handleMSProperty(const MSPropertyDecl *D) {
+bool CXIndexDataConsumer::handleMSProperty(const MSPropertyDecl *D) {
   DeclInfo DInfo(/*isRedeclaration=*/false, /*isDefinition=*/true,
                  /*isContainer=*/false);
   return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
 }
 
-bool IndexingContext::handleEnumerator(const EnumConstantDecl *D) {
+bool CXIndexDataConsumer::handleEnumerator(const EnumConstantDecl *D) {
   DeclInfo DInfo(/*isRedeclaration=*/false, /*isDefinition=*/true,
                  /*isContainer=*/false);
   return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
 }
 
-bool IndexingContext::handleTagDecl(const TagDecl *D) {
+bool CXIndexDataConsumer::handleTagDecl(const TagDecl *D) {
   if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(D))
     return handleCXXRecordDecl(CXXRD, D);
 
@@ -421,13 +627,13 @@
   return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
 }
 
-bool IndexingContext::handleTypedefName(const TypedefNameDecl *D) {
+bool CXIndexDataConsumer::handleTypedefName(const TypedefNameDecl *D) {
   DeclInfo DInfo(!D->isFirstDecl(), /*isDefinition=*/true,
                  /*isContainer=*/false);
   return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
 }
 
-bool IndexingContext::handleObjCInterface(const ObjCInterfaceDecl *D) {
+bool CXIndexDataConsumer::handleObjCInterface(const ObjCInterfaceDecl *D) {
   // For @class forward declarations, suppress them the same way as references.
   if (!D->isThisDeclarationADefinition()) {
     if (shouldSuppressRefs() && markEntityOccurrenceInFile(D, D->getLocation()))
@@ -475,7 +681,7 @@
   return handleObjCContainer(D, D->getLocation(), getCursor(D), InterInfo);
 }
 
-bool IndexingContext::handleObjCImplementation(
+bool CXIndexDataConsumer::handleObjCImplementation(
                                               const ObjCImplementationDecl *D) {
   ObjCContainerDeclInfo ContDInfo(/*isForwardRef=*/false,
                       /*isRedeclaration=*/true,
@@ -483,7 +689,7 @@
   return handleObjCContainer(D, D->getLocation(), getCursor(D), ContDInfo);
 }
 
-bool IndexingContext::handleObjCProtocol(const ObjCProtocolDecl *D) {
+bool CXIndexDataConsumer::handleObjCProtocol(const ObjCProtocolDecl *D) {
   if (!D->isThisDeclarationADefinition()) {
     if (shouldSuppressRefs() && markEntityOccurrenceInFile(D, D->getLocation()))
       return false; // already occurred.
@@ -512,7 +718,7 @@
   return handleObjCContainer(D, D->getLocation(), getCursor(D), ProtInfo);
 }
 
-bool IndexingContext::handleObjCCategory(const ObjCCategoryDecl *D) {
+bool CXIndexDataConsumer::handleObjCCategory(const ObjCCategoryDecl *D) {
   ScratchAlloc SA(*this);
 
   ObjCCategoryDeclInfo CatDInfo(/*isImplementation=*/false);
@@ -544,7 +750,7 @@
   return handleObjCContainer(D, CategoryLoc, getCursor(D), CatDInfo);
 }
 
-bool IndexingContext::handleObjCCategoryImpl(const ObjCCategoryImplDecl *D) {
+bool CXIndexDataConsumer::handleObjCCategoryImpl(const ObjCCategoryImplDecl *D) {
   ScratchAlloc SA(*this);
 
   const ObjCCategoryDecl *CatD = D->getCategoryDecl();
@@ -573,7 +779,7 @@
   return handleObjCContainer(D, CategoryLoc, getCursor(D), CatDInfo);
 }
 
-bool IndexingContext::handleObjCMethod(const ObjCMethodDecl *D) {
+bool CXIndexDataConsumer::handleObjCMethod(const ObjCMethodDecl *D) {
   bool isDef = D->isThisDeclarationADefinition();
   bool isContainer = isDef;
   bool isSkipped = false;
@@ -589,7 +795,7 @@
   return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
 }
 
-bool IndexingContext::handleSynthesizedObjCProperty(
+bool CXIndexDataConsumer::handleSynthesizedObjCProperty(
                                                 const ObjCPropertyImplDecl *D) {
   ObjCPropertyDecl *PD = D->getPropertyDecl();
   auto *DC = D->getDeclContext();
@@ -597,7 +803,7 @@
                          dyn_cast<NamedDecl>(DC), DC);
 }
 
-bool IndexingContext::handleSynthesizedObjCMethod(const ObjCMethodDecl *D,
+bool CXIndexDataConsumer::handleSynthesizedObjCMethod(const ObjCMethodDecl *D,
                                                   SourceLocation Loc,
                                                  const DeclContext *LexicalDC) {
   DeclInfo DInfo(/*isRedeclaration=*/true, /*isDefinition=*/true,
@@ -605,7 +811,7 @@
   return handleDecl(D, Loc, getCursor(D), DInfo, LexicalDC, LexicalDC);
 }
 
-bool IndexingContext::handleObjCProperty(const ObjCPropertyDecl *D) {
+bool CXIndexDataConsumer::handleObjCProperty(const ObjCPropertyDecl *D) {
   ScratchAlloc SA(*this);
 
   ObjCPropertyDeclInfo DInfo;
@@ -630,31 +836,31 @@
   return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
 }
 
-bool IndexingContext::handleNamespace(const NamespaceDecl *D) {
+bool CXIndexDataConsumer::handleNamespace(const NamespaceDecl *D) {
   DeclInfo DInfo(/*isRedeclaration=*/!D->isOriginalNamespace(),
                  /*isDefinition=*/true,
                  /*isContainer=*/true);
   return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
 }
 
-bool IndexingContext::handleClassTemplate(const ClassTemplateDecl *D) {
+bool CXIndexDataConsumer::handleClassTemplate(const ClassTemplateDecl *D) {
   return handleCXXRecordDecl(D->getTemplatedDecl(), D);
 }
 
-bool IndexingContext::handleFunctionTemplate(const FunctionTemplateDecl *D) {
+bool CXIndexDataConsumer::handleFunctionTemplate(const FunctionTemplateDecl *D) {
   DeclInfo DInfo(/*isRedeclaration=*/!D->isCanonicalDecl(),
                  /*isDefinition=*/D->isThisDeclarationADefinition(),
                  /*isContainer=*/D->isThisDeclarationADefinition());
   return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
 }
 
-bool IndexingContext::handleTypeAliasTemplate(const TypeAliasTemplateDecl *D) {
+bool CXIndexDataConsumer::handleTypeAliasTemplate(const TypeAliasTemplateDecl *D) {
   DeclInfo DInfo(/*isRedeclaration=*/!D->isCanonicalDecl(),
                  /*isDefinition=*/true, /*isContainer=*/false);
   return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
 }
 
-bool IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc,
+bool CXIndexDataConsumer::handleReference(const NamedDecl *D, SourceLocation Loc,
                                       const NamedDecl *Parent,
                                       const DeclContext *DC,
                                       const Expr *E,
@@ -667,7 +873,7 @@
   return handleReference(D, Loc, Cursor, Parent, DC, E, Kind);
 }
 
-bool IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc,
+bool CXIndexDataConsumer::handleReference(const NamedDecl *D, SourceLocation Loc,
                                       CXCursor Cursor,
                                       const NamedDecl *Parent,
                                       const DeclContext *DC,
@@ -713,7 +919,7 @@
   return true;
 }
 
-bool IndexingContext::isNotFromSourceFile(SourceLocation Loc) const {
+bool CXIndexDataConsumer::isNotFromSourceFile(SourceLocation Loc) const {
   if (Loc.isInvalid())
     return true;
   SourceManager &SM = Ctx->getSourceManager();
@@ -722,7 +928,7 @@
   return SM.getFileEntryForID(FID) == nullptr;
 }
 
-void IndexingContext::addContainerInMap(const DeclContext *DC,
+void CXIndexDataConsumer::addContainerInMap(const DeclContext *DC,
                                         CXIdxClientContainer container) {
   if (!DC)
     return;
@@ -741,7 +947,7 @@
     ContainerMap.erase(I);
 }
 
-CXIdxClientEntity IndexingContext::getClientEntity(const Decl *D) const {
+CXIdxClientEntity CXIndexDataConsumer::getClientEntity(const Decl *D) const {
   if (!D)
     return nullptr;
   EntityMapTy::const_iterator I = EntityMap.find(D);
@@ -750,13 +956,13 @@
   return I->second;
 }
 
-void IndexingContext::setClientEntity(const Decl *D, CXIdxClientEntity client) {
+void CXIndexDataConsumer::setClientEntity(const Decl *D, CXIdxClientEntity client) {
   if (!D)
     return;
   EntityMap[D] = client;
 }
 
-bool IndexingContext::handleCXXRecordDecl(const CXXRecordDecl *RD,
+bool CXIndexDataConsumer::handleCXXRecordDecl(const CXXRecordDecl *RD,
                                           const NamedDecl *OrigD) {
   if (RD->isThisDeclarationADefinition()) {
     ScratchAlloc SA(*this);
@@ -789,7 +995,7 @@
   return handleDecl(OrigD, OrigD->getLocation(), getCursor(OrigD), DInfo);
 }
 
-bool IndexingContext::markEntityOccurrenceInFile(const NamedDecl *D,
+bool CXIndexDataConsumer::markEntityOccurrenceInFile(const NamedDecl *D,
                                                  SourceLocation Loc) {
   if (!D || Loc.isInvalid())
     return true;
@@ -811,7 +1017,7 @@
   return !res.second; // already in map
 }
 
-const NamedDecl *IndexingContext::getEntityDecl(const NamedDecl *D) const {
+const NamedDecl *CXIndexDataConsumer::getEntityDecl(const NamedDecl *D) const {
   assert(D);
   D = cast<NamedDecl>(D->getCanonicalDecl());
 
@@ -834,7 +1040,7 @@
 }
 
 const DeclContext *
-IndexingContext::getEntityContainer(const Decl *D) const {
+CXIndexDataConsumer::getEntityContainer(const Decl *D) const {
   const DeclContext *DC = dyn_cast<DeclContext>(D);
   if (DC)
     return DC;
@@ -850,7 +1056,7 @@
 }
 
 CXIdxClientContainer
-IndexingContext::getClientContainerForDC(const DeclContext *DC) const {
+CXIndexDataConsumer::getClientContainerForDC(const DeclContext *DC) const {
   if (!DC)
     return nullptr;
 
@@ -861,7 +1067,7 @@
   return I->second;
 }
 
-CXIdxClientFile IndexingContext::getIndexFile(const FileEntry *File) {
+CXIdxClientFile CXIndexDataConsumer::getIndexFile(const FileEntry *File) {
   if (!File)
     return nullptr;
 
@@ -872,17 +1078,17 @@
   return nullptr;
 }
 
-CXIdxLoc IndexingContext::getIndexLoc(SourceLocation Loc) const {
+CXIdxLoc CXIndexDataConsumer::getIndexLoc(SourceLocation Loc) const {
   CXIdxLoc idxLoc =  { {nullptr, nullptr}, 0 };
   if (Loc.isInvalid())
     return idxLoc;
 
-  idxLoc.ptr_data[0] = const_cast<IndexingContext *>(this);
+  idxLoc.ptr_data[0] = const_cast<CXIndexDataConsumer *>(this);
   idxLoc.int_data = Loc.getRawEncoding();
   return idxLoc;
 }
 
-void IndexingContext::translateLoc(SourceLocation Loc,
+void CXIndexDataConsumer::translateLoc(SourceLocation Loc,
                                    CXIdxClientFile *indexFile, CXFile *file,
                                    unsigned *line, unsigned *column,
                                    unsigned *offset) {
@@ -912,7 +1118,12 @@
     *offset = FileOffset;
 }
 
-void IndexingContext::getEntityInfo(const NamedDecl *D,
+static CXIdxEntityKind getEntityKindFromSymbolKind(SymbolKind K);
+static CXIdxEntityCXXTemplateKind
+getEntityKindFromSymbolCXXTemplateKind(SymbolCXXTemplateKind K);
+static CXIdxEntityLanguage getEntityLangFromSymbolLang(SymbolLanguage L);
+
+void CXIndexDataConsumer::getEntityInfo(const NamedDecl *D,
                                     EntityInfo &EntityInfo,
                                     ScratchAlloc &SA) {
   if (!D)
@@ -922,9 +1133,12 @@
   EntityInfo.cursor = getCursor(D);
   EntityInfo.Dcl = D;
   EntityInfo.IndexCtx = this;
-  EntityInfo.kind = CXIdxEntity_Unexposed;
-  EntityInfo.templateKind = CXIdxEntity_NonTemplate;
-  EntityInfo.lang = CXIdxEntityLang_C;
+
+  SymbolInfo SymInfo = getSymbolInfo(D);
+  EntityInfo.kind = getEntityKindFromSymbolKind(SymInfo.Kind);
+  EntityInfo.templateKind =
+    getEntityKindFromSymbolCXXTemplateKind(SymInfo.TemplateKind);
+  EntityInfo.lang = getEntityLangFromSymbolLang(SymInfo.Lang);
 
   if (D->hasAttrs()) {
     EntityInfo.AttrList = AttrListInfo::create(D, *this);
@@ -932,167 +1146,9 @@
     EntityInfo.numAttributes = EntityInfo.AttrList->getNumAttrs();
   }
 
-  if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
-    switch (TD->getTagKind()) {
-    case TTK_Struct:
-      EntityInfo.kind = CXIdxEntity_Struct; break;
-    case TTK_Union:
-      EntityInfo.kind = CXIdxEntity_Union; break;
-    case TTK_Class:
-      EntityInfo.kind = CXIdxEntity_CXXClass;
-      EntityInfo.lang = CXIdxEntityLang_CXX;
-      break;
-    case TTK_Interface:
-      EntityInfo.kind = CXIdxEntity_CXXInterface;
-      EntityInfo.lang = CXIdxEntityLang_CXX;
-      break;
-    case TTK_Enum:
-      EntityInfo.kind = CXIdxEntity_Enum; break;
-    }
-
-    if (const CXXRecordDecl *CXXRec = dyn_cast<CXXRecordDecl>(D))
-      if (!CXXRec->isCLike())
-        EntityInfo.lang = CXIdxEntityLang_CXX;
-
-    if (isa<ClassTemplatePartialSpecializationDecl>(D)) {
-      EntityInfo.templateKind = CXIdxEntity_TemplatePartialSpecialization;
-    } else if (isa<ClassTemplateSpecializationDecl>(D)) {
-      EntityInfo.templateKind = CXIdxEntity_TemplateSpecialization;
-    }
-
-  } else {
-    switch (D->getKind()) {
-    case Decl::Typedef:
-      EntityInfo.kind = CXIdxEntity_Typedef; break;
-    case Decl::Function:
-      EntityInfo.kind = CXIdxEntity_Function;
-      break;
-    case Decl::ParmVar:
-      EntityInfo.kind = CXIdxEntity_Variable;
-      break;
-    case Decl::Var:
-      EntityInfo.kind = CXIdxEntity_Variable;
-      if (isa<CXXRecordDecl>(D->getDeclContext())) {
-        EntityInfo.kind = CXIdxEntity_CXXStaticVariable;
-        EntityInfo.lang = CXIdxEntityLang_CXX;
-      }
-      break;
-    case Decl::Field:
-      EntityInfo.kind = CXIdxEntity_Field;
-      if (const CXXRecordDecl *
-            CXXRec = dyn_cast<CXXRecordDecl>(D->getDeclContext())) {
-        // FIXME: isPOD check is not sufficient, a POD can contain methods,
-        // we want a isCStructLike check.
-        if (!CXXRec->isPOD())
-          EntityInfo.lang = CXIdxEntityLang_CXX;
-      }
-      break;
-    case Decl::EnumConstant:
-      EntityInfo.kind = CXIdxEntity_EnumConstant; break;
-    case Decl::ObjCInterface:
-      EntityInfo.kind = CXIdxEntity_ObjCClass;
-      EntityInfo.lang = CXIdxEntityLang_ObjC;
-      break;
-    case Decl::ObjCProtocol:
-      EntityInfo.kind = CXIdxEntity_ObjCProtocol;
-      EntityInfo.lang = CXIdxEntityLang_ObjC;
-      break;
-    case Decl::ObjCCategory:
-      EntityInfo.kind = CXIdxEntity_ObjCCategory;
-      EntityInfo.lang = CXIdxEntityLang_ObjC;
-      break;
-    case Decl::ObjCMethod:
-      if (cast<ObjCMethodDecl>(D)->isInstanceMethod())
-        EntityInfo.kind = CXIdxEntity_ObjCInstanceMethod;
-      else
-        EntityInfo.kind = CXIdxEntity_ObjCClassMethod;
-      EntityInfo.lang = CXIdxEntityLang_ObjC;
-      break;
-    case Decl::ObjCProperty:
-      EntityInfo.kind = CXIdxEntity_ObjCProperty;
-      EntityInfo.lang = CXIdxEntityLang_ObjC;
-      break;
-    case Decl::ObjCIvar:
-      EntityInfo.kind = CXIdxEntity_ObjCIvar;
-      EntityInfo.lang = CXIdxEntityLang_ObjC;
-      break;
-    case Decl::Namespace:
-      EntityInfo.kind = CXIdxEntity_CXXNamespace;
-      EntityInfo.lang = CXIdxEntityLang_CXX;
-      break;
-    case Decl::NamespaceAlias:
-      EntityInfo.kind = CXIdxEntity_CXXNamespaceAlias;
-      EntityInfo.lang = CXIdxEntityLang_CXX;
-      break;
-    case Decl::CXXConstructor:
-      EntityInfo.kind = CXIdxEntity_CXXConstructor;
-      EntityInfo.lang = CXIdxEntityLang_CXX;
-      break;
-    case Decl::CXXDestructor:
-      EntityInfo.kind = CXIdxEntity_CXXDestructor;
-      EntityInfo.lang = CXIdxEntityLang_CXX;
-      break;
-    case Decl::CXXConversion:
-      EntityInfo.kind = CXIdxEntity_CXXConversionFunction;
-      EntityInfo.lang = CXIdxEntityLang_CXX;
-      break;
-    case Decl::CXXMethod: {
-      const CXXMethodDecl *MD = cast<CXXMethodDecl>(D);
-      if (MD->isStatic())
-        EntityInfo.kind = CXIdxEntity_CXXStaticMethod;
-      else
-        EntityInfo.kind = CXIdxEntity_CXXInstanceMethod;
-      EntityInfo.lang = CXIdxEntityLang_CXX;
-      break;
-    }
-    case Decl::ClassTemplate:
-      EntityInfo.kind = CXIdxEntity_CXXClass;
-      EntityInfo.templateKind = CXIdxEntity_Template;
-      break;
-    case Decl::FunctionTemplate:
-      EntityInfo.kind = CXIdxEntity_Function;
-      EntityInfo.templateKind = CXIdxEntity_Template;
-      if (const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(
-                           cast<FunctionTemplateDecl>(D)->getTemplatedDecl())) {
-        if (isa<CXXConstructorDecl>(MD))
-          EntityInfo.kind = CXIdxEntity_CXXConstructor;
-        else if (isa<CXXDestructorDecl>(MD))
-          EntityInfo.kind = CXIdxEntity_CXXDestructor;
-        else if (isa<CXXConversionDecl>(MD))
-          EntityInfo.kind = CXIdxEntity_CXXConversionFunction;
-        else {
-          if (MD->isStatic())
-            EntityInfo.kind = CXIdxEntity_CXXStaticMethod;
-          else
-            EntityInfo.kind = CXIdxEntity_CXXInstanceMethod;
-        }
-      }
-      break;
-    case Decl::TypeAliasTemplate:
-      EntityInfo.kind = CXIdxEntity_CXXTypeAlias;
-      EntityInfo.templateKind = CXIdxEntity_Template;
-      break;
-    case Decl::TypeAlias:
-      EntityInfo.kind = CXIdxEntity_CXXTypeAlias;
-      EntityInfo.lang = CXIdxEntityLang_CXX;
-      break;
-    default:
-      break;
-    }
-  }
-
   if (EntityInfo.kind == CXIdxEntity_Unexposed)
     return;
 
-  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
-    if (FD->getTemplatedKind() ==
-          FunctionDecl::TK_FunctionTemplateSpecialization)
-      EntityInfo.templateKind = CXIdxEntity_TemplateSpecialization;
-  }
-
-  if (EntityInfo.templateKind != CXIdxEntity_NonTemplate)
-    EntityInfo.lang = CXIdxEntityLang_CXX;
-
   if (IdentifierInfo *II = D->getIdentifier()) {
     EntityInfo.name = SA.toCStr(II->getName());
 
@@ -1119,14 +1175,14 @@
   }
 }
 
-void IndexingContext::getContainerInfo(const DeclContext *DC,
+void CXIndexDataConsumer::getContainerInfo(const DeclContext *DC,
                                        ContainerInfo &ContInfo) {
   ContInfo.cursor = getCursor(cast<Decl>(DC));
   ContInfo.DC = DC;
   ContInfo.IndexCtx = this;
 }
 
-CXCursor IndexingContext::getRefCursor(const NamedDecl *D, SourceLocation Loc) {
+CXCursor CXIndexDataConsumer::getRefCursor(const NamedDecl *D, SourceLocation Loc) {
   if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
     return MakeCursorTypeRef(TD, Loc, CXTU);
   if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
@@ -1147,7 +1203,7 @@
   return clang_getNullCursor();
 }
 
-bool IndexingContext::shouldIgnoreIfImplicit(const Decl *D) {
+bool CXIndexDataConsumer::shouldIgnoreIfImplicit(const Decl *D) {
   if (isa<ObjCInterfaceDecl>(D))
     return false;
   if (isa<ObjCCategoryDecl>(D))
@@ -1161,7 +1217,7 @@
   return true;
 }
 
-bool IndexingContext::isTemplateImplicitInstantiation(const Decl *D) {
+bool CXIndexDataConsumer::isTemplateImplicitInstantiation(const Decl *D) {
   if (const ClassTemplateSpecializationDecl *
         SD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
     return SD->getSpecializationKind() == TSK_ImplicitInstantiation;
@@ -1171,3 +1227,60 @@
   }
   return false;
 }
+
+static CXIdxEntityKind getEntityKindFromSymbolKind(SymbolKind K) {
+  switch (K) {
+  case SymbolKind::Unknown:
+  case SymbolKind::Module:
+  case SymbolKind::Macro:
+    return CXIdxEntity_Unexposed;
+
+  case SymbolKind::Enum: return CXIdxEntity_Enum;
+  case SymbolKind::Struct: return CXIdxEntity_Struct;
+  case SymbolKind::Union: return CXIdxEntity_Union;
+  case SymbolKind::Typedef: return CXIdxEntity_Typedef;
+  case SymbolKind::Function: return CXIdxEntity_Function;
+  case SymbolKind::Variable: return CXIdxEntity_Variable;
+  case SymbolKind::Field: return CXIdxEntity_Field;
+  case SymbolKind::EnumConstant: return CXIdxEntity_EnumConstant;
+  case SymbolKind::ObjCClass: return CXIdxEntity_ObjCClass;
+  case SymbolKind::ObjCProtocol: return CXIdxEntity_ObjCProtocol;
+  case SymbolKind::ObjCCategory: return CXIdxEntity_ObjCCategory;
+  case SymbolKind::ObjCInstanceMethod: return CXIdxEntity_ObjCInstanceMethod;
+  case SymbolKind::ObjCClassMethod: return CXIdxEntity_ObjCClassMethod;
+  case SymbolKind::ObjCProperty: return CXIdxEntity_ObjCProperty;
+  case SymbolKind::ObjCIvar: return CXIdxEntity_ObjCIvar;
+  case SymbolKind::CXXClass: return CXIdxEntity_CXXClass;
+  case SymbolKind::CXXNamespace: return CXIdxEntity_CXXNamespace;
+  case SymbolKind::CXXNamespaceAlias: return CXIdxEntity_CXXNamespaceAlias;
+  case SymbolKind::CXXStaticVariable: return CXIdxEntity_CXXStaticVariable;
+  case SymbolKind::CXXStaticMethod: return CXIdxEntity_CXXStaticMethod;
+  case SymbolKind::CXXInstanceMethod: return CXIdxEntity_CXXInstanceMethod;
+  case SymbolKind::CXXConstructor: return CXIdxEntity_CXXConstructor;
+  case SymbolKind::CXXDestructor: return CXIdxEntity_CXXDestructor;
+  case SymbolKind::CXXConversionFunction:
+    return CXIdxEntity_CXXConversionFunction;
+  case SymbolKind::CXXTypeAlias: return CXIdxEntity_CXXTypeAlias;
+  case SymbolKind::CXXInterface: return CXIdxEntity_CXXInterface;
+  }
+}
+
+static CXIdxEntityCXXTemplateKind
+getEntityKindFromSymbolCXXTemplateKind(SymbolCXXTemplateKind K) {
+  switch (K) {
+  case SymbolCXXTemplateKind::NonTemplate: return CXIdxEntity_NonTemplate;
+  case SymbolCXXTemplateKind::Template: return CXIdxEntity_Template;
+  case SymbolCXXTemplateKind::TemplatePartialSpecialization:
+    return CXIdxEntity_TemplatePartialSpecialization;
+  case SymbolCXXTemplateKind::TemplateSpecialization:
+    return CXIdxEntity_TemplateSpecialization;
+  }
+}
+
+static CXIdxEntityLanguage getEntityLangFromSymbolLang(SymbolLanguage L) {
+  switch (L) {
+  case SymbolLanguage::C: return CXIdxEntityLang_C;
+  case SymbolLanguage::ObjC: return CXIdxEntityLang_ObjC;
+  case SymbolLanguage::CXX: return CXIdxEntityLang_CXX;
+  }
+}
diff --git a/clang/tools/libclang/IndexingContext.h b/clang/tools/libclang/CXIndexDataConsumer.h
similarity index 90%
rename from clang/tools/libclang/IndexingContext.h
rename to clang/tools/libclang/CXIndexDataConsumer.h
index d1d62c9..308fa79 100644
--- a/clang/tools/libclang/IndexingContext.h
+++ b/clang/tools/libclang/CXIndexDataConsumer.h
@@ -1,4 +1,4 @@
-//===- IndexingContext.h - Higher level API functions -----------*- C++ -*-===//
+//===- CXIndexDataConsumer.h - Index data consumer for libclang--*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -7,11 +7,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_CLANG_TOOLS_LIBCLANG_INDEXINGCONTEXT_H
-#define LLVM_CLANG_TOOLS_LIBCLANG_INDEXINGCONTEXT_H
+#ifndef LLVM_CLANG_TOOLS_LIBCLANG_CXINDEXDATACONSUMER_H
+#define LLVM_CLANG_TOOLS_LIBCLANG_CXINDEXDATACONSUMER_H
 
 #include "CXCursor.h"
 #include "Index_Internal.h"
+#include "clang/Index/IndexDataConsumer.h"
 #include "clang/AST/DeclGroup.h"
 #include "clang/AST/DeclObjC.h"
 #include "llvm/ADT/DenseSet.h"
@@ -27,14 +28,14 @@
   class ClassTemplateSpecializationDecl;
 
 namespace cxindex {
-  class IndexingContext;
+  class CXIndexDataConsumer;
   class AttrListInfo;
 
 class ScratchAlloc {
-  IndexingContext &IdxCtx;
+  CXIndexDataConsumer &IdxCtx;
 
 public:
-  explicit ScratchAlloc(IndexingContext &indexCtx);
+  explicit ScratchAlloc(CXIndexDataConsumer &indexCtx);
   ScratchAlloc(const ScratchAlloc &SA);
 
   ~ScratchAlloc();
@@ -48,7 +49,7 @@
 
 struct EntityInfo : public CXIdxEntityInfo {
   const NamedDecl *Dcl;
-  IndexingContext *IndexCtx;
+  CXIndexDataConsumer *IndexCtx;
   IntrusiveRefCntPtr<AttrListInfo> AttrList;
 
   EntityInfo() {
@@ -60,7 +61,7 @@
 
 struct ContainerInfo : public CXIdxContainerInfo {
   const DeclContext *DC;
-  IndexingContext *IndexCtx;
+  CXIndexDataConsumer *IndexCtx;
 };
   
 struct DeclInfo : public CXIdxDeclInfo {
@@ -248,10 +249,10 @@
   AttrListInfo(const AttrListInfo &) = delete;
   void operator=(const AttrListInfo &) = delete;
 public:
-  AttrListInfo(const Decl *D, IndexingContext &IdxCtx);
+  AttrListInfo(const Decl *D, CXIndexDataConsumer &IdxCtx);
 
   static IntrusiveRefCntPtr<AttrListInfo> create(const Decl *D,
-                                                 IndexingContext &IdxCtx);
+                                                 CXIndexDataConsumer &IdxCtx);
 
   const CXIdxAttrInfo *const *getAttrs() const {
     if (CXAttrs.empty())
@@ -273,7 +274,7 @@
   }
 };
 
-class IndexingContext {
+class CXIndexDataConsumer : public index::IndexDataConsumer {
   ASTContext *Ctx;
   CXClientData ClientData;
   IndexerCallbacks &CB;
@@ -308,7 +309,7 @@
     }
 
     ObjCProtocolListInfo(const ObjCProtocolList &ProtList,
-                         IndexingContext &IdxCtx,
+                         CXIndexDataConsumer &IdxCtx,
                          ScratchAlloc &SA);
   };
 
@@ -323,7 +324,7 @@
     unsigned getNumBases() const { return (unsigned)CXBases.size(); }
 
     CXXBasesListInfo(const CXXRecordDecl *D,
-                     IndexingContext &IdxCtx, ScratchAlloc &SA);
+                     CXIndexDataConsumer &IdxCtx, ScratchAlloc &SA);
 
   private:
     SourceLocation getBaseLoc(const CXXBaseSpecifier &Base) const;
@@ -332,13 +333,14 @@
   friend class AttrListInfo;
 
 public:
-  IndexingContext(CXClientData clientData, IndexerCallbacks &indexCallbacks,
+  CXIndexDataConsumer(CXClientData clientData, IndexerCallbacks &indexCallbacks,
                   unsigned indexOptions, CXTranslationUnit cxTU)
     : Ctx(nullptr), ClientData(clientData), CB(indexCallbacks),
       IndexOptions(indexOptions), CXTU(cxTU),
       StrScratch(), StrAdapterCount(0) { }
 
   ASTContext &getASTContext() const { return *Ctx; }
+  CXTranslationUnit getCXTU() const { return CXTU; }
 
   void setASTContext(ASTContext &ctx);
   void setPreprocessor(Preprocessor &PP);
@@ -391,6 +393,8 @@
   void indexBody(const Stmt *S, const NamedDecl *Parent,
                  const DeclContext *DC = nullptr);
 
+  void indexDiagnostics();
+
   void handleDiagnosticSet(CXDiagnosticSet CXDiagSet);
 
   bool handleFunction(const FunctionDecl *FD);
@@ -458,6 +462,17 @@
   static bool isTemplateImplicitInstantiation(const Decl *D);
 
 private:
+  bool handleDeclOccurence(const Decl *D, index::SymbolRoleSet Roles,
+                           ArrayRef<index::SymbolRelation> Relations,
+                           FileID FID, unsigned Offset,
+                           ASTNodeInfo ASTNode) override;
+
+  bool handleModuleOccurence(const ImportDecl *ImportD,
+                             index::SymbolRoleSet Roles,
+                             FileID FID, unsigned Offset) override;
+
+  void finish() override;
+
   bool handleDecl(const NamedDecl *D,
                   SourceLocation Loc, CXCursor Cursor,
                   DeclInfo &DInfo,
@@ -495,7 +510,7 @@
   static bool shouldIgnoreIfImplicit(const Decl *D);
 };
 
-inline ScratchAlloc::ScratchAlloc(IndexingContext &idxCtx) : IdxCtx(idxCtx) {
+inline ScratchAlloc::ScratchAlloc(CXIndexDataConsumer &idxCtx) : IdxCtx(idxCtx) {
   ++IdxCtx.StrAdapterCount;
 }
 inline ScratchAlloc::ScratchAlloc(const ScratchAlloc &SA) : IdxCtx(SA.IdxCtx) {
diff --git a/clang/tools/libclang/IndexBody.cpp b/clang/tools/libclang/IndexBody.cpp
deleted file mode 100644
index 58dc117..0000000
--- a/clang/tools/libclang/IndexBody.cpp
+++ /dev/null
@@ -1,224 +0,0 @@
-//===- CIndexHigh.cpp - Higher level API functions ------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "IndexingContext.h"
-#include "clang/AST/RecursiveASTVisitor.h"
-
-using namespace clang;
-using namespace cxindex;
-
-namespace {
-
-class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> {
-  IndexingContext &IndexCtx;
-  const NamedDecl *Parent;
-  const DeclContext *ParentDC;
-
-  typedef RecursiveASTVisitor<BodyIndexer> base;
-public:
-  BodyIndexer(IndexingContext &indexCtx,
-              const NamedDecl *Parent, const DeclContext *DC)
-    : IndexCtx(indexCtx), Parent(Parent), ParentDC(DC) { }
-  
-  bool shouldWalkTypesOfTypeLocs() const { return false; }
-
-  bool TraverseTypeLoc(TypeLoc TL) {
-    IndexCtx.indexTypeLoc(TL, Parent, ParentDC);
-    return true;
-  }
-
-  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
-    IndexCtx.indexNestedNameSpecifierLoc(NNS, Parent, ParentDC);
-    return true;
-  }
-
-  bool VisitDeclRefExpr(DeclRefExpr *E) {
-    IndexCtx.handleReference(E->getDecl(), E->getLocation(),
-                             Parent, ParentDC, E);
-    return true;
-  }
-
-  bool VisitMemberExpr(MemberExpr *E) {
-    IndexCtx.handleReference(E->getMemberDecl(), E->getMemberLoc(),
-                             Parent, ParentDC, E);
-    return true;
-  }
-
-  bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
-    IndexCtx.handleReference(E->getDecl(), E->getLocation(),
-                             Parent, ParentDC, E);
-    return true;
-  }
-
-  bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
-    if (ObjCMethodDecl *MD = E->getMethodDecl())
-      IndexCtx.handleReference(MD, E->getSelectorStartLoc(),
-                               Parent, ParentDC, E,
-                               E->isImplicit() ? CXIdxEntityRef_Implicit
-                                               : CXIdxEntityRef_Direct);
-    return true;
-  }
-
-  bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
-    if (E->isExplicitProperty())
-      IndexCtx.handleReference(E->getExplicitProperty(), E->getLocation(),
-                               Parent, ParentDC, E);
-
-    // No need to do a handleReference for the objc method, because there will
-    // be a message expr as part of PseudoObjectExpr.
-    return true;
-  }
-
-  bool VisitMSPropertyRefExpr(MSPropertyRefExpr *E) {
-    IndexCtx.handleReference(E->getPropertyDecl(), E->getMemberLoc(), Parent,
-                             ParentDC, E, CXIdxEntityRef_Direct);
-    return true;
-  }
-
-  bool VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
-    IndexCtx.handleReference(E->getProtocol(), E->getProtocolIdLoc(),
-                             Parent, ParentDC, E, CXIdxEntityRef_Direct);
-    return true;
-  }
-
-  bool VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
-    if (ObjCMethodDecl *MD = E->getBoxingMethod())
-      IndexCtx.handleReference(MD, E->getLocStart(),
-                               Parent, ParentDC, E, CXIdxEntityRef_Implicit);
-    return true;
-  }
-  
-  bool VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
-    if (ObjCMethodDecl *MD = E->getDictWithObjectsMethod())
-      IndexCtx.handleReference(MD, E->getLocStart(),
-                               Parent, ParentDC, E, CXIdxEntityRef_Implicit);
-    return true;
-  }
-
-  bool VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
-    if (ObjCMethodDecl *MD = E->getArrayWithObjectsMethod())
-      IndexCtx.handleReference(MD, E->getLocStart(),
-                               Parent, ParentDC, E, CXIdxEntityRef_Implicit);
-    return true;
-  }
-
-  bool VisitCXXConstructExpr(CXXConstructExpr *E) {
-    IndexCtx.handleReference(E->getConstructor(), E->getLocation(),
-                             Parent, ParentDC, E);
-    return true;
-  }
-
-  bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *E,
-                                   DataRecursionQueue *Q = nullptr) {
-    if (E->getOperatorLoc().isInvalid())
-      return true; // implicit.
-    return base::TraverseCXXOperatorCallExpr(E, Q);
-  }
-
-  bool VisitDeclStmt(DeclStmt *S) {
-    if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
-      IndexCtx.indexDeclGroupRef(S->getDeclGroup());
-      return true;
-    }
-
-    DeclGroupRef DG = S->getDeclGroup();
-    for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) {
-      const Decl *D = *I;
-      if (!D)
-        continue;
-      if (!IndexCtx.isFunctionLocalDecl(D))
-        IndexCtx.indexTopLevelDecl(D);
-    }
-
-    return true;
-  }
-
-  bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C) {
-    if (C->capturesThis() || C->capturesVLAType())
-      return true;
-
-    if (C->capturesVariable() && IndexCtx.shouldIndexFunctionLocalSymbols())
-      IndexCtx.handleReference(C->getCapturedVar(), C->getLocation(), Parent,
-                               ParentDC);
-
-    // FIXME: Lambda init-captures.
-    return true;
-  }
-
-  // RecursiveASTVisitor visits both syntactic and semantic forms, duplicating
-  // the things that we visit. Make sure to only visit the semantic form.
-  // Also visit things that are in the syntactic form but not the semantic one,
-  // for example the indices in DesignatedInitExprs.
-  bool TraverseInitListExpr(InitListExpr *S) {
-
-    class SyntacticFormIndexer :
-              public RecursiveASTVisitor<SyntacticFormIndexer> {
-      IndexingContext &IndexCtx;
-      const NamedDecl *Parent;
-      const DeclContext *ParentDC;
-
-    public:
-      SyntacticFormIndexer(IndexingContext &indexCtx,
-                            const NamedDecl *Parent, const DeclContext *DC)
-        : IndexCtx(indexCtx), Parent(Parent), ParentDC(DC) { }
-
-      bool shouldWalkTypesOfTypeLocs() const { return false; }
-
-      bool VisitDesignatedInitExpr(DesignatedInitExpr *E) {
-        for (DesignatedInitExpr::reverse_designators_iterator
-               D = E->designators_rbegin(), DEnd = E->designators_rend();
-               D != DEnd; ++D) {
-          if (D->isFieldDesignator())
-            IndexCtx.handleReference(D->getField(), D->getFieldLoc(),
-                                     Parent, ParentDC, E);
-        }
-        return true;
-      }
-    };
-
-    auto visitForm = [&](InitListExpr *Form) {
-      for (Stmt *SubStmt : Form->children()) {
-        if (!TraverseStmt(SubStmt))
-          return false;
-      }
-      return true;
-    };
-
-    InitListExpr *SemaForm = S->isSemanticForm() ? S : S->getSemanticForm();
-    InitListExpr *SyntaxForm = S->isSemanticForm() ? S->getSyntacticForm() : S;
-
-    if (SemaForm) {
-      // Visit things present in syntactic form but not the semantic form.
-      if (SyntaxForm) {
-        SyntacticFormIndexer(IndexCtx, Parent, ParentDC).TraverseStmt(SyntaxForm);
-      }
-      return visitForm(SemaForm);
-    }
-
-    // No semantic, try the syntactic.
-    if (SyntaxForm) {
-      return visitForm(SyntaxForm);
-    }
-
-    return true;
-  }
-
-};
-
-} // anonymous namespace
-
-void IndexingContext::indexBody(const Stmt *S, const NamedDecl *Parent,
-                                const DeclContext *DC) {
-  if (!S)
-    return;
-
-  if (!DC)
-    DC = Parent->getLexicalDeclContext();
-  BodyIndexer(*this, Parent, DC).TraverseStmt(const_cast<Stmt*>(S));
-}
diff --git a/clang/tools/libclang/IndexDecl.cpp b/clang/tools/libclang/IndexDecl.cpp
deleted file mode 100644
index aa97129..0000000
--- a/clang/tools/libclang/IndexDecl.cpp
+++ /dev/null
@@ -1,341 +0,0 @@
-//===- CIndexHigh.cpp - Higher level API functions ------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "IndexingContext.h"
-#include "clang/AST/DeclVisitor.h"
-
-using namespace clang;
-using namespace cxindex;
-
-namespace {
-
-class IndexingDeclVisitor : public ConstDeclVisitor<IndexingDeclVisitor, bool> {
-  IndexingContext &IndexCtx;
-
-public:
-  explicit IndexingDeclVisitor(IndexingContext &indexCtx)
-    : IndexCtx(indexCtx) { }
-
-  /// \brief Returns true if the given method has been defined explicitly by the
-  /// user.
-  static bool hasUserDefined(const ObjCMethodDecl *D,
-                             const ObjCImplDecl *Container) {
-    const ObjCMethodDecl *MD = Container->getMethod(D->getSelector(),
-                                                    D->isInstanceMethod());
-    return MD && !MD->isImplicit() && MD->isThisDeclarationADefinition();
-  }
-
-  void handleDeclarator(const DeclaratorDecl *D,
-                        const NamedDecl *Parent = nullptr) {
-    if (!Parent) Parent = D;
-
-    if (!IndexCtx.shouldIndexFunctionLocalSymbols()) {
-      IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), Parent);
-      IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent);
-    } else {
-      if (const ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) {
-        IndexCtx.handleVar(Parm);
-      } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
-        for (auto PI : FD->params()) {
-          IndexCtx.handleVar(PI);
-        }
-      }
-    }
-  }
-
-  void handleObjCMethod(const ObjCMethodDecl *D) {
-    IndexCtx.handleObjCMethod(D);
-    if (D->isImplicit())
-      return;
-
-    IndexCtx.indexTypeSourceInfo(D->getReturnTypeSourceInfo(), D);
-    for (const auto *I : D->params())
-      handleDeclarator(I, D);
-
-    if (D->isThisDeclarationADefinition()) {
-      const Stmt *Body = D->getBody();
-      if (Body) {
-        IndexCtx.indexBody(Body, D, D);
-      }
-    }
-  }
-
-  bool VisitFunctionDecl(const FunctionDecl *D) {
-    IndexCtx.handleFunction(D);
-    handleDeclarator(D);
-
-    if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
-      // Constructor initializers.
-      for (const auto *Init : Ctor->inits()) {
-        if (Init->isWritten()) {
-          IndexCtx.indexTypeSourceInfo(Init->getTypeSourceInfo(), D);
-          if (const FieldDecl *Member = Init->getAnyMember())
-            IndexCtx.handleReference(Member, Init->getMemberLocation(), D, D);
-          IndexCtx.indexBody(Init->getInit(), D, D);
-        }
-      }
-    }
-
-    if (D->isThisDeclarationADefinition()) {
-      const Stmt *Body = D->getBody();
-      if (Body) {
-        IndexCtx.indexBody(Body, D, D);
-      }
-    }
-    return true;
-  }
-
-  bool VisitVarDecl(const VarDecl *D) {
-    IndexCtx.handleVar(D);
-    handleDeclarator(D);
-    IndexCtx.indexBody(D->getInit(), D);
-    return true;
-  }
-
-  bool VisitFieldDecl(const FieldDecl *D) {
-    IndexCtx.handleField(D);
-    handleDeclarator(D);
-    if (D->isBitField())
-      IndexCtx.indexBody(D->getBitWidth(), D);
-    else if (D->hasInClassInitializer())
-      IndexCtx.indexBody(D->getInClassInitializer(), D);
-    return true;
-  }
-
-  bool VisitMSPropertyDecl(const MSPropertyDecl *D) {
-    handleDeclarator(D);
-    return true;
-  }
-
-  bool VisitEnumConstantDecl(const EnumConstantDecl *D) {
-    IndexCtx.handleEnumerator(D);
-    IndexCtx.indexBody(D->getInitExpr(), D);
-    return true;
-  }
-
-  bool VisitTypedefNameDecl(const TypedefNameDecl *D) {
-    IndexCtx.handleTypedefName(D);
-    IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
-    return true;
-  }
-
-  bool VisitTagDecl(const TagDecl *D) {
-    // Non-free standing tags are handled in indexTypeSourceInfo.
-    if (D->isFreeStanding())
-      IndexCtx.indexTagDecl(D);
-    return true;
-  }
-
-  bool VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
-    IndexCtx.handleObjCInterface(D);
-
-    if (D->isThisDeclarationADefinition()) {
-      IndexCtx.indexDeclContext(D);
-    }
-    return true;
-  }
-
-  bool VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
-    IndexCtx.handleObjCProtocol(D);
-
-    if (D->isThisDeclarationADefinition()) {
-      IndexCtx.indexDeclContext(D);
-    }
-    return true;
-  }
-
-  bool VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
-    const ObjCInterfaceDecl *Class = D->getClassInterface();
-    if (!Class)
-      return true;
-
-    if (Class->isImplicitInterfaceDecl())
-      IndexCtx.handleObjCInterface(Class);
-
-    IndexCtx.handleObjCImplementation(D);
-
-    // Index the ivars first to make sure the synthesized ivars are indexed
-    // before indexing the methods that can reference them.
-    for (const auto *IvarI : D->ivars())
-      IndexCtx.indexDecl(IvarI);
-    for (const auto *I : D->decls()) {
-      if (!isa<ObjCIvarDecl>(I))
-        IndexCtx.indexDecl(I);
-    }
-
-    return true;
-  }
-
-  bool VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
-    IndexCtx.handleObjCCategory(D);
-    IndexCtx.indexDeclContext(D);
-    return true;
-  }
-
-  bool VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
-    const ObjCCategoryDecl *Cat = D->getCategoryDecl();
-    if (!Cat)
-      return true;
-
-    IndexCtx.handleObjCCategoryImpl(D);
-    IndexCtx.indexDeclContext(D);
-    return true;
-  }
-
-  bool VisitObjCMethodDecl(const ObjCMethodDecl *D) {
-    // Methods associated with a property, even user-declared ones, are
-    // handled when we handle the property.
-    if (D->isPropertyAccessor())
-      return true;
-
-    handleObjCMethod(D);
-    return true;
-  }
-
-  bool VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
-    if (ObjCMethodDecl *MD = D->getGetterMethodDecl())
-      if (MD->getLexicalDeclContext() == D->getLexicalDeclContext())
-        handleObjCMethod(MD);
-    if (ObjCMethodDecl *MD = D->getSetterMethodDecl())
-      if (MD->getLexicalDeclContext() == D->getLexicalDeclContext())
-        handleObjCMethod(MD);
-    IndexCtx.handleObjCProperty(D);
-    IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
-    return true;
-  }
-
-  bool VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
-    ObjCPropertyDecl *PD = D->getPropertyDecl();
-    IndexCtx.handleSynthesizedObjCProperty(D);
-
-    if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
-      return true;
-    assert(D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize);
-    
-    if (ObjCIvarDecl *IvarD = D->getPropertyIvarDecl()) {
-      if (!IvarD->getSynthesize())
-        IndexCtx.handleReference(IvarD, D->getPropertyIvarDeclLoc(), nullptr,
-                                 D->getDeclContext());
-    }
-
-    if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) {
-      if (MD->isPropertyAccessor() &&
-          !hasUserDefined(MD, cast<ObjCImplDecl>(D->getDeclContext())))
-        IndexCtx.handleSynthesizedObjCMethod(MD, D->getLocation(),
-                                             D->getLexicalDeclContext());
-    }
-    if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) {
-      if (MD->isPropertyAccessor() &&
-          !hasUserDefined(MD, cast<ObjCImplDecl>(D->getDeclContext())))
-        IndexCtx.handleSynthesizedObjCMethod(MD, D->getLocation(),
-                                             D->getLexicalDeclContext());
-    }
-    return true;
-  }
-
-  bool VisitNamespaceDecl(const NamespaceDecl *D) {
-    IndexCtx.handleNamespace(D);
-    IndexCtx.indexDeclContext(D);
-    return true;
-  }
-
-  bool VisitUsingDecl(const UsingDecl *D) {
-    // FIXME: Parent for the following is CXIdxEntity_Unexposed with no USR,
-    // we should do better.
-
-    IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), D);
-    for (const auto *I : D->shadows())
-      IndexCtx.handleReference(I->getUnderlyingDecl(), D->getLocation(), D,
-                               D->getLexicalDeclContext());
-    return true;
-  }
-
-  bool VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
-    // FIXME: Parent for the following is CXIdxEntity_Unexposed with no USR,
-    // we should do better.
-
-    IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), D);
-    IndexCtx.handleReference(D->getNominatedNamespaceAsWritten(),
-                             D->getLocation(), D, D->getLexicalDeclContext());
-    return true;
-  }
-
-  bool VisitClassTemplateDecl(const ClassTemplateDecl *D) {
-    IndexCtx.handleClassTemplate(D);
-    if (D->isThisDeclarationADefinition())
-      IndexCtx.indexDeclContext(D->getTemplatedDecl());
-    return true;
-  }
-
-  bool VisitClassTemplateSpecializationDecl(const
-                                           ClassTemplateSpecializationDecl *D) {
-    // FIXME: Notify subsequent callbacks if info comes from implicit
-    // instantiation.
-    if (D->isThisDeclarationADefinition() &&
-        (IndexCtx.shouldIndexImplicitTemplateInsts() ||
-         !IndexCtx.isTemplateImplicitInstantiation(D)))
-      IndexCtx.indexTagDecl(D);
-    return true;
-  }
-
-  bool VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
-    IndexCtx.handleFunctionTemplate(D);
-    FunctionDecl *FD = D->getTemplatedDecl();
-    handleDeclarator(FD, D);
-    if (FD->isThisDeclarationADefinition()) {
-      const Stmt *Body = FD->getBody();
-      if (Body) {
-        IndexCtx.indexBody(Body, D, FD);
-      }
-    }
-    return true;
-  }
-
-  bool VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) {
-    IndexCtx.handleTypeAliasTemplate(D);
-    IndexCtx.indexTypeSourceInfo(D->getTemplatedDecl()->getTypeSourceInfo(), D);
-    return true;
-  }
-
-  bool VisitImportDecl(const ImportDecl *D) {
-    IndexCtx.importedModule(D);
-    return true;
-  }
-};
-
-} // anonymous namespace
-
-void IndexingContext::indexDecl(const Decl *D) {
-  if (D->isImplicit() && shouldIgnoreIfImplicit(D))
-    return;
-
-  bool Handled = IndexingDeclVisitor(*this).Visit(D);
-  if (!Handled && isa<DeclContext>(D))
-    indexDeclContext(cast<DeclContext>(D));
-}
-
-void IndexingContext::indexDeclContext(const DeclContext *DC) {
-  for (const auto *I : DC->decls())
-    indexDecl(I);
-}
-
-void IndexingContext::indexTopLevelDecl(const Decl *D) {
-  if (isNotFromSourceFile(D->getLocation()))
-    return;
-
-  if (isa<ObjCMethodDecl>(D))
-    return; // Wait for the objc container.
-
-  indexDecl(D);
-}
-
-void IndexingContext::indexDeclGroupRef(DeclGroupRef DG) {
-  for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
-    indexTopLevelDecl(*I);
-}
diff --git a/clang/tools/libclang/IndexTypeSourceInfo.cpp b/clang/tools/libclang/IndexTypeSourceInfo.cpp
deleted file mode 100644
index 9666052..0000000
--- a/clang/tools/libclang/IndexTypeSourceInfo.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-//===- CIndexHigh.cpp - Higher level API functions ------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "IndexingContext.h"
-#include "clang/AST/RecursiveASTVisitor.h"
-
-using namespace clang;
-using namespace cxindex;
-
-namespace {
-
-class TypeIndexer : public RecursiveASTVisitor<TypeIndexer> {
-  IndexingContext &IndexCtx;
-  const NamedDecl *Parent;
-  const DeclContext *ParentDC;
-
-public:
-  TypeIndexer(IndexingContext &indexCtx, const NamedDecl *parent,
-              const DeclContext *DC)
-    : IndexCtx(indexCtx), Parent(parent), ParentDC(DC) { }
-  
-  bool shouldWalkTypesOfTypeLocs() const { return false; }
-
-  bool VisitTypedefTypeLoc(TypedefTypeLoc TL) {
-    IndexCtx.handleReference(TL.getTypedefNameDecl(), TL.getNameLoc(),
-                             Parent, ParentDC);
-    return true;
-  }
-
-  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
-    IndexCtx.indexNestedNameSpecifierLoc(NNS, Parent, ParentDC);
-    return true;
-  }
-
-  bool VisitTagTypeLoc(TagTypeLoc TL) {
-    TagDecl *D = TL.getDecl();
-    if (D->getParentFunctionOrMethod())
-      return true;
-
-    if (TL.isDefinition()) {
-      IndexCtx.indexTagDecl(D);
-      return true;
-    }
-
-    if (D->getLocation() == TL.getNameLoc())
-      IndexCtx.handleTagDecl(D);
-    else
-      IndexCtx.handleReference(D, TL.getNameLoc(),
-                               Parent, ParentDC);
-    return true;
-  }
-
-  bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
-    IndexCtx.handleReference(TL.getIFaceDecl(), TL.getNameLoc(),
-                             Parent, ParentDC);
-    return true;
-  }
-
-  bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
-    for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i) {
-      IndexCtx.handleReference(TL.getProtocol(i), TL.getProtocolLoc(i),
-                               Parent, ParentDC);
-    }
-    return true;
-  }
-
-  bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) {
-    if (const TemplateSpecializationType *T = TL.getTypePtr()) {
-      if (IndexCtx.shouldIndexImplicitTemplateInsts()) {
-        if (CXXRecordDecl *RD = T->getAsCXXRecordDecl())
-          IndexCtx.handleReference(RD, TL.getTemplateNameLoc(),
-                                   Parent, ParentDC);
-      } else {
-        if (const TemplateDecl *D = T->getTemplateName().getAsTemplateDecl())
-          IndexCtx.handleReference(D, TL.getTemplateNameLoc(),
-                                   Parent, ParentDC);
-      }
-    }
-    return true;
-  }
-
-  bool TraverseStmt(Stmt *S) {
-    IndexCtx.indexBody(S, Parent, ParentDC);
-    return true;
-  }
-};
-
-} // anonymous namespace
-
-void IndexingContext::indexTypeSourceInfo(TypeSourceInfo *TInfo,
-                                          const NamedDecl *Parent,
-                                          const DeclContext *DC) {
-  if (!TInfo || TInfo->getTypeLoc().isNull())
-    return;
-  
-  indexTypeLoc(TInfo->getTypeLoc(), Parent, DC);
-}
-
-void IndexingContext::indexTypeLoc(TypeLoc TL,
-                                   const NamedDecl *Parent,
-                                   const DeclContext *DC) {
-  if (TL.isNull())
-    return;
-
-  if (!DC)
-    DC = Parent->getLexicalDeclContext();
-  TypeIndexer(*this, Parent, DC).TraverseTypeLoc(TL);
-}
-
-void IndexingContext::indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
-                                                  const NamedDecl *Parent,
-                                                  const DeclContext *DC) {
-  if (!NNS)
-    return;
-
-  if (NestedNameSpecifierLoc Prefix = NNS.getPrefix())
-    indexNestedNameSpecifierLoc(Prefix, Parent, DC);
-
-  if (!DC)
-    DC = Parent->getLexicalDeclContext();
-  SourceLocation Loc = NNS.getSourceRange().getBegin();
-
-  switch (NNS.getNestedNameSpecifier()->getKind()) {
-  case NestedNameSpecifier::Identifier:
-  case NestedNameSpecifier::Global:
-  case NestedNameSpecifier::Super:
-    break;
-
-  case NestedNameSpecifier::Namespace:
-    handleReference(NNS.getNestedNameSpecifier()->getAsNamespace(),
-                    Loc, Parent, DC);
-    break;
-  case NestedNameSpecifier::NamespaceAlias:
-    handleReference(NNS.getNestedNameSpecifier()->getAsNamespaceAlias(),
-                    Loc, Parent, DC);
-    break;
-
-  case NestedNameSpecifier::TypeSpec:
-  case NestedNameSpecifier::TypeSpecWithTemplate:
-    indexTypeLoc(NNS.getTypeLoc(), Parent, DC);
-    break;
-  }
-}
-
-void IndexingContext::indexTagDecl(const TagDecl *D) {
-  if (handleTagDecl(D)) {
-    if (D->isThisDeclarationADefinition())
-      indexDeclContext(D);
-  }
-}
diff --git a/clang/tools/libclang/Indexing.cpp b/clang/tools/libclang/Indexing.cpp
index 01f1b95..d901b53 100644
--- a/clang/tools/libclang/Indexing.cpp
+++ b/clang/tools/libclang/Indexing.cpp
@@ -7,7 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "IndexingContext.h"
+#include "CXIndexDataConsumer.h"
 #include "CIndexDiagnostic.h"
 #include "CIndexer.h"
 #include "CLog.h"
@@ -16,12 +16,12 @@
 #include "CXString.h"
 #include "CXTranslationUnit.h"
 #include "clang/AST/ASTConsumer.h"
-#include "clang/AST/DeclVisitor.h"
 #include "clang/Frontend/ASTUnit.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/CompilerInvocation.h"
 #include "clang/Frontend/FrontendAction.h"
 #include "clang/Frontend/Utils.h"
+#include "clang/Index/IndexingAction.h"
 #include "clang/Lex/HeaderSearch.h"
 #include "clang/Lex/PPCallbacks.h"
 #include "clang/Lex/PPConditionalDirectiveRecord.h"
@@ -34,11 +34,10 @@
 #include <cstdio>
 
 using namespace clang;
+using namespace clang::index;
 using namespace cxtu;
 using namespace cxindex;
 
-static void indexDiagnostics(CXTranslationUnit TU, IndexingContext &IdxCtx);
-
 namespace {
 
 //===----------------------------------------------------------------------===//
@@ -224,12 +223,12 @@
 
 class IndexPPCallbacks : public PPCallbacks {
   Preprocessor &PP;
-  IndexingContext &IndexCtx;
+  CXIndexDataConsumer &DataConsumer;
   bool IsMainFileEntered;
 
 public:
-  IndexPPCallbacks(Preprocessor &PP, IndexingContext &indexCtx)
-    : PP(PP), IndexCtx(indexCtx), IsMainFileEntered(false) { }
+  IndexPPCallbacks(Preprocessor &PP, CXIndexDataConsumer &dataConsumer)
+    : PP(PP), DataConsumer(dataConsumer), IsMainFileEntered(false) { }
 
   void FileChanged(SourceLocation Loc, FileChangeReason Reason,
                  SrcMgr::CharacteristicKind FileType, FileID PrevFID) override {
@@ -241,7 +240,7 @@
 
     if (Loc == MainFileLoc && Reason == PPCallbacks::EnterFile) {
       IsMainFileEntered = true;
-      IndexCtx.enteredMainFile(SM.getFileEntryForID(SM.getMainFileID()));
+      DataConsumer.enteredMainFile(SM.getFileEntryForID(SM.getMainFileID()));
     }
   }
 
@@ -252,7 +251,7 @@
                           const Module *Imported) override {
     bool isImport = (IncludeTok.is(tok::identifier) &&
             IncludeTok.getIdentifierInfo()->getPPKeywordID() == tok::pp_import);
-    IndexCtx.ppIncludedFile(HashLoc, FileName, File, isImport, IsAngled,
+    DataConsumer.ppIncludedFile(HashLoc, FileName, File, isImport, IsAngled,
                             Imported);
   }
 
@@ -279,18 +278,18 @@
 //===----------------------------------------------------------------------===//
 
 class IndexingConsumer : public ASTConsumer {
-  IndexingContext &IndexCtx;
+  CXIndexDataConsumer &DataConsumer;
   TUSkipBodyControl *SKCtrl;
 
 public:
-  IndexingConsumer(IndexingContext &indexCtx, TUSkipBodyControl *skCtrl)
-    : IndexCtx(indexCtx), SKCtrl(skCtrl) { }
+  IndexingConsumer(CXIndexDataConsumer &dataConsumer, TUSkipBodyControl *skCtrl)
+    : DataConsumer(dataConsumer), SKCtrl(skCtrl) { }
 
   // ASTConsumer Implementation
 
   void Initialize(ASTContext &Context) override {
-    IndexCtx.setASTContext(Context);
-    IndexCtx.startedTranslationUnit();
+    DataConsumer.setASTContext(Context);
+    DataConsumer.startedTranslationUnit();
   }
 
   void HandleTranslationUnit(ASTContext &Ctx) override {
@@ -299,34 +298,7 @@
   }
 
   bool HandleTopLevelDecl(DeclGroupRef DG) override {
-    IndexCtx.indexDeclGroupRef(DG);
-    return !IndexCtx.shouldAbort();
-  }
-
-  /// \brief Handle the specified top-level declaration that occurred inside
-  /// and ObjC container.
-  void HandleTopLevelDeclInObjCContainer(DeclGroupRef DG) override {
-    IndexCtx.indexDeclGroupRef(DG);
-  }
-
-  /// \brief This is called by the AST reader when deserializing things.
-  /// The default implementation forwards to HandleTopLevelDecl but we don't
-  /// care about them when indexing, so have an empty definition.
-  void HandleInterestingDecl(DeclGroupRef D) override {}
-
-  void HandleTagDeclDefinition(TagDecl *D) override {
-    if (!IndexCtx.shouldIndexImplicitTemplateInsts())
-      return;
-
-    if (IndexCtx.isTemplateImplicitInstantiation(D))
-      IndexCtx.indexDecl(D);
-  }
-
-  void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) override {
-    if (!IndexCtx.shouldIndexImplicitTemplateInsts())
-      return;
-
-    IndexCtx.indexDecl(D);
+    return !DataConsumer.shouldAbort();
   }
 
   bool shouldSkipFunctionBody(Decl *D) override {
@@ -335,7 +307,7 @@
       return true;
     }
 
-    const SourceManager &SM = IndexCtx.getASTContext().getSourceManager();
+    const SourceManager &SM = DataConsumer.getASTContext().getSourceManager();
     SourceLocation Loc = D->getLocation();
     if (Loc.isMacroID())
       return false;
@@ -376,34 +348,29 @@
 //===----------------------------------------------------------------------===//
 
 class IndexingFrontendAction : public ASTFrontendAction {
-  IndexingContext IndexCtx;
-  CXTranslationUnit CXTU;
+  std::shared_ptr<CXIndexDataConsumer> DataConsumer;
 
   SessionSkipBodyData *SKData;
   std::unique_ptr<TUSkipBodyControl> SKCtrl;
 
 public:
-  IndexingFrontendAction(CXClientData clientData,
-                         IndexerCallbacks &indexCallbacks,
-                         unsigned indexOptions,
-                         CXTranslationUnit cxTU,
+  IndexingFrontendAction(std::shared_ptr<CXIndexDataConsumer> dataConsumer,
                          SessionSkipBodyData *skData)
-    : IndexCtx(clientData, indexCallbacks, indexOptions, cxTU),
-      CXTU(cxTU), SKData(skData) { }
+    : DataConsumer(dataConsumer), SKData(skData) { }
 
   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
                                                  StringRef InFile) override {
     PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
 
     if (!PPOpts.ImplicitPCHInclude.empty()) {
-      IndexCtx.importedPCH(
+      DataConsumer->importedPCH(
                         CI.getFileManager().getFile(PPOpts.ImplicitPCHInclude));
     }
 
-    IndexCtx.setASTContext(CI.getASTContext());
+    DataConsumer->setASTContext(CI.getASTContext());
     Preprocessor &PP = CI.getPreprocessor();
-    PP.addPPCallbacks(llvm::make_unique<IndexPPCallbacks>(PP, IndexCtx));
-    IndexCtx.setPreprocessor(PP);
+    PP.addPPCallbacks(llvm::make_unique<IndexPPCallbacks>(PP, *DataConsumer));
+    DataConsumer->setPreprocessor(PP);
 
     if (SKData) {
       auto *PPRec = new PPConditionalDirectiveRecord(PP.getSourceManager());
@@ -411,15 +378,11 @@
       SKCtrl = llvm::make_unique<TUSkipBodyControl>(*SKData, *PPRec, PP);
     }
 
-    return llvm::make_unique<IndexingConsumer>(IndexCtx, SKCtrl.get());
-  }
-
-  void EndSourceFileAction() override {
-    indexDiagnostics(CXTU, IndexCtx);
+    return llvm::make_unique<IndexingConsumer>(*DataConsumer, SKCtrl.get());
   }
 
   TranslationUnitKind getTranslationUnitKind() override {
-    if (IndexCtx.shouldIndexImplicitTemplateInsts())
+    if (DataConsumer->shouldIndexImplicitTemplateInsts())
       return TU_Complete;
     else
       return TU_Prefix;
@@ -431,6 +394,13 @@
 // clang_indexSourceFileUnit Implementation
 //===----------------------------------------------------------------------===//
 
+static IndexingOptions getIndexingOptionsFromCXOptions(unsigned index_options) {
+  IndexingOptions IdxOpts;
+  if (index_options & CXIndexOpt_IndexFunctionLocalSymbols)
+    IdxOpts.IndexFunctionLocals = true;
+  return IdxOpts;
+}
+
 struct IndexSessionData {
   CXIndex CIdx;
   std::unique_ptr<SessionSkipBodyData> SkipBodyData;
@@ -566,13 +536,17 @@
   if (SkipBodies)
     CInvok->getFrontendOpts().SkipFunctionBodies = true;
 
-  std::unique_ptr<IndexingFrontendAction> IndexAction;
-  IndexAction.reset(new IndexingFrontendAction(client_data, CB,
-                                               index_options, CXTU->getTU(),
-                        SkipBodies ? IdxSession->SkipBodyData.get() : nullptr));
+  auto DataConsumer =
+    std::make_shared<CXIndexDataConsumer>(client_data, CB, index_options,
+                                          CXTU->getTU());
+  auto InterAction = llvm::make_unique<IndexingFrontendAction>(DataConsumer,
+                         SkipBodies ? IdxSession->SkipBodyData.get() : nullptr);
+  std::unique_ptr<FrontendAction> IndexAction;
+  IndexAction = createIndexingAction(std::move(InterAction), DataConsumer,
+                                getIndexingOptionsFromCXOptions(index_options));
 
   // Recover resources if we crash before exiting this method.
-  llvm::CrashRecoveryContextCleanupRegistrar<IndexingFrontendAction>
+  llvm::CrashRecoveryContextCleanupRegistrar<FrontendAction>
     IndexActionCleanup(IndexAction.get());
 
   bool Persistent = requestedToGetTU;
@@ -632,7 +606,7 @@
 // clang_indexTranslationUnit Implementation
 //===----------------------------------------------------------------------===//
 
-static void indexPreprocessingRecord(ASTUnit &Unit, IndexingContext &IdxCtx) {
+static void indexPreprocessingRecord(ASTUnit &Unit, CXIndexDataConsumer &IdxCtx) {
   Preprocessor &PP = Unit.getPreprocessor();
   if (!PP.getPreprocessingRecord())
     return;
@@ -655,24 +629,6 @@
   }
 }
 
-static bool topLevelDeclVisitor(void *context, const Decl *D) {
-  IndexingContext &IdxCtx = *static_cast<IndexingContext*>(context);
-  IdxCtx.indexTopLevelDecl(D);
-  return !IdxCtx.shouldAbort();
-}
-
-static void indexTranslationUnit(ASTUnit &Unit, IndexingContext &IdxCtx) {
-  Unit.visitLocalTopLevelDecls(&IdxCtx, topLevelDeclVisitor);
-}
-
-static void indexDiagnostics(CXTranslationUnit TU, IndexingContext &IdxCtx) {
-  if (!IdxCtx.hasDiagnosticCallback())
-    return;
-
-  CXDiagnosticSetImpl *DiagSet = cxdiag::lazyCreateDiags(TU);
-  IdxCtx.handleDiagnosticSet(DiagSet);
-}
-
 static CXErrorCode clang_indexTranslationUnit_Impl(
     CXIndexAction idxAction, CXClientData client_data,
     IndexerCallbacks *client_index_callbacks, unsigned index_callbacks_size,
@@ -696,19 +652,8 @@
                                   ? index_callbacks_size : sizeof(CB);
   memcpy(&CB, client_index_callbacks, ClientCBSize);
 
-  std::unique_ptr<IndexingContext> IndexCtx;
-  IndexCtx.reset(new IndexingContext(client_data, CB, index_options, TU));
-
-  // Recover resources if we crash before exiting this method.
-  llvm::CrashRecoveryContextCleanupRegistrar<IndexingContext>
-    IndexCtxCleanup(IndexCtx.get());
-
-  std::unique_ptr<IndexingConsumer> IndexConsumer;
-  IndexConsumer.reset(new IndexingConsumer(*IndexCtx, nullptr));
-
-  // Recover resources if we crash before exiting this method.
-  llvm::CrashRecoveryContextCleanupRegistrar<IndexingConsumer>
-    IndexConsumerCleanup(IndexConsumer.get());
+  auto DataConsumer = std::make_shared<CXIndexDataConsumer>(client_data, CB,
+                                                            index_options, TU);
 
   ASTUnit *Unit = cxtu::getASTUnit(TU);
   if (!Unit)
@@ -717,20 +662,21 @@
   ASTUnit::ConcurrencyCheck Check(*Unit);
 
   if (const FileEntry *PCHFile = Unit->getPCHFile())
-    IndexCtx->importedPCH(PCHFile);
+    DataConsumer->importedPCH(PCHFile);
 
   FileManager &FileMgr = Unit->getFileManager();
 
   if (Unit->getOriginalSourceFileName().empty())
-    IndexCtx->enteredMainFile(nullptr);
+    DataConsumer->enteredMainFile(nullptr);
   else
-    IndexCtx->enteredMainFile(FileMgr.getFile(Unit->getOriginalSourceFileName()));
+    DataConsumer->enteredMainFile(FileMgr.getFile(Unit->getOriginalSourceFileName()));
 
-  IndexConsumer->Initialize(Unit->getASTContext());
+  DataConsumer->setASTContext(Unit->getASTContext());
+  DataConsumer->startedTranslationUnit();
 
-  indexPreprocessingRecord(*Unit, *IndexCtx);
-  indexTranslationUnit(*Unit, *IndexCtx);
-  indexDiagnostics(TU, *IndexCtx);
+  indexPreprocessingRecord(*Unit, *DataConsumer);
+  indexASTUnit(*Unit, DataConsumer, getIndexingOptionsFromCXOptions(index_options));
+  DataConsumer->indexDiagnostics();
 
   return CXError_Success;
 }
@@ -1015,9 +961,9 @@
   if (!location.ptr_data[0] || Loc.isInvalid())
     return;
 
-  IndexingContext &IndexCtx =
-      *static_cast<IndexingContext*>(location.ptr_data[0]);
-  IndexCtx.translateLoc(Loc, indexFile, file, line, column, offset);
+  CXIndexDataConsumer &DataConsumer =
+      *static_cast<CXIndexDataConsumer*>(location.ptr_data[0]);
+  DataConsumer.translateLoc(Loc, indexFile, file, line, column, offset);
 }
 
 CXSourceLocation clang_indexLoc_getCXSourceLocation(CXIdxLoc location) {
@@ -1025,9 +971,9 @@
   if (!location.ptr_data[0] || Loc.isInvalid())
     return clang_getNullLocation();
 
-  IndexingContext &IndexCtx =
-      *static_cast<IndexingContext*>(location.ptr_data[0]);
-  return cxloc::translateSourceLocation(IndexCtx.getASTContext(), Loc);
+  CXIndexDataConsumer &DataConsumer =
+      *static_cast<CXIndexDataConsumer*>(location.ptr_data[0]);
+  return cxloc::translateSourceLocation(DataConsumer.getASTContext(), Loc);
 }
 
 } // end: extern "C"