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");
220 Args.AddAllArgValues(CmdArgs, options::OPT_Xstatic_lib_tool);
223 for (
const auto &II : Inputs) {
224 if (II.isFilename()) {
225 CmdArgs.push_back(II.getFilename());
232 if (Output.
isFilename() && llvm::sys::fs::exists(OutputFileName)) {
233 if (std::error_code EC = llvm::sys::fs::remove(OutputFileName)) {
234 D.
Diag(diag::err_drv_unable_to_remove_file) << EC.message();
239 const char *Exec = Args.MakeArgString(
getToolChain().GetStaticLibToolPath());
240 C.addCommand(std::make_unique<Command>(JA, *
this,
242 Exec, CmdArgs, Inputs, Output));
252 if (!D.SysRoot.empty()) {
254 llvm::sys::path::append(P,
"lib");
258 auto FilePaths = [&](
const Multilib &M) -> std::vector<std::string> {
259 std::vector<std::string> FP;
262 llvm::sys::path::append(P, M.gccSuffix());
263 FP.push_back(std::string(P));
271 .
flag(
"-fexceptions",
true)
272 .flag(
"-fno-exceptions")
276 .
flag(
"-fsanitize=address")
280 .
flag(
"-fsanitize=address")
281 .flag(
"-fexceptions",
true)
282 .flag(
"-fno-exceptions")
287 .
flag(
"-fsanitize=hwaddress")
291 .
flag(
"-fsanitize=hwaddress")
292 .flag(
"-fexceptions",
true)
293 .flag(
"-fno-exceptions")
297 .
flag(
"-fc++-abi=itanium")
301 std::vector<std::string> RD = FilePaths(M);
302 return llvm::all_of(RD, [&](std::string P) {
return !
getVFS().exists(P); });
307 Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions,
true);
313 "-fsanitize=hwaddress", Flags);
315 addMultilibFlag(Args.getLastArgValue(options::OPT_fcxx_abi_EQ) ==
"itanium",
316 "-fc++-abi=itanium", Flags);
318 Multilibs.setFilePathsCallback(FilePaths);
326 if (
const auto &PathsCallback =
Multilibs.filePathsCallback())
348 if (Arg *A = Args.getLastArg(options::OPT_rtlib_EQ)) {
349 StringRef
Value = A->getValue();
350 if (
Value !=
"compiler-rt" &&
Value !=
"platform")
351 getDriver().
Diag(clang::diag::err_drv_unsupported_rtlib_for_platform)
352 <<
Value <<
"Fuchsia";
359 if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
360 StringRef
Value = A->getValue();
361 if (
Value !=
"libc++")
363 << A->getAsString(Args);
372 if (!DriverArgs.hasFlag(options::OPT_fuse_init_array,
373 options::OPT_fno_use_init_array,
true))
374 CC1Args.push_back(
"-fno-use-init-array");
378 ArgStringList &CC1Args)
const {
381 if (DriverArgs.hasArg(options::OPT_nostdinc))
384 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
386 llvm::sys::path::append(P,
"include");
390 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
394 StringRef CIncludeDirs(C_INCLUDE_DIRS);
395 if (CIncludeDirs !=
"") {
397 CIncludeDirs.split(dirs,
":");
398 for (StringRef dir : dirs) {
400 llvm::sys::path::is_absolute(dir) ?
"" : StringRef(D.SysRoot);
406 if (!D.SysRoot.empty()) {
408 llvm::sys::path::append(P,
"include");
414 ArgStringList &CC1Args)
const {
415 if (DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdlibinc,
416 options::OPT_nostdincxx))
422 auto AddCXXIncludePath = [&](StringRef Path) {
431 llvm::sys::path::append(TargetDir,
Target, M.
gccSuffix(),
"c++", Version);
432 if (
getVFS().exists(TargetDir)) {
439 llvm::sys::path::append(TargetDir,
Target,
"c++", Version);
440 if (
getVFS().exists(TargetDir))
445 llvm::sys::path::append(Dir,
"c++", Version);
452 llvm::sys::path::append(P,
"..",
"include");
453 AddCXXIncludePath(P);
458 llvm_unreachable(
"invalid stdlib name");
463 ArgStringList &CmdArgs)
const {
466 CmdArgs.push_back(
"-lc++");
467 if (Args.hasArg(options::OPT_fexperimental_library))
468 CmdArgs.push_back(
"-lc++experimental");
472 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
Top level wrappers for InstallAPI frontend operations.
Represents a bound architecture for offload / multiple architecture compilation.
static constexpr ResponseFileSupport AtFileCurCP()