11#include "clang/Config/config.h"
18#include "llvm/Option/ArgList.h"
19#include "llvm/ProfileData/InstrProf.h"
20#include "llvm/Support/FileSystem.h"
21#include "llvm/Support/Path.h"
22#include "llvm/Support/VirtualFileSystem.h"
36 const char *LinkingOutput)
const {
42 ArgStringList CmdArgs;
45 Args.ClaimAllArgs(options::OPT_g_Group);
47 Args.ClaimAllArgs(options::OPT_emit_llvm);
50 Args.ClaimAllArgs(options::OPT_w);
52 CmdArgs.push_back(
"-z");
53 CmdArgs.push_back(
"max-page-size=4096");
55 CmdArgs.push_back(
"-z");
56 CmdArgs.push_back(
"now");
58 CmdArgs.push_back(
"-z");
59 CmdArgs.push_back(
"start-stop-visibility=hidden");
62 if (llvm::sys::path::filename(Exec).equals_insensitive(
"ld.lld") ||
63 llvm::sys::path::stem(Exec).equals_insensitive(
"ld.lld")) {
64 CmdArgs.push_back(
"-z");
65 CmdArgs.push_back(
"rodynamic");
66 CmdArgs.push_back(
"-z");
67 CmdArgs.push_back(
"separate-loadable-segments");
68 CmdArgs.push_back(
"-z");
69 CmdArgs.push_back(
"rel");
70 CmdArgs.push_back(
"--pack-dyn-relocs=relr");
73 if (!
D.SysRoot.empty())
74 CmdArgs.push_back(Args.MakeArgString(
"--sysroot=" +
D.SysRoot));
76 if (!Args.hasArg(options::OPT_shared) && !Args.hasArg(options::OPT_r))
77 CmdArgs.push_back(
"-pie");
79 if (Args.hasArg(options::OPT_rdynamic))
80 CmdArgs.push_back(
"-export-dynamic");
82 if (Args.hasArg(options::OPT_s))
83 CmdArgs.push_back(
"-s");
85 if (Args.hasArg(options::OPT_r)) {
86 CmdArgs.push_back(
"-r");
88 CmdArgs.push_back(
"--build-id");
89 CmdArgs.push_back(
"--hash-style=gnu");
93 CmdArgs.push_back(
"--execute-only");
96 if (CPU.empty() || CPU ==
"generic" || CPU ==
"cortex-a53")
97 CmdArgs.push_back(
"--fix-cortex-a53-843419");
100 CmdArgs.push_back(
"--eh-frame-hdr");
102 if (Args.hasArg(options::OPT_static))
103 CmdArgs.push_back(
"-Bstatic");
104 else if (Args.hasArg(options::OPT_shared))
105 CmdArgs.push_back(
"-shared");
109 if (!Args.hasArg(options::OPT_shared) && !Args.hasArg(options::OPT_r)) {
110 std::string Dyld =
D.DyldPrefix;
118 CmdArgs.push_back(
"-dynamic-linker");
119 CmdArgs.push_back(Args.MakeArgString(Dyld));
122 if (Triple.isRISCV64()) {
123 CmdArgs.push_back(
"-X");
124 if (Args.hasArg(options::OPT_mno_relax))
125 CmdArgs.push_back(
"--no-relax");
128 CmdArgs.push_back(
"-o");
131 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles,
133 if (!Args.hasArg(options::OPT_shared)) {
138 Args.addAllArgs(CmdArgs, {options::OPT_L, options::OPT_u});
142 if (
D.isUsingLTO()) {
143 assert(!Inputs.empty() &&
"Must have at least one input.");
145 auto Input = llvm::find_if(
147 if (Input == Inputs.end())
150 Input = Inputs.begin();
160 bool NoLibc = Args.hasArg(options::OPT_nolibc);
161 bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
162 !Args.hasArg(options::OPT_static);
163 bool Pthreads = Args.hasArg(options::OPT_pthread, options::OPT_pthreads);
164 bool SplitStack = Args.hasArg(options::OPT_fsplit_stack);
165 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs,
167 if (Args.hasArg(options::OPT_static))
168 CmdArgs.push_back(
"-Bdynamic");
172 CmdArgs.push_back(
"--push-state");
173 CmdArgs.push_back(
"--as-needed");
174 if (OnlyLibstdcxxStatic)
175 CmdArgs.push_back(
"-Bstatic");
177 if (OnlyLibstdcxxStatic)
178 CmdArgs.push_back(
"-Bdynamic");
179 CmdArgs.push_back(
"-lm");
180 CmdArgs.push_back(
"--pop-state");
196 CmdArgs.push_back(
"-lpthread");
199 CmdArgs.push_back(
"--wrap=pthread_create");
202 CmdArgs.push_back(
"-lc");
205 C.addCommand(std::make_unique<Command>(JA, *
this,
207 Exec, CmdArgs, Inputs, Output));
214 const char *LinkingOutput)
const {
215 const Driver &
D = getToolChain().getDriver();
218 Args.ClaimAllArgs(options::OPT_g_Group);
220 Args.ClaimAllArgs(options::OPT_emit_llvm);
223 Args.ClaimAllArgs(options::OPT_w);
225 Args.ClaimAllArgs(options::OPT_stdlib_EQ);
228 ArgStringList CmdArgs;
230 CmdArgs.push_back(
"rcsD");
233 for (
const auto &II : Inputs) {
234 if (II.isFilename()) {
235 CmdArgs.push_back(II.getFilename());
242 if (Output.
isFilename() && llvm::sys::fs::exists(OutputFileName)) {
243 if (std::error_code EC = llvm::sys::fs::remove(OutputFileName)) {
244 D.Diag(diag::err_drv_unable_to_remove_file) << EC.message();
249 const char *Exec = Args.MakeArgString(getToolChain().GetStaticLibToolPath());
250 C.addCommand(std::make_unique<Command>(JA, *
this,
252 Exec, CmdArgs, Inputs, Output));
262 if (!
D.SysRoot.empty()) {
264 llvm::sys::path::append(
P,
"lib");
268 auto FilePaths = [&](
const Multilib &M) -> std::vector<std::string> {
269 std::vector<std::string> FP;
272 llvm::sys::path::append(
P, M.gccSuffix());
273 FP.push_back(std::string(
P));
281 .flag(
"-fexceptions",
true)
282 .flag(
"-fno-exceptions")
286 .flag(
"-fsanitize=address")
290 .flag(
"-fsanitize=address")
291 .flag(
"-fexceptions",
true)
292 .flag(
"-fno-exceptions")
297 .flag(
"-fsanitize=hwaddress")
301 .flag(
"-fsanitize=hwaddress")
302 .flag(
"-fexceptions",
true)
303 .flag(
"-fno-exceptions")
307 .flag(
"-fc++-abi=itanium")
311 std::vector<std::string> RD = FilePaths(M);
312 return llvm::all_of(RD, [&](std::string
P) {
return !
getVFS().exists(
P); });
317 Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions,
true);
323 "-fsanitize=hwaddress", Flags);
325 addMultilibFlag(Args.getLastArgValue(options::OPT_fcxx_abi_EQ) ==
"itanium",
326 "-fc++-abi=itanium", Flags);
357 if (Arg *A = Args.getLastArg(clang::driver::options::OPT_rtlib_EQ)) {
358 StringRef
Value = A->getValue();
359 if (
Value !=
"compiler-rt")
361 << A->getAsString(Args);
368 if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
369 StringRef
Value = A->getValue();
370 if (
Value !=
"libc++")
372 << A->getAsString(Args);
379 ArgStringList &CC1Args,
381 if (!DriverArgs.hasFlag(options::OPT_fuse_init_array,
382 options::OPT_fno_use_init_array,
true))
383 CC1Args.push_back(
"-fno-use-init-array");
387 ArgStringList &CC1Args)
const {
390 if (DriverArgs.hasArg(options::OPT_nostdinc))
393 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
395 llvm::sys::path::append(
P,
"include");
399 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
403 StringRef CIncludeDirs(C_INCLUDE_DIRS);
404 if (CIncludeDirs !=
"") {
406 CIncludeDirs.split(dirs,
":");
407 for (StringRef dir : dirs) {
409 llvm::sys::path::is_absolute(dir) ?
"" : StringRef(
D.SysRoot);
415 if (!
D.SysRoot.empty()) {
417 llvm::sys::path::append(
P,
"include");
423 ArgStringList &CC1Args)
const {
424 if (DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdlibinc,
425 options::OPT_nostdincxx))
431 auto AddCXXIncludePath = [&](StringRef
Path) {
440 llvm::sys::path::append(TargetDir,
Target, M.
gccSuffix(),
"c++", Version);
441 if (
getVFS().exists(TargetDir)) {
448 llvm::sys::path::append(TargetDir,
Target,
"c++", Version);
449 if (
getVFS().exists(TargetDir))
454 llvm::sys::path::append(Dir,
"c++", Version);
461 llvm::sys::path::append(
P,
"..",
"include");
462 AddCXXIncludePath(
P);
467 llvm_unreachable(
"invalid stdlib name");
472 ArgStringList &CmdArgs)
const {
475 CmdArgs.push_back(
"-lc++");
476 if (Args.hasArg(options::OPT_fexperimental_library))
477 CmdArgs.push_back(
"-lc++experimental");
481 llvm_unreachable(
"invalid stdlib name");
487 Res |= SanitizerKind::Address;
488 Res |= SanitizerKind::HWAddress;
489 Res |= SanitizerKind::PointerCompare;
490 Res |= SanitizerKind::PointerSubtract;
491 Res |= SanitizerKind::Fuzzer;
492 Res |= SanitizerKind::FuzzerNoLink;
493 Res |= SanitizerKind::Leak;
494 Res |= SanitizerKind::SafeStack;
495 Res |= SanitizerKind::Scudo;
496 Res |= SanitizerKind::Thread;
503 case llvm::Triple::aarch64:
504 case llvm::Triple::riscv64:
505 Res |= SanitizerKind::ShadowCallStack;
507 case llvm::Triple::x86_64:
508 Res |= SanitizerKind::SafeStack;
llvm::MachO::Target Target
Compilation - A set of tasks to perform for a single driver invocation.
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
DiagnosticBuilder Diag(unsigned DiagID) const
This corresponds to a single GCC multilib, or a segment of one controlled by a command line flag.
MultilibSet & setFilePathsCallback(IncludeDirsFunc F)
MultilibSet & FilterOut(FilterCallback F)
Filter out some subset of the Multilibs using a user defined callback.
const IncludeDirsFunc & filePathsCallback() const
void push_back(const Multilib &M)
Add a completed Multilib to the set.
bool select(const Driver &D, const Multilib::flags_list &Flags, llvm::SmallVectorImpl< Multilib > &) const
Select compatible variants,.
This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag.
const std::string & gccSuffix() const
Get the detected GCC installation path suffix for the multi-arch target variant.
std::vector< std::string > flags_list
bool needsHwasanRt() const
bool needsSharedRt() const
The JSON file list parser is used to communicate input to InstallAPI.
static constexpr ResponseFileSupport AtFileCurCP()