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 {
43 ArgStringList CmdArgs;
46 Args.ClaimAllArgs(options::OPT_g_Group);
48 Args.ClaimAllArgs(options::OPT_emit_llvm);
51 Args.ClaimAllArgs(options::OPT_w);
53 CmdArgs.push_back(
"-z");
54 CmdArgs.push_back(
"max-page-size=4096");
56 CmdArgs.push_back(
"-z");
57 CmdArgs.push_back(
"now");
59 CmdArgs.push_back(
"-z");
60 CmdArgs.push_back(
"start-stop-visibility=hidden");
63 if (llvm::sys::path::filename(Exec).equals_insensitive(
"ld.lld") ||
64 llvm::sys::path::stem(Exec).equals_insensitive(
"ld.lld")) {
65 CmdArgs.push_back(
"-z");
66 CmdArgs.push_back(
"rodynamic");
67 CmdArgs.push_back(
"-z");
68 CmdArgs.push_back(
"separate-loadable-segments");
69 CmdArgs.push_back(
"-z");
70 CmdArgs.push_back(
"rel");
71 CmdArgs.push_back(
"--pack-dyn-relocs=relr");
75 CmdArgs.push_back(Args.MakeArgString(
"--sysroot=" + D.
SysRoot));
77 if (!Args.hasArg(options::OPT_shared) && !Args.hasArg(options::OPT_r))
78 CmdArgs.push_back(
"-pie");
80 if (Args.hasArg(options::OPT_rdynamic))
81 CmdArgs.push_back(
"-export-dynamic");
83 if (Args.hasArg(options::OPT_s))
84 CmdArgs.push_back(
"-s");
86 if (Args.hasArg(options::OPT_r)) {
87 CmdArgs.push_back(
"-r");
89 CmdArgs.push_back(
"--build-id");
90 CmdArgs.push_back(
"--hash-style=gnu");
94 CmdArgs.push_back(
"--execute-only");
97 if (CPU.empty() || CPU ==
"generic" || CPU ==
"cortex-a53")
98 CmdArgs.push_back(
"--fix-cortex-a53-843419");
101 CmdArgs.push_back(
"--eh-frame-hdr");
103 if (Args.hasArg(options::OPT_static))
104 CmdArgs.push_back(
"-Bstatic");
105 else if (Args.hasArg(options::OPT_shared))
106 CmdArgs.push_back(
"-shared");
110 if (!Args.hasArg(options::OPT_shared) && !Args.hasArg(options::OPT_r)) {
119 CmdArgs.push_back(
"-dynamic-linker");
120 CmdArgs.push_back(Args.MakeArgString(Dyld));
124 CmdArgs.push_back(
"-X");
126 CmdArgs.push_back(
"-o");
129 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles,
131 if (!Args.hasArg(options::OPT_shared)) {
136 Args.AddAllArgs(CmdArgs, options::OPT_L);
137 Args.AddAllArgs(CmdArgs, options::OPT_u);
142 assert(!Inputs.empty() &&
"Must have at least one input.");
150 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs,
152 if (Args.hasArg(options::OPT_static))
153 CmdArgs.push_back(
"-Bdynamic");
157 bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
158 !Args.hasArg(options::OPT_static);
159 CmdArgs.push_back(
"--push-state");
160 CmdArgs.push_back(
"--as-needed");
161 if (OnlyLibstdcxxStatic)
162 CmdArgs.push_back(
"-Bstatic");
164 if (OnlyLibstdcxxStatic)
165 CmdArgs.push_back(
"-Bdynamic");
166 CmdArgs.push_back(
"-lm");
167 CmdArgs.push_back(
"--pop-state");
182 if (Args.hasArg(options::OPT_pthread) ||
183 Args.hasArg(options::OPT_pthreads))
184 CmdArgs.push_back(
"-lpthread");
186 if (Args.hasArg(options::OPT_fsplit_stack))
187 CmdArgs.push_back(
"--wrap=pthread_create");
189 if (!Args.hasArg(options::OPT_nolibc))
190 CmdArgs.push_back(
"-lc");
193 C.addCommand(std::make_unique<Command>(JA, *
this,
195 Exec, CmdArgs, Inputs, Output));
202 const char *LinkingOutput)
const {
203 const Driver &D = getToolChain().getDriver();
206 Args.ClaimAllArgs(options::OPT_g_Group);
208 Args.ClaimAllArgs(options::OPT_emit_llvm);
211 Args.ClaimAllArgs(options::OPT_w);
213 Args.ClaimAllArgs(options::OPT_stdlib_EQ);
216 ArgStringList CmdArgs;
218 CmdArgs.push_back(
"rcsD");
221 for (
const auto &II : Inputs) {
222 if (II.isFilename()) {
223 CmdArgs.push_back(II.getFilename());
230 if (Output.
isFilename() && llvm::sys::fs::exists(OutputFileName)) {
231 if (std::error_code EC = llvm::sys::fs::remove(OutputFileName)) {
232 D.
Diag(diag::err_drv_unable_to_remove_file) << EC.message();
237 const char *Exec = Args.MakeArgString(getToolChain().GetStaticLibToolPath());
238 C.addCommand(std::make_unique<Command>(JA, *
this,
240 Exec, CmdArgs, Inputs, Output));
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.str()));
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);
348 const ArgList &Args)
const {
349 if (Arg *A = Args.getLastArg(clang::driver::options::OPT_rtlib_EQ)) {
350 StringRef
Value = A->getValue();
351 if (
Value !=
"compiler-rt")
353 << A->getAsString(Args);
361 if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
362 StringRef
Value = A->getValue();
363 if (
Value !=
"libc++")
365 << A->getAsString(Args);
372 ArgStringList &CC1Args,
374 if (!DriverArgs.hasFlag(options::OPT_fuse_init_array,
375 options::OPT_fno_use_init_array,
true))
376 CC1Args.push_back(
"-fno-use-init-array");
380 ArgStringList &CC1Args)
const {
383 if (DriverArgs.hasArg(options::OPT_nostdinc))
386 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
388 llvm::sys::path::append(
P,
"include");
392 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
396 StringRef CIncludeDirs(C_INCLUDE_DIRS);
397 if (CIncludeDirs !=
"") {
399 CIncludeDirs.split(dirs,
":");
400 for (StringRef dir : dirs) {
402 llvm::sys::path::is_absolute(dir) ?
"" : StringRef(D.
SysRoot);
410 llvm::sys::path::append(
P,
"include");
416 ArgStringList &CC1Args)
const {
417 if (DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdlibinc,
418 options::OPT_nostdincxx))
424 auto AddCXXIncludePath = [&](StringRef Path) {
431 llvm::sys::path::append(TargetDir,
Target,
"c++", Version);
432 if (
getVFS().exists(TargetDir))
437 llvm::sys::path::append(Dir,
"c++", Version);
444 llvm::sys::path::append(
P,
"..",
"include");
445 AddCXXIncludePath(
P);
450 llvm_unreachable(
"invalid stdlib name");
455 ArgStringList &CmdArgs)
const {
458 CmdArgs.push_back(
"-lc++");
459 if (Args.hasArg(options::OPT_fexperimental_library))
460 CmdArgs.push_back(
"-lc++experimental");
464 llvm_unreachable(
"invalid stdlib name");
470 Res |= SanitizerKind::Address;
471 Res |= SanitizerKind::HWAddress;
472 Res |= SanitizerKind::PointerCompare;
473 Res |= SanitizerKind::PointerSubtract;
474 Res |= SanitizerKind::Fuzzer;
475 Res |= SanitizerKind::FuzzerNoLink;
476 Res |= SanitizerKind::Leak;
477 Res |= SanitizerKind::SafeStack;
478 Res |= SanitizerKind::Scudo;
479 Res |= SanitizerKind::Thread;
486 case llvm::Triple::aarch64:
487 case llvm::Triple::riscv64:
488 Res |= SanitizerKind::ShadowCallStack;
490 case llvm::Triple::x86_64:
491 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
LTOKind getLTOMode(bool IsOffload=false) const
Get the specific kind of LTO being performed.
std::string ResourceDir
The path to the compiler resource directory.
bool isUsingLTO(bool IsOffload=false) const
Returns true if we are performing any kind of LTO.
std::string Dir
The path the driver executable was in, as invoked from the command line.
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.
bool select(const Multilib::flags_list &Flags, llvm::SmallVector< Multilib > &) const
Select compatible variants,.
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.
This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag.
std::vector< std::string > flags_list
bool needsHwasanRt() const
bool needsSharedRt() const
@ C
Languages that the frontend can parse and compile.
static constexpr ResponseFileSupport AtFileCurCP()