Add ASTUnit::LoadFromCompilerInvocation, which does what it says.

Also, add an -ast-from-source option to index-test which allows index-test to
run on source files directly.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90223 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/index-test/CMakeLists.txt b/tools/index-test/CMakeLists.txt
index 9c9656a..163afc4 100644
--- a/tools/index-test/CMakeLists.txt
+++ b/tools/index-test/CMakeLists.txt
@@ -3,8 +3,10 @@
 set( LLVM_USED_LIBS
   clangIndex
   clangFrontend
+  clangAnalysis
   clangSema
   clangAST
+  clangParse
   clangLex
   clangBasic
   )
diff --git a/tools/index-test/Makefile b/tools/index-test/Makefile
index 76602e1..8e7bfe5 100644
--- a/tools/index-test/Makefile
+++ b/tools/index-test/Makefile
@@ -19,6 +19,7 @@
 include $(LEVEL)/Makefile.config
 
 LINK_COMPONENTS := bitreader mc
-USEDLIBS = clangIndex.a clangFrontend.a clangSema.a clangAST.a clangLex.a clangBasic.a 
+USEDLIBS = clangIndex.a clangFrontend.a clangDriver.a clangAnalysis.a clangSema.a \
+	   clangAST.a clangParse.a clangLex.a clangBasic.a
 
 include $(LLVM_SRC_ROOT)/Makefile.rules
diff --git a/tools/index-test/index-test.cpp b/tools/index-test/index-test.cpp
index fce48ed..dd7cbb2 100644
--- a/tools/index-test/index-test.cpp
+++ b/tools/index-test/index-test.cpp
@@ -43,6 +43,10 @@
 #include "clang/Index/Analyzer.h"
 #include "clang/Index/Utils.h"
 #include "clang/Frontend/ASTUnit.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/CompilerInvocation.h"
+#include "clang/Frontend/DiagnosticOptions.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
 #include "clang/Frontend/CommandLineSourceLoc.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/ExprObjC.h"
@@ -202,9 +206,24 @@
   }
 }
 
+static llvm::cl::opt<bool>
+ASTFromSource("ast-from-source",
+              llvm::cl::desc("Treat the inputs as source files to parse."));
+
 static llvm::cl::list<std::string>
 InputFilenames(llvm::cl::Positional, llvm::cl::desc("<input AST files>"));
 
+void CreateCompilerInvocation(const std::string &Filename,
+                              CompilerInvocation &CI, Diagnostic &Diags,
+                              const char *argv0) {
+  llvm::SmallVector<const char *, 16> Args;
+  Args.push_back(Filename.c_str());
+
+  void *MainAddr = (void*) (intptr_t) CreateCompilerInvocation;
+  CompilerInvocation::CreateFromArgs(CI, Args.data(), Args.data() + Args.size(),
+                                     argv0, MainAddr, Diags);
+}
+
 int main(int argc, char **argv) {
   llvm::sys::PrintStackTraceOnErrorSignal();
   llvm::PrettyStackTraceProgram X(argc, argv);
@@ -215,6 +234,10 @@
   Indexer Idxer(Prog);
   llvm::SmallVector<TUnit*, 4> TUnits;
 
+  TextDiagnosticPrinter DiagClient(llvm::errs(), DiagnosticOptions(), false);
+  llvm::OwningPtr<Diagnostic> Diags(
+    CompilerInstance::createDiagnostics(DiagnosticOptions(), argc, argv));
+
   // If no input was specified, read from stdin.
   if (InputFilenames.empty())
     InputFilenames.push_back("-");
@@ -225,7 +248,15 @@
     std::string ErrMsg;
     llvm::OwningPtr<ASTUnit> AST;
 
-    AST.reset(ASTUnit::LoadFromPCHFile(InFile, &ErrMsg));
+    if (ASTFromSource) {
+      CompilerInvocation CI;
+      CreateCompilerInvocation(InFile, CI, *Diags, argv[0]);
+      AST.reset(ASTUnit::LoadFromCompilerInvocation(CI, *Diags));
+      if (!AST)
+        ErrMsg = "unable to create AST";
+    } else
+      AST.reset(ASTUnit::LoadFromPCHFile(InFile, &ErrMsg));
+
     if (!AST) {
       llvm::errs() << "[" << InFile << "] Error: " << ErrMsg << '\n';
       return 1;