diff options
Diffstat (limited to 'lib/Frontend/CreateInvocationFromCommandLine.cpp')
| -rw-r--r-- | lib/Frontend/CreateInvocationFromCommandLine.cpp | 90 | 
1 files changed, 90 insertions, 0 deletions
| diff --git a/lib/Frontend/CreateInvocationFromCommandLine.cpp b/lib/Frontend/CreateInvocationFromCommandLine.cpp new file mode 100644 index 000000000000..0005f910d214 --- /dev/null +++ b/lib/Frontend/CreateInvocationFromCommandLine.cpp @@ -0,0 +1,90 @@ +//===--- CreateInvocationFromCommandLine.cpp - CompilerInvocation from Args ==// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Construct a compiler invocation object for command line driver arguments +// +//===----------------------------------------------------------------------===// + +#include "clang/Frontend/Utils.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/DiagnosticOptions.h" +#include "clang/Frontend/FrontendDiagnostic.h" +#include "clang/Driver/Compilation.h" +#include "clang/Driver/Driver.h" +#include "clang/Driver/ArgList.h" +#include "clang/Driver/Options.h" +#include "clang/Driver/Tool.h" +#include "llvm/Support/Host.h" +using namespace clang; + +/// createInvocationFromCommandLine - Construct a compiler invocation object for +/// a command line argument vector. +/// +/// \return A CompilerInvocation, or 0 if none was built for the given +/// argument vector. +CompilerInvocation * +clang::createInvocationFromCommandLine(llvm::ArrayRef<const char *> ArgList, +                                   llvm::IntrusiveRefCntPtr<Diagnostic> Diags) { +  if (!Diags.getPtr()) { +    // No diagnostics engine was provided, so create our own diagnostics object +    // with the default options. +    DiagnosticOptions DiagOpts; +    Diags = CompilerInstance::createDiagnostics(DiagOpts, ArgList.size(), +                                                ArgList.begin()); +  } + +  llvm::SmallVector<const char *, 16> Args; +  Args.push_back("<clang>"); // FIXME: Remove dummy argument. +  Args.insert(Args.end(), ArgList.begin(), ArgList.end()); + +  // 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"); + +  // FIXME: We shouldn't have to pass in the path info. +  driver::Driver TheDriver("clang", llvm::sys::getHostTriple(), +                           "a.out", false, false, *Diags); + +  // Don't check that inputs exist, they may have been remapped. +  TheDriver.setCheckInputsExist(false); + +  llvm::OwningPtr<driver::Compilation> C(TheDriver.BuildCompilation(Args)); + +  // Just print the cc1 options if -### was present. +  if (C->getArgs().hasArg(driver::options::OPT__HASH_HASH_HASH)) { +    C->PrintJob(llvm::errs(), C->getJobs(), "\n", true); +    return 0; +  } + +  // 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 = new CompilerInvocation(); +  CompilerInvocation::CreateFromArgs(*CI, +                                     const_cast<const char **>(CCArgs.data()), +                                     const_cast<const char **>(CCArgs.data()) + +                                     CCArgs.size(), +                                     *Diags); +  return CI; +} | 
