1ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis//===--- CreateInvocationFromCommandLine.cpp - CompilerInvocation from Args ==//
2ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis//
3ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis//                     The LLVM Compiler Infrastructure
4ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis//
5ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source
6ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis// License. See LICENSE.TXT for details.
7ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis//
8ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
9ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis//
10ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis// Construct a compiler invocation object for command line driver arguments
11ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis//
12ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
13ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis
14ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis#include "clang/Frontend/Utils.h"
1555fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Basic/DiagnosticOptions.h"
16ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis#include "clang/Driver/Compilation.h"
17ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis#include "clang/Driver/Driver.h"
18ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis#include "clang/Driver/Options.h"
19ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis#include "clang/Driver/Tool.h"
2055fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Frontend/CompilerInstance.h"
2155fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Frontend/FrontendDiagnostic.h"
22b1e25a1bc03292dc538d336573e0be1490223171Reid Kleckner#include "llvm/Option/ArgList.h"
23ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis#include "llvm/Support/Host.h"
24ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidisusing namespace clang;
25b1e25a1bc03292dc538d336573e0be1490223171Reid Klecknerusing namespace llvm::opt;
26ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis
27ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis/// createInvocationFromCommandLine - Construct a compiler invocation object for
28ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis/// a command line argument vector.
29ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis///
30ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis/// \return A CompilerInvocation, or 0 if none was built for the given
31ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis/// argument vector.
32ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios KyrtzidisCompilerInvocation *
332d3ba4f5a923a90c3fc290ddfba5e36c2d0a9b46Chris Lattnerclang::createInvocationFromCommandLine(ArrayRef<const char *> ArgList,
34c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith                            IntrusiveRefCntPtr<DiagnosticsEngine> Diags) {
35c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  if (!Diags.get()) {
36ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis    // No diagnostics engine was provided, so create our own diagnostics object
37ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis    // with the default options.
38d47afb96a3f988e6d21a92fe4dfe875ab227c7c0Sean Silva    Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions);
39ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis  }
40ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis
415f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<const char *, 16> Args;
42ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis  Args.push_back("<clang>"); // FIXME: Remove dummy argument.
43ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis  Args.insert(Args.end(), ArgList.begin(), ArgList.end());
44ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis
45d6277fb9e0353edffc0d6c8655a65542c08cf6f1Argyrios Kyrtzidis  // FIXME: Find a cleaner way to force the driver into restricted modes.
46ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis  Args.push_back("-fsyntax-only");
47ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis
48ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis  // FIXME: We shouldn't have to pass in the path info.
495d8b9548420e67f1bf45b7bbc1cf9fb86e9e4505Sebastian Pop  driver::Driver TheDriver("clang", llvm::sys::getDefaultTargetTriple(),
506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                           *Diags);
51ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis
52ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis  // Don't check that inputs exist, they may have been remapped.
53ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis  TheDriver.setCheckInputsExist(false);
54ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis
55651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<driver::Compilation> C(TheDriver.BuildCompilation(Args));
56ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis
57ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis  // Just print the cc1 options if -### was present.
58ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis  if (C->getArgs().hasArg(driver::options::OPT__HASH_HASH_HASH)) {
59fc3389701ead32709ba84825e4c06651065da2c0Hans Wennborg    C->getJobs().Print(llvm::errs(), "\n", true);
606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
61ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis  }
62ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis
63ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis  // We expect to get back exactly one command job, if we didn't something
64ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis  // failed.
65ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis  const driver::JobList &Jobs = C->getJobs();
664d509341bd5db06a517daa311379f52bb540bc34Eli Friedman  if (Jobs.size() != 1 || !isa<driver::Command>(*Jobs.begin())) {
67f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith    SmallString<256> Msg;
68ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis    llvm::raw_svector_ostream OS(Msg);
69fc3389701ead32709ba84825e4c06651065da2c0Hans Wennborg    Jobs.Print(OS, "; ", true);
70ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis    Diags->Report(diag::err_fe_expected_compiler_job) << OS.str();
716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
72ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis  }
73ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis
74176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  const driver::Command &Cmd = cast<driver::Command>(*Jobs.begin());
75176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  if (StringRef(Cmd.getCreator().getName()) != "clang") {
76ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis    Diags->Report(diag::err_fe_expected_clang_command);
776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
78ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis  }
79ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis
80176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  const ArgStringList &CCArgs = Cmd.getArguments();
81651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<CompilerInvocation> CI(new CompilerInvocation());
828fdb6dee2da0dee97d64fe12eda46fb318414de9Dylan Noblesmith  if (!CompilerInvocation::CreateFromArgs(*CI,
83ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis                                     const_cast<const char **>(CCArgs.data()),
84ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis                                     const_cast<const char **>(CCArgs.data()) +
85ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis                                     CCArgs.size(),
868fdb6dee2da0dee97d64fe12eda46fb318414de9Dylan Noblesmith                                     *Diags))
876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
88651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return CI.release();
89ea383c0dffb78aea0c427a6ccf4490a5083fcb6aArgyrios Kyrtzidis}
90