CreateInvocationFromCommandLine.cpp revision 261991
1212793Sdim//===--- CreateInvocationFromCommandLine.cpp - CompilerInvocation from Args ==// 2212793Sdim// 3212793Sdim// The LLVM Compiler Infrastructure 4212793Sdim// 5212793Sdim// This file is distributed under the University of Illinois Open Source 6212793Sdim// License. See LICENSE.TXT for details. 7212793Sdim// 8212793Sdim//===----------------------------------------------------------------------===// 9212793Sdim// 10212793Sdim// Construct a compiler invocation object for command line driver arguments 11212793Sdim// 12212793Sdim//===----------------------------------------------------------------------===// 13212793Sdim 14212793Sdim#include "clang/Frontend/Utils.h" 15212793Sdim#include "clang/Basic/DiagnosticOptions.h" 16212793Sdim#include "clang/Driver/Compilation.h" 17212793Sdim#include "clang/Driver/Driver.h" 18212793Sdim#include "clang/Driver/Options.h" 19212793Sdim#include "clang/Driver/Tool.h" 20212793Sdim#include "clang/Frontend/CompilerInstance.h" 21212793Sdim#include "clang/Frontend/FrontendDiagnostic.h" 22212793Sdim#include "llvm/Option/ArgList.h" 23234353Sdim#include "llvm/Support/Host.h" 24212793Sdimusing namespace clang; 25224145Sdimusing namespace llvm::opt; 26224145Sdim 27224145Sdim/// createInvocationFromCommandLine - Construct a compiler invocation object for 28243830Sdim/// a command line argument vector. 29224145Sdim/// 30224145Sdim/// \return A CompilerInvocation, or 0 if none was built for the given 31224145Sdim/// argument vector. 32224145SdimCompilerInvocation * 33224145Sdimclang::createInvocationFromCommandLine(ArrayRef<const char *> ArgList, 34224145Sdim IntrusiveRefCntPtr<DiagnosticsEngine> Diags) { 35224145Sdim if (!Diags.getPtr()) { 36263508Sdim // No diagnostics engine was provided, so create our own diagnostics object 37263508Sdim // with the default options. 38263508Sdim Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions); 39263508Sdim } 40263508Sdim 41263508Sdim SmallVector<const char *, 16> Args; 42263508Sdim Args.push_back("<clang>"); // FIXME: Remove dummy argument. 43263508Sdim Args.insert(Args.end(), ArgList.begin(), ArgList.end()); 44263508Sdim 45263508Sdim // FIXME: Find a cleaner way to force the driver into restricted modes. 46263508Sdim Args.push_back("-fsyntax-only"); 47263508Sdim 48263508Sdim // FIXME: We shouldn't have to pass in the path info. 49224145Sdim driver::Driver TheDriver("clang", llvm::sys::getDefaultTargetTriple(), 50218893Sdim "a.out", *Diags); 51218893Sdim 52218893Sdim // Don't check that inputs exist, they may have been remapped. 53218893Sdim TheDriver.setCheckInputsExist(false); 54218893Sdim 55218893Sdim OwningPtr<driver::Compilation> C(TheDriver.BuildCompilation(Args)); 56218893Sdim 57218893Sdim // Just print the cc1 options if -### was present. 58218893Sdim if (C->getArgs().hasArg(driver::options::OPT__HASH_HASH_HASH)) { 59218893Sdim C->getJobs().Print(llvm::errs(), "\n", true); 60218893Sdim return 0; 61218893Sdim } 62218893Sdim 63218893Sdim // We expect to get back exactly one command job, if we didn't something 64218893Sdim // failed. 65218893Sdim const driver::JobList &Jobs = C->getJobs(); 66218893Sdim if (Jobs.size() != 1 || !isa<driver::Command>(*Jobs.begin())) { 67218893Sdim SmallString<256> Msg; 68218893Sdim llvm::raw_svector_ostream OS(Msg); 69212793Sdim Jobs.Print(OS, "; ", true); 70224145Sdim Diags->Report(diag::err_fe_expected_compiler_job) << OS.str(); 71263508Sdim return 0; 72263508Sdim } 73224145Sdim 74212793Sdim const driver::Command *Cmd = cast<driver::Command>(*Jobs.begin()); 75224145Sdim if (StringRef(Cmd->getCreator().getName()) != "clang") { 76263508Sdim Diags->Report(diag::err_fe_expected_clang_command); 77263508Sdim return 0; 78224145Sdim } 79224145Sdim 80224145Sdim const ArgStringList &CCArgs = Cmd->getArguments(); 81224145Sdim OwningPtr<CompilerInvocation> CI(new CompilerInvocation()); 82224145Sdim if (!CompilerInvocation::CreateFromArgs(*CI, 83263508Sdim const_cast<const char **>(CCArgs.data()), 84263508Sdim const_cast<const char **>(CCArgs.data()) + 85263508Sdim CCArgs.size(), 86263508Sdim *Diags)) 87224145Sdim return 0; 88224145Sdim return CI.take(); 89224145Sdim} 90263508Sdim