Switch clang_createTranslationUnitFromSourceFile to use ASTUnit::LoadFromCommandLine.
 - This is much faster, as it avoids the overhead of dumping an AST file to disk and reloading it.
 - For debugging purposes, there is a clang_setUseExternalASTGeneration hook which can be used to disable this.

On the Sketch Cocoa app, the speedup is pretty nice, especially when using a PCH file while scanning the source:

Wall time to c-index-test all files (no PCH):
Old: 23.4221
New: 12.3884

Wall time to c-index-test all files (with a PCH, and "local" mode):
Old: 10.9233
New:  1.9038

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90385 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp
index a5b7e99..8ef9fb5 100644
--- a/tools/CIndex/CIndex.cpp
+++ b/tools/CIndex/CIndex.cpp
@@ -324,6 +324,11 @@
     DisplayDiagnostics = Display;
   }
 
+  bool getUseExternalASTGeneration() const { return UseExternalASTGeneration; }
+  void setUseExternalASTGeneration(bool Value) {
+    UseExternalASTGeneration = Value;
+  }
+
   Diagnostic &getDiags() {
     return DisplayDiagnostics ? *TextDiags : IgnoreDiags;
   }
@@ -466,6 +471,12 @@
   delete static_cast<CIndexer *>(CIdx);
 }
 
+void clang_setUseExternalASTGeneration(CXIndex CIdx, int value) {
+  assert(CIdx && "Passed null CXIndex");
+  CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
+  CXXIdx->setUseExternalASTGeneration(value);
+}
+
 // FIXME: need to pass back error info.
 CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
                                               const char *ast_filename) {
@@ -485,6 +496,24 @@
   assert(CIdx && "Passed null CXIndex");
   CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
 
+  if (!CXXIdx->getUseExternalASTGeneration()) {
+    llvm::SmallVector<const char *, 16> Args;
+
+    // The 'source_filename' argument is optional.  If the caller does not
+    // specify it then it is assumed that the source file is specified
+    // in the actual argument list.
+    if (source_filename)
+      Args.push_back(source_filename);
+    Args.insert(Args.end(), command_line_args,
+                command_line_args + num_command_line_args);
+
+    void *MainAddr = (void *)(uintptr_t)clang_createTranslationUnit;
+    return ASTUnit::LoadFromCommandLine(Args.data(), Args.data() + Args.size(),
+                                        CXXIdx->getDiags(), "<clang>", MainAddr,
+                                        CXXIdx->getOnlyLocalDecls(),
+                                        /* UseBumpAllocator = */ true);
+  }
+
   // Build up the arguments for invoking 'clang'.
   std::vector<const char *> argv;
 
@@ -572,8 +601,18 @@
   ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit);
   ASTContext &Ctx = CXXUnit->getASTContext();
 
-  TUVisitor DVisit(CTUnit, callback, CData,
-                   CXXUnit->getOnlyLocalDecls()? 1 : Decl::MaxPCHLevel);
+  unsigned PCHLevel = Decl::MaxPCHLevel;
+
+  // Set the PCHLevel to filter out unwanted decls if requested.
+  if (CXXUnit->getOnlyLocalDecls()) {
+    PCHLevel = 0;
+
+    // If the main input was an AST, bump the level.
+    if (CXXUnit->isMainFileAST())
+      ++PCHLevel;
+  }
+
+  TUVisitor DVisit(CTUnit, callback, CData, PCHLevel);
   DVisit.Visit(Ctx.getTranslationUnitDecl());
 }