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())
347 if (Arg *A = Args.getLastArg(clang::driver::options::OPT_rtlib_EQ)) {
348 StringRef
Value = A->getValue();
349 if (
Value !=
"compiler-rt")
351 << A->getAsString(Args);
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,
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");
477 Res |= SanitizerKind::Address;
478 Res |= SanitizerKind::HWAddress;
479 Res |= SanitizerKind::PointerCompare;
480 Res |= SanitizerKind::PointerSubtract;
481 Res |= SanitizerKind::Fuzzer;
482 Res |= SanitizerKind::FuzzerNoLink;
483 Res |= SanitizerKind::Leak;
484 Res |= SanitizerKind::SafeStack;
485 Res |= SanitizerKind::Scudo;
486 Res |= SanitizerKind::Thread;
493 case llvm::Triple::aarch64:
494 case llvm::Triple::riscv64:
495 Res |= SanitizerKind::ShadowCallStack;
497 case llvm::Triple::x86_64:
498 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()