mirror of
https://github.com/Gericom/teak-llvm.git
synced 2025-06-23 21:45:46 -04:00

Now FixedCompilationDatabase::loadFromCommandLine has no means to report which error occurred if it fails to create compilation object. This is a block for implementing D33013, because after that change driver will refuse to create compilation if command line contains erroneous options. This change adds additional argument to loadFromCommandLine, which is assigned error message text if compilation object was not created. This is the same way as other methods of CompilationDatabase report failure. Differential Revision: https://reviews.llvm.org/D33272 llvm-svn: 303741
107 lines
3.9 KiB
C++
107 lines
3.9 KiB
C++
//===--- CreateInvocationFromCommandLine.cpp - CompilerInvocation from Args ==//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Construct a compiler invocation object for command line driver arguments
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "clang/Frontend/Utils.h"
|
|
#include "clang/Basic/DiagnosticOptions.h"
|
|
#include "clang/Driver/Compilation.h"
|
|
#include "clang/Driver/Driver.h"
|
|
#include "clang/Driver/Action.h"
|
|
#include "clang/Driver/Options.h"
|
|
#include "clang/Driver/Tool.h"
|
|
#include "clang/Frontend/CompilerInstance.h"
|
|
#include "clang/Frontend/FrontendDiagnostic.h"
|
|
#include "llvm/Option/ArgList.h"
|
|
#include "llvm/Support/Host.h"
|
|
using namespace clang;
|
|
using namespace llvm::opt;
|
|
|
|
/// createInvocationFromCommandLine - 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.
|
|
std::unique_ptr<CompilerInvocation> clang::createInvocationFromCommandLine(
|
|
ArrayRef<const char *> ArgList,
|
|
IntrusiveRefCntPtr<DiagnosticsEngine> Diags) {
|
|
if (!Diags.get()) {
|
|
// No diagnostics engine was provided, so create our own diagnostics object
|
|
// with the default options.
|
|
Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions);
|
|
}
|
|
|
|
SmallVector<const char *, 16> Args(ArgList.begin(), ArgList.end());
|
|
|
|
// FIXME: Find a cleaner way to force the driver into restricted modes.
|
|
Args.push_back("-fsyntax-only");
|
|
|
|
// FIXME: We shouldn't have to pass in the path info.
|
|
driver::Driver TheDriver(Args[0], llvm::sys::getDefaultTargetTriple(),
|
|
*Diags);
|
|
|
|
// Don't check that inputs exist, they may have been remapped.
|
|
TheDriver.setCheckInputsExist(false);
|
|
|
|
std::unique_ptr<driver::Compilation> C(TheDriver.BuildCompilation(Args));
|
|
if (!C)
|
|
return nullptr;
|
|
|
|
// Just print the cc1 options if -### was present.
|
|
if (C->getArgs().hasArg(driver::options::OPT__HASH_HASH_HASH)) {
|
|
C->getJobs().Print(llvm::errs(), "\n", true);
|
|
return nullptr;
|
|
}
|
|
|
|
// We expect to get back exactly one command job, if we didn't something
|
|
// failed. Offload compilation is an exception as it creates multiple jobs. If
|
|
// that's the case, we proceed with the first job. If caller needs a
|
|
// particular job, it should be controlled via options (e.g.
|
|
// --cuda-{host|device}-only for CUDA) passed to the driver.
|
|
const driver::JobList &Jobs = C->getJobs();
|
|
bool OffloadCompilation = false;
|
|
if (Jobs.size() > 1) {
|
|
for (auto &A : C->getActions()){
|
|
// On MacOSX real actions may end up being wrapped in BindArchAction
|
|
if (isa<driver::BindArchAction>(A))
|
|
A = *A->input_begin();
|
|
if (isa<driver::OffloadAction>(A)) {
|
|
OffloadCompilation = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (Jobs.size() == 0 || !isa<driver::Command>(*Jobs.begin()) ||
|
|
(Jobs.size() > 1 && !OffloadCompilation)) {
|
|
SmallString<256> Msg;
|
|
llvm::raw_svector_ostream OS(Msg);
|
|
Jobs.Print(OS, "; ", true);
|
|
Diags->Report(diag::err_fe_expected_compiler_job) << OS.str();
|
|
return nullptr;
|
|
}
|
|
|
|
const driver::Command &Cmd = cast<driver::Command>(*Jobs.begin());
|
|
if (StringRef(Cmd.getCreator().getName()) != "clang") {
|
|
Diags->Report(diag::err_fe_expected_clang_command);
|
|
return nullptr;
|
|
}
|
|
|
|
const ArgStringList &CCArgs = Cmd.getArguments();
|
|
auto CI = llvm::make_unique<CompilerInvocation>();
|
|
if (!CompilerInvocation::CreateFromArgs(*CI,
|
|
const_cast<const char **>(CCArgs.data()),
|
|
const_cast<const char **>(CCArgs.data()) +
|
|
CCArgs.size(),
|
|
*Diags))
|
|
return nullptr;
|
|
return CI;
|
|
}
|