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