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});
150 bool NoLibc = Args.hasArg(options::OPT_nolibc);
151 bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
152 !Args.hasArg(options::OPT_static);
153 bool Pthreads = Args.hasArg(options::OPT_pthread, options::OPT_pthreads);
154 bool SplitStack = Args.hasArg(options::OPT_fsplit_stack);
155 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs,
157 if (Args.hasArg(options::OPT_static))
158 CmdArgs.push_back(
"-Bdynamic");
162 CmdArgs.push_back(
"--push-state");
163 CmdArgs.push_back(
"--as-needed");
164 if (OnlyLibstdcxxStatic)
165 CmdArgs.push_back(
"-Bstatic");
167 if (OnlyLibstdcxxStatic)
168 CmdArgs.push_back(
"-Bdynamic");
169 CmdArgs.push_back(
"-lm");
170 CmdArgs.push_back(
"--pop-state");
186 CmdArgs.push_back(
"-lpthread");
189 CmdArgs.push_back(
"--wrap=pthread_create");
192 CmdArgs.push_back(
"-lc");
195 C.addCommand(std::make_unique<Command>(JA, *
this,
197 Exec, CmdArgs, Inputs, Output));
204 const char *LinkingOutput)
const {
208 Args.ClaimAllArgs(options::OPT_g_Group);
210 Args.ClaimAllArgs(options::OPT_emit_llvm);
213 Args.ClaimAllArgs(options::OPT_w);
215 Args.ClaimAllArgs(options::OPT_stdlib_EQ);
218 ArgStringList CmdArgs;
220 CmdArgs.push_back(
"rcsD");
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())
334 llvm::StringRef BoundArch,
348 if (Arg *A = Args.getLastArg(options::OPT_rtlib_EQ)) {
349 StringRef
Value = A->getValue();
350 if (
Value !=
"compiler-rt")
352 << A->getAsString(Args);
359 if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
360 StringRef
Value = A->getValue();
361 if (
Value !=
"libc++")
363 << A->getAsString(Args);
370 ArgStringList &CC1Args,
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");
478 Res |= SanitizerKind::Address;
479 Res |= SanitizerKind::HWAddress;
480 Res |= SanitizerKind::PointerCompare;
481 Res |= SanitizerKind::PointerSubtract;
482 Res |= SanitizerKind::Fuzzer;
483 Res |= SanitizerKind::FuzzerNoLink;
484 Res |= SanitizerKind::Leak;
485 Res |= SanitizerKind::Scudo;
486 Res |= SanitizerKind::Thread;
489 Res |= SanitizerKind::SafeStack;
497 case llvm::Triple::aarch64:
498 case llvm::Triple::riscv64:
499 Res |= SanitizerKind::ShadowCallStack;
501 case llvm::Triple::x86:
502 case llvm::Triple::x86_64:
503 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 isUsingLTO() const
Returns true if we are performing any kind of LTO.
LTOKind getLTOMode() const
Get the specific kind of LTO being performed.
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()