10#include "clang/Config/config.h"
17#include "llvm/Option/ArgList.h"
18#include "llvm/Support/FileSystem.h"
19#include "llvm/Support/Path.h"
20#include "llvm/Support/VirtualFileSystem.h"
34 const char *LinkingOutput)
const {
40 ArgStringList CmdArgs;
43 Args.ClaimAllArgs(options::OPT_g_Group);
45 Args.ClaimAllArgs(options::OPT_emit_llvm);
48 Args.ClaimAllArgs(options::OPT_w);
50 CmdArgs.push_back(
"-z");
51 CmdArgs.push_back(
"max-page-size=4096");
53 CmdArgs.push_back(
"-z");
54 CmdArgs.push_back(
"now");
56 CmdArgs.push_back(
"-z");
57 CmdArgs.push_back(
"start-stop-visibility=hidden");
60 if (llvm::sys::path::filename(Exec).equals_insensitive(
"ld.lld") ||
61 llvm::sys::path::stem(Exec).equals_insensitive(
"ld.lld")) {
62 CmdArgs.push_back(
"-z");
63 CmdArgs.push_back(
"rodynamic");
64 CmdArgs.push_back(
"-z");
65 CmdArgs.push_back(
"separate-loadable-segments");
66 CmdArgs.push_back(
"-z");
67 CmdArgs.push_back(
"rel");
68 CmdArgs.push_back(
"--pack-dyn-relocs=relr");
72 CmdArgs.push_back(Args.MakeArgString(
"--sysroot=" + D.
SysRoot));
74 if (!Args.hasArg(options::OPT_shared) && !Args.hasArg(options::OPT_r))
75 CmdArgs.push_back(
"-pie");
77 if (Args.hasArg(options::OPT_rdynamic))
78 CmdArgs.push_back(
"-export-dynamic");
80 if (Args.hasArg(options::OPT_s))
81 CmdArgs.push_back(
"-s");
83 if (Args.hasArg(options::OPT_r)) {
84 CmdArgs.push_back(
"-r");
86 CmdArgs.push_back(
"--build-id");
87 CmdArgs.push_back(
"--hash-style=gnu");
91 CmdArgs.push_back(
"--execute-only");
94 if (Args.hasFlag(options::OPT_mfix_cortex_a53_843419,
95 options::OPT_mno_fix_cortex_a53_843419,
true) &&
96 (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)) {
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});
149 bool NoLibc = Args.hasArg(options::OPT_nolibc);
150 bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
151 !Args.hasArg(options::OPT_static);
152 bool Pthreads = Args.hasArg(options::OPT_pthread, options::OPT_pthreads);
153 bool SplitStack = Args.hasArg(options::OPT_fsplit_stack);
154 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs,
156 if (Args.hasArg(options::OPT_static))
157 CmdArgs.push_back(
"-Bdynamic");
161 CmdArgs.push_back(
"--push-state");
162 CmdArgs.push_back(
"--as-needed");
163 if (OnlyLibstdcxxStatic)
164 CmdArgs.push_back(
"-Bstatic");
166 if (OnlyLibstdcxxStatic)
167 CmdArgs.push_back(
"-Bdynamic");
168 CmdArgs.push_back(
"-lm");
169 CmdArgs.push_back(
"--pop-state");
185 CmdArgs.push_back(
"-lpthread");
188 CmdArgs.push_back(
"--wrap=pthread_create");
191 CmdArgs.push_back(
"-lc");
194 C.addCommand(std::make_unique<Command>(JA, *
this,
196 Exec, CmdArgs, Inputs, Output));
203 const char *LinkingOutput)
const {
207 Args.ClaimAllArgs(options::OPT_g_Group);
209 Args.ClaimAllArgs(options::OPT_emit_llvm);
212 Args.ClaimAllArgs(options::OPT_w);
214 Args.ClaimAllArgs(options::OPT_stdlib_EQ);
217 ArgStringList CmdArgs;
219 CmdArgs.push_back(
"rcsD");
222 for (
const auto &II : Inputs) {
223 if (II.isFilename()) {
224 CmdArgs.push_back(II.getFilename());
231 if (Output.
isFilename() && llvm::sys::fs::exists(OutputFileName)) {
232 if (std::error_code EC = llvm::sys::fs::remove(OutputFileName)) {
233 D.
Diag(diag::err_drv_unable_to_remove_file) << EC.message();
238 const char *Exec = Args.MakeArgString(
getToolChain().GetStaticLibToolPath());
239 C.addCommand(std::make_unique<Command>(JA, *
this,
241 Exec, CmdArgs, Inputs, Output));
251 if (!D.SysRoot.empty()) {
253 llvm::sys::path::append(P,
"lib");
257 auto FilePaths = [&](
const Multilib &M) -> std::vector<std::string> {
258 std::vector<std::string> FP;
261 llvm::sys::path::append(P, M.gccSuffix());
262 FP.push_back(std::string(P));
270 .
flag(
"-fexceptions",
true)
271 .flag(
"-fno-exceptions")
275 .
flag(
"-fsanitize=address")
279 .
flag(
"-fsanitize=address")
280 .flag(
"-fexceptions",
true)
281 .flag(
"-fno-exceptions")
286 .
flag(
"-fsanitize=hwaddress")
290 .
flag(
"-fsanitize=hwaddress")
291 .flag(
"-fexceptions",
true)
292 .flag(
"-fno-exceptions")
296 .
flag(
"-fc++-abi=itanium")
300 std::vector<std::string> RD = FilePaths(M);
301 return llvm::all_of(RD, [&](std::string P) {
return !
getVFS().exists(P); });
306 Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions,
true);
312 "-fsanitize=hwaddress", Flags);
314 addMultilibFlag(Args.getLastArgValue(options::OPT_fcxx_abi_EQ) ==
"itanium",
315 "-fc++-abi=itanium", Flags);
317 Multilibs.setFilePathsCallback(FilePaths);
325 if (
const auto &PathsCallback =
Multilibs.filePathsCallback())
333 llvm::StringRef BoundArch,
347 if (Arg *A = Args.getLastArg(options::OPT_rtlib_EQ)) {
348 StringRef
Value = A->getValue();
349 if (
Value !=
"compiler-rt" &&
Value !=
"platform")
350 getDriver().
Diag(clang::diag::err_drv_unsupported_rtlib_for_platform)
351 <<
Value <<
"Fuchsia";
358 if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
359 StringRef
Value = A->getValue();
360 if (
Value !=
"libc++")
362 << A->getAsString(Args);
369 ArgStringList &CC1Args, StringRef BoundArch,
371 if (!DriverArgs.hasFlag(options::OPT_fuse_init_array,
372 options::OPT_fno_use_init_array,
true))
373 CC1Args.push_back(
"-fno-use-init-array");
377 ArgStringList &CC1Args)
const {
380 if (DriverArgs.hasArg(options::OPT_nostdinc))
383 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
385 llvm::sys::path::append(P,
"include");
389 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
393 StringRef CIncludeDirs(C_INCLUDE_DIRS);
394 if (CIncludeDirs !=
"") {
396 CIncludeDirs.split(dirs,
":");
397 for (StringRef dir : dirs) {
399 llvm::sys::path::is_absolute(dir) ?
"" : StringRef(D.SysRoot);
405 if (!D.SysRoot.empty()) {
407 llvm::sys::path::append(P,
"include");
413 ArgStringList &CC1Args)
const {
414 if (DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdlibinc,
415 options::OPT_nostdincxx))
421 auto AddCXXIncludePath = [&](StringRef Path) {
430 llvm::sys::path::append(TargetDir,
Target, M.
gccSuffix(),
"c++", Version);
431 if (
getVFS().exists(TargetDir)) {
438 llvm::sys::path::append(TargetDir,
Target,
"c++", Version);
439 if (
getVFS().exists(TargetDir))
444 llvm::sys::path::append(Dir,
"c++", Version);
451 llvm::sys::path::append(P,
"..",
"include");
452 AddCXXIncludePath(P);
457 llvm_unreachable(
"invalid stdlib name");
462 ArgStringList &CmdArgs)
const {
465 CmdArgs.push_back(
"-lc++");
466 if (Args.hasArg(options::OPT_fexperimental_library))
467 CmdArgs.push_back(
"-lc++experimental");
471 llvm_unreachable(
"invalid stdlib name");
480 Res |= SanitizerKind::Address;
481 Res |= SanitizerKind::HWAddress;
482 Res |= SanitizerKind::PointerCompare;
483 Res |= SanitizerKind::PointerSubtract;
484 Res |= SanitizerKind::Fuzzer;
485 Res |= SanitizerKind::FuzzerNoLink;
486 Res |= SanitizerKind::Leak;
487 Res |= SanitizerKind::Scudo;
488 Res |= SanitizerKind::Thread;
491 Res |= SanitizerKind::SafeStack;
499 case llvm::Triple::aarch64:
500 case llvm::Triple::riscv64:
501 Res |= SanitizerKind::ShadowCallStack;
503 case llvm::Triple::x86:
504 case llvm::Triple::x86_64:
505 Res |= SanitizerKind::SafeStack;
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...
std::string SysRoot
sysroot, if present
std::string DyldPrefix
Dynamic loader prefix, if present.
DiagnosticBuilder Diag(unsigned DiagID) const
bool CCCIsCXX() const
Whether the driver should follow g++ like behavior.
This corresponds to a single GCC multilib, or a segment of one controlled by a command line flag.
MultilibBuilder & flag(StringRef Flag, bool Disallow=false)
Add a flag to the flags list Flag must be a flag accepted by the driver.
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
SmallVector< InputInfo, 4 > InputInfoList
The JSON file list parser is used to communicate input to InstallAPI.
static constexpr ResponseFileSupport AtFileCurCP()