From: Argyrios Kyrtzidis Date: Mon, 4 Apr 2011 21:38:51 +0000 (+0000) Subject: Introduce Driver::createInvocationFromArgs used to create a CompilerInvocation from... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=054e4f50e2f1995e91b0cd3c3258aa252785fe3f;p=clang 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 --- diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h index 099a354145..016f56ac6f 100644 --- a/include/clang/Driver/Driver.h +++ b/include/clang/Driver/Driver.h @@ -28,6 +28,7 @@ namespace llvm { template class ArrayRef; } namespace clang { + class CompilerInvocation; namespace driver { class Action; class ArgList; @@ -351,6 +352,17 @@ public: /// @} + + /// 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. + static CompilerInvocation * + createInvocationFromArgs(llvm::ArrayRef Args, + llvm::IntrusiveRefCntPtr Diags = + llvm::IntrusiveRefCntPtr()); + /// GetReleaseVersion - Parse (([0-9]+)(.([0-9]+)(.([0-9]+)?))?)? and /// return the grouped values as integers. Numbers which are not /// provided are set to 0. 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 ArgList, + llvm::IntrusiveRefCntPtr 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 Args; + Args.push_back(""); // 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 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(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(*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(CCArgs.data()), + const_cast(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. /// diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp index 21a45b2962..bfa2791ef6 100644 --- a/lib/Frontend/ASTUnit.cpp +++ b/lib/Frontend/ASTUnit.cpp @@ -1632,20 +1632,6 @@ ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin, Diags = CompilerInstance::createDiagnostics(DiagOpts, ArgEnd - ArgBegin, ArgBegin); } - - llvm::OwningPtr > - Args(new std::vector); - - // Recover resources if we crash before exiting this function. - llvm::CrashRecoveryContextCleanupRegistrar< - std::vector > CleanupArgs(Args.get()); - - Args->push_back(""); // 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::SmallVector StoredDiagnostics; @@ -1655,45 +1641,11 @@ ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin, CaptureDroppedDiagnostics Capture(CaptureDiagnostics, *Diags, StoredDiagnostics); - // 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 have been remapped. - TheDriver.setCheckInputsExist(false); - - llvm::OwningPtr 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); + CI = driver::Driver::createInvocationFromArgs( + llvm::ArrayRef(ArgBegin, ArgEnd-ArgBegin), + Diags); + if (!CI) 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(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(*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(); - CI = new CompilerInvocation(); - CompilerInvocation::CreateFromArgs(*CI, - const_cast(CCArgs.data()), - const_cast(CCArgs.data()) + - CCArgs.size(), - *Diags); } // Override any files that need remapping