Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp
35232 views
1
//===--- CreateInvocationFromCommandLine.cpp - CompilerInvocation from Args ==//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// Construct a compiler invocation object for command line driver arguments
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "clang/Basic/DiagnosticOptions.h"
14
#include "clang/Driver/Action.h"
15
#include "clang/Driver/Compilation.h"
16
#include "clang/Driver/Driver.h"
17
#include "clang/Driver/Options.h"
18
#include "clang/Driver/Tool.h"
19
#include "clang/Frontend/CompilerInstance.h"
20
#include "clang/Frontend/FrontendDiagnostic.h"
21
#include "clang/Frontend/Utils.h"
22
#include "llvm/ADT/STLExtras.h"
23
#include "llvm/ADT/StringRef.h"
24
#include "llvm/Option/ArgList.h"
25
#include "llvm/TargetParser/Host.h"
26
using namespace clang;
27
using namespace llvm::opt;
28
29
std::unique_ptr<CompilerInvocation>
30
clang::createInvocation(ArrayRef<const char *> ArgList,
31
CreateInvocationOptions Opts) {
32
assert(!ArgList.empty());
33
auto Diags = Opts.Diags
34
? std::move(Opts.Diags)
35
: CompilerInstance::createDiagnostics(new DiagnosticOptions);
36
37
SmallVector<const char *, 16> Args(ArgList.begin(), ArgList.end());
38
39
// FIXME: Find a cleaner way to force the driver into restricted modes.
40
Args.insert(
41
llvm::find_if(
42
Args, [](const char *Elem) { return llvm::StringRef(Elem) == "--"; }),
43
"-fsyntax-only");
44
45
// FIXME: We shouldn't have to pass in the path info.
46
driver::Driver TheDriver(Args[0], llvm::sys::getDefaultTargetTriple(), *Diags,
47
"clang LLVM compiler", Opts.VFS);
48
49
// Don't check that inputs exist, they may have been remapped.
50
TheDriver.setCheckInputsExist(false);
51
TheDriver.setProbePrecompiled(Opts.ProbePrecompiled);
52
53
std::unique_ptr<driver::Compilation> C(TheDriver.BuildCompilation(Args));
54
if (!C)
55
return nullptr;
56
57
if (C->getArgs().hasArg(driver::options::OPT_fdriver_only))
58
return nullptr;
59
60
// Just print the cc1 options if -### was present.
61
if (C->getArgs().hasArg(driver::options::OPT__HASH_HASH_HASH)) {
62
C->getJobs().Print(llvm::errs(), "\n", true);
63
return nullptr;
64
}
65
66
// We expect to get back exactly one command job, if we didn't something
67
// failed. Offload compilation is an exception as it creates multiple jobs. If
68
// that's the case, we proceed with the first job. If caller needs a
69
// particular job, it should be controlled via options (e.g.
70
// --cuda-{host|device}-only for CUDA) passed to the driver.
71
const driver::JobList &Jobs = C->getJobs();
72
bool OffloadCompilation = false;
73
if (Jobs.size() > 1) {
74
for (auto &A : C->getActions()){
75
// On MacOSX real actions may end up being wrapped in BindArchAction
76
if (isa<driver::BindArchAction>(A))
77
A = *A->input_begin();
78
if (isa<driver::OffloadAction>(A)) {
79
OffloadCompilation = true;
80
break;
81
}
82
}
83
}
84
85
bool PickFirstOfMany = OffloadCompilation || Opts.RecoverOnError;
86
if (Jobs.size() == 0 || (Jobs.size() > 1 && !PickFirstOfMany)) {
87
SmallString<256> Msg;
88
llvm::raw_svector_ostream OS(Msg);
89
Jobs.Print(OS, "; ", true);
90
Diags->Report(diag::err_fe_expected_compiler_job) << OS.str();
91
return nullptr;
92
}
93
auto Cmd = llvm::find_if(Jobs, [](const driver::Command &Cmd) {
94
return StringRef(Cmd.getCreator().getName()) == "clang";
95
});
96
if (Cmd == Jobs.end()) {
97
Diags->Report(diag::err_fe_expected_clang_command);
98
return nullptr;
99
}
100
101
const ArgStringList &CCArgs = Cmd->getArguments();
102
if (Opts.CC1Args)
103
*Opts.CC1Args = {CCArgs.begin(), CCArgs.end()};
104
auto CI = std::make_unique<CompilerInvocation>();
105
if (!CompilerInvocation::CreateFromArgs(*CI, CCArgs, *Diags, Args[0]) &&
106
!Opts.RecoverOnError)
107
return nullptr;
108
return CI;
109
}
110
111