diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-04-04 21:38:51 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-04-04 21:38:51 +0000 |
commit | 054e4f50e2f1995e91b0cd3c3258aa252785fe3f (patch) | |
tree | ec793b80884a3df7679e2f9488c73005a44c28f6 /lib/Driver/Driver.cpp | |
parent | 6f41715df2c6a31c0c3ab3088b8cd18a3c8321b8 (diff) |
Introduce Driver::createInvocationFromArgs used to create a CompilerInvocation from command-line args.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@128848 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Driver/Driver.cpp')
-rw-r--r-- | lib/Driver/Driver.cpp | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index 9d02dee540..6dd8fb8f88 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -27,6 +27,9 @@ #include "clang/Driver/ToolChain.h" #include "clang/Driver/Types.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/DiagnosticOptions.h" +#include "clang/Frontend/FrontendDiagnostic.h" #include "clang/Basic/Version.h" #include "llvm/Config/config.h" @@ -38,6 +41,7 @@ #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" #include "llvm/Support/Program.h" +#include "llvm/Support/Host.h" #include "InputInfo.h" @@ -1430,6 +1434,72 @@ bool Driver::ShouldUseClangCompiler(const Compilation &C, const JobAction &JA, return true; } +/// createInvocationFromArgs - 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 * +Driver::createInvocationFromArgs(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; +} + /// GetReleaseVersion - Parse (([0-9]+)(.([0-9]+)(.([0-9]+)?))?)? and return the /// grouped values as integers. Numbers which are not provided are set to 0. /// |