CreateInvocationFromCommandLine.cpp revision 249423
1250323Sdteske//===--- CreateInvocationFromCommandLine.cpp - CompilerInvocation from Args ==// 2250323Sdteske// 3250323Sdteske// The LLVM Compiler Infrastructure 4252980Sdteske// 5250323Sdteske// This file is distributed under the University of Illinois Open Source 6250323Sdteske// License. See LICENSE.TXT for details. 7250323Sdteske// 8250323Sdteske//===----------------------------------------------------------------------===// 9250323Sdteske// 10250323Sdteske// Construct a compiler invocation object for command line driver arguments 11250323Sdteske// 12250323Sdteske//===----------------------------------------------------------------------===// 13250323Sdteske 14250323Sdteske#include "clang/Frontend/Utils.h" 15250323Sdteske#include "clang/Basic/DiagnosticOptions.h" 16252987Sdteske#include "clang/Driver/ArgList.h" 17250323Sdteske#include "clang/Driver/Compilation.h" 18250323Sdteske#include "clang/Driver/Driver.h" 19250323Sdteske#include "clang/Driver/Options.h" 20252987Sdteske#include "clang/Driver/Tool.h" 21250323Sdteske#include "clang/Frontend/CompilerInstance.h" 22250323Sdteske#include "clang/Frontend/FrontendDiagnostic.h" 23250323Sdteske#include "llvm/Support/Host.h" 24250323Sdteskeusing namespace clang; 25250323Sdteske 26250323Sdteske/// createInvocationFromCommandLine - Construct a compiler invocation object for 27250323Sdteske/// a command line argument vector. 28250323Sdteske/// 29250323Sdteske/// \return A CompilerInvocation, or 0 if none was built for the given 30250323Sdteske/// argument vector. 31250323SdteskeCompilerInvocation * 32250323Sdteskeclang::createInvocationFromCommandLine(ArrayRef<const char *> ArgList, 33250323Sdteske IntrusiveRefCntPtr<DiagnosticsEngine> Diags) { 34250323Sdteske if (!Diags.getPtr()) { 35250323Sdteske // No diagnostics engine was provided, so create our own diagnostics object 36272230Sdteske // with the default options. 37250323Sdteske Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions); 38250323Sdteske } 39250323Sdteske 40250323Sdteske SmallVector<const char *, 16> Args; 41250323Sdteske Args.push_back("<clang>"); // FIXME: Remove dummy argument. 42250323Sdteske Args.insert(Args.end(), ArgList.begin(), ArgList.end()); 43250323Sdteske 44250323Sdteske // FIXME: Find a cleaner way to force the driver into restricted modes. 45250323Sdteske Args.push_back("-fsyntax-only"); 46250323Sdteske 47258420Sdteske // FIXME: We shouldn't have to pass in the path info. 48258420Sdteske driver::Driver TheDriver("clang", llvm::sys::getDefaultTargetTriple(), 49258420Sdteske "a.out", *Diags); 50258420Sdteske 51258420Sdteske // Don't check that inputs exist, they may have been remapped. 52258420Sdteske TheDriver.setCheckInputsExist(false); 53258420Sdteske 54258420Sdteske OwningPtr<driver::Compilation> C(TheDriver.BuildCompilation(Args)); 55258420Sdteske 56258420Sdteske // Just print the cc1 options if -### was present. 57250323Sdteske if (C->getArgs().hasArg(driver::options::OPT__HASH_HASH_HASH)) { 58250323Sdteske C->PrintJob(llvm::errs(), C->getJobs(), "\n", true); 59258420Sdteske return 0; 60250323Sdteske } 61258420Sdteske 62258420Sdteske // We expect to get back exactly one command job, if we didn't something 63258420Sdteske // failed. 64250323Sdteske const driver::JobList &Jobs = C->getJobs(); 65250323Sdteske if (Jobs.size() != 1 || !isa<driver::Command>(*Jobs.begin())) { 66250323Sdteske SmallString<256> Msg; 67250323Sdteske llvm::raw_svector_ostream OS(Msg); 68250323Sdteske C->PrintJob(OS, C->getJobs(), "; ", true); 69258420Sdteske Diags->Report(diag::err_fe_expected_compiler_job) << OS.str(); 70272230Sdteske return 0; 71250323Sdteske } 72250323Sdteske 73250323Sdteske const driver::Command *Cmd = cast<driver::Command>(*Jobs.begin()); 74250323Sdteske if (StringRef(Cmd->getCreator().getName()) != "clang") { 75250323Sdteske Diags->Report(diag::err_fe_expected_clang_command); 76250323Sdteske return 0; 77272230Sdteske } 78272230Sdteske 79272230Sdteske const driver::ArgStringList &CCArgs = Cmd->getArguments(); 80250323Sdteske OwningPtr<CompilerInvocation> CI(new CompilerInvocation()); 81266290Sdteske if (!CompilerInvocation::CreateFromArgs(*CI, 82250323Sdteske const_cast<const char **>(CCArgs.data()), 83258420Sdteske const_cast<const char **>(CCArgs.data()) + 84258420Sdteske CCArgs.size(), 85258420Sdteske *Diags)) 86258420Sdteske return 0; 87258420Sdteske return CI.take(); 88258420Sdteske} 89258420Sdteske