[libclang] Introduce a new high level API for indexing clients that assumes
more of the work involved in indexing a translation unit and simplifies client
implementations.

Only C/ObjC for now, C++ (and comments) to come.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142233 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/libclang/IndexBody.cpp b/tools/libclang/IndexBody.cpp
new file mode 100644
index 0000000..e02a4fa
--- /dev/null
+++ b/tools/libclang/IndexBody.cpp
@@ -0,0 +1,72 @@
+//===- 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 DeclContext *ParentDC;
+
+public:
+  BodyIndexer(IndexingContext &indexCtx, const DeclContext *DC)
+    : IndexCtx(indexCtx), ParentDC(DC) { }
+  
+  bool shouldWalkTypesOfTypeLocs() const { return false; }
+
+  bool TraverseTypeLoc(TypeLoc TL) {
+    IndexCtx.indexTypeLoc(TL, 0, ParentDC);
+    return true;
+  }
+
+  bool VisitDeclRefExpr(DeclRefExpr *E) {
+    const NamedDecl *D = E->getDecl();
+    if (!D)
+      return true;
+    if (D->getParentFunctionOrMethod())
+      return true;
+    
+    IndexCtx.handleReference(D, E->getLocation(), 0, ParentDC, E);
+    return true;
+  }
+
+  bool VisitMemberExpr(MemberExpr *E) {
+    const NamedDecl *D = E->getMemberDecl();
+    if (!D)
+      return true;
+    if (D->getParentFunctionOrMethod())
+      return true;
+    
+    IndexCtx.handleReference(D, E->getMemberLoc(), 0, ParentDC, E);
+    return true;
+  }
+
+  bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
+    const NamedDecl *D = E->getDecl();
+    if (!D)
+      return true;
+    if (D->getParentFunctionOrMethod())
+      return true;
+    
+    IndexCtx.handleReference(D, E->getLocation(), 0, ParentDC, E);
+    return true;
+  }
+};
+
+} // anonymous namespace
+
+void IndexingContext::indexBody(const Stmt *S, const DeclContext *DC) {
+  BodyIndexer(*this, DC).TraverseStmt(const_cast<Stmt*>(S));
+}