11 #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" 25 using namespace clang;
34 const char *LinkingOutput)
const {
39 ArgStringList CmdArgs;
42 Args.ClaimAllArgs(options::OPT_g_Group);
44 Args.ClaimAllArgs(options::OPT_emit_llvm);
47 Args.ClaimAllArgs(options::OPT_w);
49 CmdArgs.push_back(
"-z");
50 CmdArgs.push_back(
"now");
52 const char *Exec = Args.MakeArgString(ToolChain.
GetLinkerPath());
53 if (llvm::sys::path::filename(Exec).equals_lower(
"ld.lld") ||
54 llvm::sys::path::stem(Exec).equals_lower(
"ld.lld")) {
55 CmdArgs.push_back(
"-z");
56 CmdArgs.push_back(
"rodynamic");
57 CmdArgs.push_back(
"-z");
58 CmdArgs.push_back(
"separate-loadable-segments");
62 CmdArgs.push_back(Args.MakeArgString(
"--sysroot=" + D.
SysRoot));
64 if (!Args.hasArg(options::OPT_shared) && !Args.hasArg(options::OPT_r))
65 CmdArgs.push_back(
"-pie");
67 if (Args.hasArg(options::OPT_rdynamic))
68 CmdArgs.push_back(
"-export-dynamic");
70 if (Args.hasArg(options::OPT_s))
71 CmdArgs.push_back(
"-s");
73 if (Args.hasArg(options::OPT_r)) {
74 CmdArgs.push_back(
"-r");
76 CmdArgs.push_back(
"--build-id");
77 CmdArgs.push_back(
"--hash-style=gnu");
80 CmdArgs.push_back(
"--eh-frame-hdr");
82 if (Args.hasArg(options::OPT_static))
83 CmdArgs.push_back(
"-Bstatic");
84 else if (Args.hasArg(options::OPT_shared))
85 CmdArgs.push_back(
"-shared");
89 if (!Args.hasArg(options::OPT_shared)) {
94 CmdArgs.push_back(
"-dynamic-linker");
95 CmdArgs.push_back(Args.MakeArgString(Dyld));
98 CmdArgs.push_back(
"-o");
101 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
102 if (!Args.hasArg(options::OPT_shared)) {
103 CmdArgs.push_back(Args.MakeArgString(ToolChain.
GetFilePath(
"Scrt1.o")));
107 Args.AddAllArgs(CmdArgs, options::OPT_L);
108 Args.AddAllArgs(CmdArgs, options::OPT_u);
113 assert(!Inputs.empty() &&
"Must have at least one input.");
123 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
124 if (Args.hasArg(options::OPT_static))
125 CmdArgs.push_back(
"-Bdynamic");
129 bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
130 !Args.hasArg(options::OPT_static);
131 CmdArgs.push_back(
"--push-state");
132 CmdArgs.push_back(
"--as-needed");
133 if (OnlyLibstdcxxStatic)
134 CmdArgs.push_back(
"-Bstatic");
136 if (OnlyLibstdcxxStatic)
137 CmdArgs.push_back(
"-Bdynamic");
138 CmdArgs.push_back(
"-lm");
139 CmdArgs.push_back(
"--pop-state");
143 if (NeedsSanitizerDeps)
151 if (Args.hasArg(options::OPT_pthread) ||
152 Args.hasArg(options::OPT_pthreads))
153 CmdArgs.push_back(
"-lpthread");
155 if (Args.hasArg(options::OPT_fsplit_stack))
156 CmdArgs.push_back(
"--wrap=pthread_create");
158 if (!Args.hasArg(options::OPT_nolibc))
159 CmdArgs.push_back(
"-lc");
162 C.
addCommand(std::make_unique<Command>(JA, *
this, Exec, CmdArgs, Inputs));
176 llvm::sys::path::append(P,
"lib");
180 auto FilePaths = [&](
const Multilib &M) -> std::vector<std::string> {
181 std::vector<std::string> FP;
185 llvm::sys::path::append(P, M.gccSuffix());
186 FP.push_back(P.str());
195 .flag(
"-fexceptions")
196 .flag(
"+fno-exceptions"));
199 .flag(
"+fsanitize=address"));
202 .flag(
"+fsanitize=address")
203 .flag(
"-fexceptions")
204 .flag(
"+fno-exceptions"));
206 std::vector<std::string> RD = FilePaths(M);
207 return std::all_of(RD.begin(), RD.end(), [&](std::string
P) {
214 Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions,
true),
215 "fexceptions", Flags);
238 const ArgList &Args)
const {
239 if (Arg *A = Args.getLastArg(clang::driver::options::OPT_rtlib_EQ)) {
240 StringRef
Value = A->getValue();
241 if (Value !=
"compiler-rt")
243 << A->getAsString(Args);
251 if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
252 StringRef
Value = A->getValue();
253 if (Value !=
"libc++")
255 << A->getAsString(Args);
262 ArgStringList &CC1Args,
264 if (!DriverArgs.hasFlag(options::OPT_fuse_init_array,
265 options::OPT_fno_use_init_array,
true))
266 CC1Args.push_back(
"-fno-use-init-array");
270 ArgStringList &CC1Args)
const {
273 if (DriverArgs.hasArg(options::OPT_nostdinc))
276 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
278 llvm::sys::path::append(P,
"include");
282 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
286 StringRef CIncludeDirs(C_INCLUDE_DIRS);
287 if (CIncludeDirs !=
"") {
289 CIncludeDirs.split(dirs,
":");
290 for (StringRef dir : dirs) {
292 llvm::sys::path::is_absolute(dir) ? StringRef(D.
SysRoot) :
"";
300 llvm::sys::path::append(P,
"include");
306 ArgStringList &CC1Args)
const {
307 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
308 DriverArgs.hasArg(options::OPT_nostdincxx))
314 llvm::sys::path::append(P,
"..",
"include",
"c++",
"v1");
320 llvm_unreachable(
"invalid stdlib name");
325 ArgStringList &CmdArgs)
const {
328 CmdArgs.push_back(
"-lc++");
332 llvm_unreachable(
"invalid stdlib name");
338 Res |= SanitizerKind::Address;
339 Res |= SanitizerKind::PointerCompare;
340 Res |= SanitizerKind::PointerSubtract;
341 Res |= SanitizerKind::Fuzzer;
342 Res |= SanitizerKind::FuzzerNoLink;
343 Res |= SanitizerKind::SafeStack;
344 Res |= SanitizerKind::Scudo;
351 case llvm::Triple::aarch64:
352 Res |= SanitizerKind::ShadowCallStack;
354 case llvm::Triple::x86_64:
355 Res |= SanitizerKind::SafeStack;
bool isDefault() const
Check whether the default is selected.
bool isUsingLTO() const
Returns true if we are performing any kind of LTO.
std::string DyldPrefix
Dynamic loader prefix, if present.
const IncludeDirsFunc & filePathsCallback() const
LTOKind getLTOMode() const
Get the specific kind of LTO being performed.
DiagnosticBuilder Diag(unsigned DiagID) const
bool select(const Multilib::flags_list &Flags, Multilib &M) const
Pick the best multilib in the set,.
std::string Dir
The path the driver executable was in, as invoked from the command line.
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
std::vector< std::string > flags_list
void push_back(const Multilib &M)
Add a completed Multilib to the set.
void addCommand(std::unique_ptr< Command > C)
This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag...
bool CCCIsCXX() const
Whether the driver should follow g++ like behavior.
MultilibSet & setFilePathsCallback(IncludeDirsFunc F)
Dataflow Directional Tag Classes.
std::string SysRoot
sysroot, if present
Compilation - A set of tasks to perform for a single driver invocation.
MultilibSet & FilterOut(FilterCallback F)
Filter out some subset of the Multilibs using a user defined callback.
bool needsSharedRt() const
std::string ResourceDir
The path to the compiler resource directory.