[cfe-commits] r90288 - in /cfe/trunk: include/clang/Basic/DiagnosticFrontendKinds.td include/clang/Frontend/ASTUnit.h lib/Frontend/ASTUnit.cpp tools/index-test/index-test.cpp

Daniel Dunbar daniel at zuster.org
Tue Dec 1 19:23:45 PST 2009


Author: ddunbar
Date: Tue Dec  1 21:23:45 2009
New Revision: 90288

URL: http://llvm.org/viewvc/llvm-project?rev=90288&view=rev
Log:
Add ASTUnit::LoadFromCommandLine, which creates an ASTUnit out of a list of
(clang/driver) command line arguments (including the source file).
 - The arguments are expected to include the source file.

 - The idea is that even though this is a somewhat odd API, its the form which
   many tools can most easily use (for example, by interposing with the compiler).

Also, switch index-test's -ast-from-source to use this entry point, and provide
a -arg command line argument which can be used to test that the command line
arguments are handled correctly.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td
    cfe/trunk/include/clang/Frontend/ASTUnit.h
    cfe/trunk/lib/Frontend/ASTUnit.cpp
    cfe/trunk/tools/index-test/index-test.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td?rev=90288&r1=90287&r2=90288&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td Tue Dec  1 21:23:45 2009
@@ -15,8 +15,8 @@
 def err_fe_error_backend : Error<"error in backend: %0">, DefaultFatal;
 def err_fe_invalid_ast_file : Error<"invalid AST file: '%0'">, DefaultFatal;
 def err_fe_invalid_ast_action : Error<"invalid action for AST input">, DefaultFatal;
-def err_fe_invalid_code_complete_file
-  : Error<"cannot locate code-completion file %0">, DefaultFatal;
+def err_fe_invalid_code_complete_file : Error<
+    "cannot locate code-completion file %0">, DefaultFatal;
 def err_fe_stdout_binary : Error<"unable to change standard output to binary">,
   DefaultFatal;
 def err_fe_dependency_file_requires_MT : Error<
@@ -29,6 +29,10 @@
     "FIX-IT could not find file '%0'">;
 def err_fe_invalid_plugin_name : Error<
     "unable to find plugin '%0'">;
+def err_fe_expected_compiler_job : Error<
+    "unable to handle compilation, expected exactly one compiler job in '%0'">;
+def err_fe_expected_clang_command : Error<
+    "expected a clang compiler command">;
 
 def err_verify_bogus_characters : Error<
     "bogus characters before '{{' in expected string">;

Modified: cfe/trunk/include/clang/Frontend/ASTUnit.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/ASTUnit.h?rev=90288&r1=90287&r2=90288&view=diff

==============================================================================
--- cfe/trunk/include/clang/Frontend/ASTUnit.h (original)
+++ cfe/trunk/include/clang/Frontend/ASTUnit.h Tue Dec  1 21:23:45 2009
@@ -122,6 +122,30 @@
                                              bool OnlyLocalDecls = false,
                                              bool UseBumpAllocator = false);
 
+  /// LoadFromCommandLine - Create an ASTUnit from a vector of command line
+  /// arguments, which must specify exactly one source file.
+  ///
+  /// \param ArgBegin - The beginning of the argument vector.
+  ///
+  /// \param ArgEnd - The end of the argument vector.
+  ///
+  /// \param Diags - The diagnostics engine to use for reporting errors.
+  ///
+  /// \param Argv0 - The program path (from argv[0]), for finding the builtin
+  /// compiler path.
+  ///
+  /// \param MainAddr - The address of main (or some other function in the main
+  /// executable), for finding the builtin compiler path.
+  //
+  // FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we
+  // shouldn't need to specify them at construction time.
+  static ASTUnit *LoadFromCommandLine(const char **ArgBegin,
+                                      const char **ArgEnd,
+                                      Diagnostic &Diags,
+                                      const char *Arg0,
+                                      void *MainAddr,
+                                      bool OnlyLocalDecls = false,
+                                      bool UseBumpAllocator = false);
 };
 
 } // namespace clang

Modified: cfe/trunk/lib/Frontend/ASTUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTUnit.cpp?rev=90288&r1=90287&r2=90288&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/ASTUnit.cpp (original)
+++ cfe/trunk/lib/Frontend/ASTUnit.cpp Tue Dec  1 21:23:45 2009
@@ -17,8 +17,13 @@
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/DeclVisitor.h"
 #include "clang/AST/StmtVisitor.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/Job.h"
+#include "clang/Driver/Tool.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/FrontendActions.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
 #include "clang/Frontend/FrontendOptions.h"
 #include "clang/Lex/HeaderSearch.h"
 #include "clang/Lex/Preprocessor.h"
@@ -26,6 +31,7 @@
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/Diagnostic.h"
 #include "llvm/LLVMContext.h"
+#include "llvm/System/Host.h"
 #include "llvm/System/Path.h"
 using namespace clang;
 
@@ -262,3 +268,52 @@
   Clang.takeDiagnostics();
   return 0;
 }
+
+ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin,
+                                      const char **ArgEnd,
+                                      Diagnostic &Diags,
+                                      const char *Argv0,
+                                      void *MainAddr,
+                                      bool OnlyLocalDecls,
+                                      bool UseBumpAllocator) {
+  llvm::SmallVector<const char *, 16> Args;
+  Args.push_back("<clang>"); // FIXME: Remove dummy argument.
+  Args.insert(Args.end(), ArgBegin, ArgEnd);
+
+  // FIXME: Find a cleaner way to force the driver into restricted modes. We
+  // also want to force it to use clang.
+  Args.push_back("-fsyntax-only");
+
+  llvm::sys::Path Path = llvm::sys::Path::GetMainExecutable(Argv0, MainAddr);
+  driver::Driver TheDriver(Path.getBasename().c_str(),Path.getDirname().c_str(),
+                           llvm::sys::getHostTriple().c_str(),
+                           "a.out", false, Diags);
+  llvm::OwningPtr<driver::Compilation> C(
+    TheDriver.BuildCompilation(Args.size(), Args.data()));
+
+  // We expect to get back exactly one command job, if we didn't something
+  // failed.
+  const driver::JobList &Jobs = C->getJobs();
+  if (Jobs.size() != 1 || !isa<driver::Command>(Jobs.begin())) {
+    llvm::SmallString<256> Msg;
+    llvm::raw_svector_ostream OS(Msg);
+    C->PrintJob(OS, C->getJobs(), "; ", true);
+    Diags.Report(diag::err_fe_expected_compiler_job) << OS.str();
+    return 0;
+  }
+
+  const driver::Command *Cmd = cast<driver::Command>(*Jobs.begin());
+  if (llvm::StringRef(Cmd->getCreator().getName()) != "clang") {
+    Diags.Report(diag::err_fe_expected_clang_command);
+    return 0;
+  }
+
+  const driver::ArgStringList &CCArgs = Cmd->getArguments();
+  CompilerInvocation CI;
+  CompilerInvocation::CreateFromArgs(CI, (const char**) CCArgs.data(),
+                                     (const char**) CCArgs.data()+CCArgs.size(),
+                                     Argv0, MainAddr, Diags);
+
+  return LoadFromCompilerInvocation(CI, Diags, OnlyLocalDecls,
+                                    UseBumpAllocator);
+}

Modified: cfe/trunk/tools/index-test/index-test.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/index-test/index-test.cpp?rev=90288&r1=90287&r2=90288&view=diff

==============================================================================
--- cfe/trunk/tools/index-test/index-test.cpp (original)
+++ cfe/trunk/tools/index-test/index-test.cpp Tue Dec  1 21:23:45 2009
@@ -208,20 +208,24 @@
 
 static llvm::cl::opt<bool>
 ASTFromSource("ast-from-source",
-              llvm::cl::desc("Treat the inputs as source files to parse."));
+              llvm::cl::desc("Treat the inputs as source files to parse"));
+
+static llvm::cl::list<std::string>
+CompilerArgs("arg", llvm::cl::desc("Extra arguments to use during parsing"));
 
 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) {
+ASTUnit *CreateFromSource(const std::string &Filename, Diagnostic &Diags,
+                          const char *Argv0) {
   llvm::SmallVector<const char *, 16> Args;
   Args.push_back(Filename.c_str());
+  for (unsigned i = 0, e = CompilerArgs.size(); i != e; ++i)
+    Args.push_back(CompilerArgs[i].c_str());
 
-  void *MainAddr = (void*) (intptr_t) CreateCompilerInvocation;
-  CompilerInvocation::CreateFromArgs(CI, Args.data(), Args.data() + Args.size(),
-                                     argv0, MainAddr, Diags);
+  return ASTUnit::LoadFromCommandLine(Args.data(), Args.data() + Args.size(),
+                                      Diags, Argv0,
+                                      (void*) (intptr_t) CreateFromSource);
 }
 
 int main(int argc, char **argv) {
@@ -249,10 +253,8 @@
     llvm::OwningPtr<ASTUnit> AST;
 
     if (ASTFromSource) {
-      CompilerInvocation CI;
-      CreateCompilerInvocation(InFile, CI, *Diags, argv[0]);
-      AST.reset(ASTUnit::LoadFromCompilerInvocation(CI, *Diags));
-      if (!AST)
+      AST.reset(CreateFromSource(InFile, *Diags, argv[0]));
+      if (!AST || Diags->getNumErrors())
         ErrMsg = "unable to create AST";
     } else
       AST.reset(ASTUnit::LoadFromPCHFile(InFile, &ErrMsg));





More information about the cfe-commits mailing list