1e5dd7070Spatrick //===--- Fuchsia.cpp - Fuchsia ToolChain Implementations --------*- C++ -*-===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick
9e5dd7070Spatrick #include "Fuchsia.h"
10e5dd7070Spatrick #include "CommonArgs.h"
11e5dd7070Spatrick #include "clang/Config/config.h"
12e5dd7070Spatrick #include "clang/Driver/Compilation.h"
13e5dd7070Spatrick #include "clang/Driver/Driver.h"
14e5dd7070Spatrick #include "clang/Driver/DriverDiagnostic.h"
15e5dd7070Spatrick #include "clang/Driver/Options.h"
16e5dd7070Spatrick #include "clang/Driver/SanitizerArgs.h"
17e5dd7070Spatrick #include "llvm/Option/ArgList.h"
18ec727ea7Spatrick #include "llvm/ProfileData/InstrProf.h"
19e5dd7070Spatrick #include "llvm/Support/FileSystem.h"
20e5dd7070Spatrick #include "llvm/Support/Path.h"
21e5dd7070Spatrick #include "llvm/Support/VirtualFileSystem.h"
22e5dd7070Spatrick
23e5dd7070Spatrick using namespace clang::driver;
24e5dd7070Spatrick using namespace clang::driver::toolchains;
25e5dd7070Spatrick using namespace clang::driver::tools;
26e5dd7070Spatrick using namespace clang;
27e5dd7070Spatrick using namespace llvm::opt;
28e5dd7070Spatrick
29e5dd7070Spatrick using tools::addMultilibFlag;
30e5dd7070Spatrick
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const31e5dd7070Spatrick void fuchsia::Linker::ConstructJob(Compilation &C, const JobAction &JA,
32e5dd7070Spatrick const InputInfo &Output,
33e5dd7070Spatrick const InputInfoList &Inputs,
34e5dd7070Spatrick const ArgList &Args,
35e5dd7070Spatrick const char *LinkingOutput) const {
36e5dd7070Spatrick const toolchains::Fuchsia &ToolChain =
37e5dd7070Spatrick static_cast<const toolchains::Fuchsia &>(getToolChain());
38e5dd7070Spatrick const Driver &D = ToolChain.getDriver();
39e5dd7070Spatrick
40*12c85518Srobert const llvm::Triple &Triple = ToolChain.getEffectiveTriple();
41*12c85518Srobert
42e5dd7070Spatrick ArgStringList CmdArgs;
43e5dd7070Spatrick
44e5dd7070Spatrick // Silence warning for "clang -g foo.o -o foo"
45e5dd7070Spatrick Args.ClaimAllArgs(options::OPT_g_Group);
46e5dd7070Spatrick // and "clang -emit-llvm foo.o -o foo"
47e5dd7070Spatrick Args.ClaimAllArgs(options::OPT_emit_llvm);
48e5dd7070Spatrick // and for "clang -w foo.o -o foo". Other warning options are already
49e5dd7070Spatrick // handled somewhere else.
50e5dd7070Spatrick Args.ClaimAllArgs(options::OPT_w);
51e5dd7070Spatrick
52e5dd7070Spatrick CmdArgs.push_back("-z");
53ec727ea7Spatrick CmdArgs.push_back("max-page-size=4096");
54ec727ea7Spatrick
55ec727ea7Spatrick CmdArgs.push_back("-z");
56e5dd7070Spatrick CmdArgs.push_back("now");
57e5dd7070Spatrick
58e5dd7070Spatrick const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());
59a9ac8606Spatrick if (llvm::sys::path::filename(Exec).equals_insensitive("ld.lld") ||
60a9ac8606Spatrick llvm::sys::path::stem(Exec).equals_insensitive("ld.lld")) {
61e5dd7070Spatrick CmdArgs.push_back("-z");
62e5dd7070Spatrick CmdArgs.push_back("rodynamic");
63e5dd7070Spatrick CmdArgs.push_back("-z");
64e5dd7070Spatrick CmdArgs.push_back("separate-loadable-segments");
65*12c85518Srobert CmdArgs.push_back("-z");
66*12c85518Srobert CmdArgs.push_back("rel");
67ec727ea7Spatrick CmdArgs.push_back("--pack-dyn-relocs=relr");
68e5dd7070Spatrick }
69e5dd7070Spatrick
70e5dd7070Spatrick if (!D.SysRoot.empty())
71e5dd7070Spatrick CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
72e5dd7070Spatrick
73e5dd7070Spatrick if (!Args.hasArg(options::OPT_shared) && !Args.hasArg(options::OPT_r))
74e5dd7070Spatrick CmdArgs.push_back("-pie");
75e5dd7070Spatrick
76e5dd7070Spatrick if (Args.hasArg(options::OPT_rdynamic))
77e5dd7070Spatrick CmdArgs.push_back("-export-dynamic");
78e5dd7070Spatrick
79e5dd7070Spatrick if (Args.hasArg(options::OPT_s))
80e5dd7070Spatrick CmdArgs.push_back("-s");
81e5dd7070Spatrick
82e5dd7070Spatrick if (Args.hasArg(options::OPT_r)) {
83e5dd7070Spatrick CmdArgs.push_back("-r");
84e5dd7070Spatrick } else {
85e5dd7070Spatrick CmdArgs.push_back("--build-id");
86e5dd7070Spatrick CmdArgs.push_back("--hash-style=gnu");
87e5dd7070Spatrick }
88e5dd7070Spatrick
89*12c85518Srobert if (ToolChain.getArch() == llvm::Triple::aarch64) {
90*12c85518Srobert CmdArgs.push_back("--execute-only");
91*12c85518Srobert
92*12c85518Srobert std::string CPU = getCPUName(D, Args, Triple);
93*12c85518Srobert if (CPU.empty() || CPU == "generic" || CPU == "cortex-a53")
94*12c85518Srobert CmdArgs.push_back("--fix-cortex-a53-843419");
95*12c85518Srobert }
96*12c85518Srobert
97e5dd7070Spatrick CmdArgs.push_back("--eh-frame-hdr");
98e5dd7070Spatrick
99e5dd7070Spatrick if (Args.hasArg(options::OPT_static))
100e5dd7070Spatrick CmdArgs.push_back("-Bstatic");
101e5dd7070Spatrick else if (Args.hasArg(options::OPT_shared))
102e5dd7070Spatrick CmdArgs.push_back("-shared");
103e5dd7070Spatrick
104*12c85518Srobert const SanitizerArgs &SanArgs = ToolChain.getSanitizerArgs(Args);
105e5dd7070Spatrick
106*12c85518Srobert if (!Args.hasArg(options::OPT_shared) && !Args.hasArg(options::OPT_r)) {
107e5dd7070Spatrick std::string Dyld = D.DyldPrefix;
108e5dd7070Spatrick if (SanArgs.needsAsanRt() && SanArgs.needsSharedRt())
109e5dd7070Spatrick Dyld += "asan/";
110a9ac8606Spatrick if (SanArgs.needsHwasanRt() && SanArgs.needsSharedRt())
111a9ac8606Spatrick Dyld += "hwasan/";
112a9ac8606Spatrick if (SanArgs.needsTsanRt() && SanArgs.needsSharedRt())
113a9ac8606Spatrick Dyld += "tsan/";
114e5dd7070Spatrick Dyld += "ld.so.1";
115e5dd7070Spatrick CmdArgs.push_back("-dynamic-linker");
116e5dd7070Spatrick CmdArgs.push_back(Args.MakeArgString(Dyld));
117e5dd7070Spatrick }
118e5dd7070Spatrick
119*12c85518Srobert if (ToolChain.getArch() == llvm::Triple::riscv64)
120*12c85518Srobert CmdArgs.push_back("-X");
121*12c85518Srobert
122e5dd7070Spatrick CmdArgs.push_back("-o");
123e5dd7070Spatrick CmdArgs.push_back(Output.getFilename());
124e5dd7070Spatrick
125*12c85518Srobert if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles,
126*12c85518Srobert options::OPT_r)) {
127e5dd7070Spatrick if (!Args.hasArg(options::OPT_shared)) {
128e5dd7070Spatrick CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("Scrt1.o")));
129e5dd7070Spatrick }
130e5dd7070Spatrick }
131e5dd7070Spatrick
132e5dd7070Spatrick Args.AddAllArgs(CmdArgs, options::OPT_L);
133e5dd7070Spatrick Args.AddAllArgs(CmdArgs, options::OPT_u);
134e5dd7070Spatrick
135e5dd7070Spatrick ToolChain.AddFilePathLibArgs(Args, CmdArgs);
136e5dd7070Spatrick
137e5dd7070Spatrick if (D.isUsingLTO()) {
138e5dd7070Spatrick assert(!Inputs.empty() && "Must have at least one input.");
139ec727ea7Spatrick addLTOOptions(ToolChain, Args, CmdArgs, Output, Inputs[0],
140e5dd7070Spatrick D.getLTOMode() == LTOK_Thin);
141e5dd7070Spatrick }
142e5dd7070Spatrick
143*12c85518Srobert addLinkerCompressDebugSectionsOption(ToolChain, Args, CmdArgs);
144e5dd7070Spatrick AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
145e5dd7070Spatrick
146*12c85518Srobert if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs,
147*12c85518Srobert options::OPT_r)) {
148e5dd7070Spatrick if (Args.hasArg(options::OPT_static))
149e5dd7070Spatrick CmdArgs.push_back("-Bdynamic");
150e5dd7070Spatrick
151e5dd7070Spatrick if (D.CCCIsCXX()) {
152e5dd7070Spatrick if (ToolChain.ShouldLinkCXXStdlib(Args)) {
153e5dd7070Spatrick bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
154e5dd7070Spatrick !Args.hasArg(options::OPT_static);
155e5dd7070Spatrick CmdArgs.push_back("--push-state");
156e5dd7070Spatrick CmdArgs.push_back("--as-needed");
157e5dd7070Spatrick if (OnlyLibstdcxxStatic)
158e5dd7070Spatrick CmdArgs.push_back("-Bstatic");
159e5dd7070Spatrick ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
160e5dd7070Spatrick if (OnlyLibstdcxxStatic)
161e5dd7070Spatrick CmdArgs.push_back("-Bdynamic");
162e5dd7070Spatrick CmdArgs.push_back("-lm");
163e5dd7070Spatrick CmdArgs.push_back("--pop-state");
164e5dd7070Spatrick }
165e5dd7070Spatrick }
166e5dd7070Spatrick
167*12c85518Srobert // Note that Fuchsia never needs to link in sanitizer runtime deps. Any
168*12c85518Srobert // sanitizer runtimes with system dependencies use the `.deplibs` feature
169*12c85518Srobert // instead.
170*12c85518Srobert addSanitizerRuntimes(ToolChain, Args, CmdArgs);
171e5dd7070Spatrick
172*12c85518Srobert addXRayRuntime(ToolChain, Args, CmdArgs);
173*12c85518Srobert
174*12c85518Srobert ToolChain.addProfileRTLibs(Args, CmdArgs);
175e5dd7070Spatrick
176e5dd7070Spatrick AddRunTimeLibs(ToolChain, D, CmdArgs, Args);
177e5dd7070Spatrick
178e5dd7070Spatrick if (Args.hasArg(options::OPT_pthread) ||
179e5dd7070Spatrick Args.hasArg(options::OPT_pthreads))
180e5dd7070Spatrick CmdArgs.push_back("-lpthread");
181e5dd7070Spatrick
182e5dd7070Spatrick if (Args.hasArg(options::OPT_fsplit_stack))
183e5dd7070Spatrick CmdArgs.push_back("--wrap=pthread_create");
184e5dd7070Spatrick
185e5dd7070Spatrick if (!Args.hasArg(options::OPT_nolibc))
186e5dd7070Spatrick CmdArgs.push_back("-lc");
187e5dd7070Spatrick }
188e5dd7070Spatrick
189ec727ea7Spatrick C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
190a9ac8606Spatrick Exec, CmdArgs, Inputs, Output));
191e5dd7070Spatrick }
192e5dd7070Spatrick
193e5dd7070Spatrick /// Fuchsia - Fuchsia tool chain which can call as(1) and ld(1) directly.
194e5dd7070Spatrick
Fuchsia(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)195e5dd7070Spatrick Fuchsia::Fuchsia(const Driver &D, const llvm::Triple &Triple,
196e5dd7070Spatrick const ArgList &Args)
197e5dd7070Spatrick : ToolChain(D, Triple, Args) {
198e5dd7070Spatrick getProgramPaths().push_back(getDriver().getInstalledDir());
199e5dd7070Spatrick if (getDriver().getInstalledDir() != D.Dir)
200e5dd7070Spatrick getProgramPaths().push_back(D.Dir);
201e5dd7070Spatrick
202e5dd7070Spatrick if (!D.SysRoot.empty()) {
203e5dd7070Spatrick SmallString<128> P(D.SysRoot);
204e5dd7070Spatrick llvm::sys::path::append(P, "lib");
205ec727ea7Spatrick getFilePaths().push_back(std::string(P.str()));
206e5dd7070Spatrick }
207e5dd7070Spatrick
208e5dd7070Spatrick auto FilePaths = [&](const Multilib &M) -> std::vector<std::string> {
209e5dd7070Spatrick std::vector<std::string> FP;
210*12c85518Srobert for (const std::string &Path : getStdlibPaths()) {
211*12c85518Srobert SmallString<128> P(Path);
212e5dd7070Spatrick llvm::sys::path::append(P, M.gccSuffix());
213ec727ea7Spatrick FP.push_back(std::string(P.str()));
214*12c85518Srobert }
215e5dd7070Spatrick return FP;
216e5dd7070Spatrick };
217e5dd7070Spatrick
218e5dd7070Spatrick Multilibs.push_back(Multilib());
219e5dd7070Spatrick // Use the noexcept variant with -fno-exceptions to avoid the extra overhead.
220e5dd7070Spatrick Multilibs.push_back(Multilib("noexcept", {}, {}, 1)
221e5dd7070Spatrick .flag("-fexceptions")
222e5dd7070Spatrick .flag("+fno-exceptions"));
223e5dd7070Spatrick // ASan has higher priority because we always want the instrumentated version.
224e5dd7070Spatrick Multilibs.push_back(Multilib("asan", {}, {}, 2)
225e5dd7070Spatrick .flag("+fsanitize=address"));
226e5dd7070Spatrick // Use the asan+noexcept variant with ASan and -fno-exceptions.
227e5dd7070Spatrick Multilibs.push_back(Multilib("asan+noexcept", {}, {}, 3)
228e5dd7070Spatrick .flag("+fsanitize=address")
229e5dd7070Spatrick .flag("-fexceptions")
230e5dd7070Spatrick .flag("+fno-exceptions"));
231a9ac8606Spatrick // HWASan has higher priority because we always want the instrumentated
232a9ac8606Spatrick // version.
233a9ac8606Spatrick Multilibs.push_back(
234a9ac8606Spatrick Multilib("hwasan", {}, {}, 4).flag("+fsanitize=hwaddress"));
235a9ac8606Spatrick // Use the hwasan+noexcept variant with HWASan and -fno-exceptions.
236a9ac8606Spatrick Multilibs.push_back(Multilib("hwasan+noexcept", {}, {}, 5)
237a9ac8606Spatrick .flag("+fsanitize=hwaddress")
238a9ac8606Spatrick .flag("-fexceptions")
239a9ac8606Spatrick .flag("+fno-exceptions"));
240a9ac8606Spatrick // Use the relative vtables ABI.
241a9ac8606Spatrick // TODO: Remove these multilibs once relative vtables are enabled by default
242a9ac8606Spatrick // for Fuchsia.
243a9ac8606Spatrick Multilibs.push_back(Multilib("relative-vtables", {}, {}, 6)
244a9ac8606Spatrick .flag("+fexperimental-relative-c++-abi-vtables"));
245a9ac8606Spatrick Multilibs.push_back(Multilib("relative-vtables+noexcept", {}, {}, 7)
246a9ac8606Spatrick .flag("+fexperimental-relative-c++-abi-vtables")
247a9ac8606Spatrick .flag("-fexceptions")
248a9ac8606Spatrick .flag("+fno-exceptions"));
249a9ac8606Spatrick Multilibs.push_back(Multilib("relative-vtables+asan", {}, {}, 8)
250a9ac8606Spatrick .flag("+fexperimental-relative-c++-abi-vtables")
251a9ac8606Spatrick .flag("+fsanitize=address"));
252a9ac8606Spatrick Multilibs.push_back(Multilib("relative-vtables+asan+noexcept", {}, {}, 9)
253a9ac8606Spatrick .flag("+fexperimental-relative-c++-abi-vtables")
254a9ac8606Spatrick .flag("+fsanitize=address")
255a9ac8606Spatrick .flag("-fexceptions")
256a9ac8606Spatrick .flag("+fno-exceptions"));
257a9ac8606Spatrick Multilibs.push_back(Multilib("relative-vtables+hwasan", {}, {}, 10)
258a9ac8606Spatrick .flag("+fexperimental-relative-c++-abi-vtables")
259a9ac8606Spatrick .flag("+fsanitize=hwaddress"));
260a9ac8606Spatrick Multilibs.push_back(Multilib("relative-vtables+hwasan+noexcept", {}, {}, 11)
261a9ac8606Spatrick .flag("+fexperimental-relative-c++-abi-vtables")
262a9ac8606Spatrick .flag("+fsanitize=hwaddress")
263a9ac8606Spatrick .flag("-fexceptions")
264a9ac8606Spatrick .flag("+fno-exceptions"));
265a9ac8606Spatrick // Use Itanium C++ ABI for the compat multilib.
266a9ac8606Spatrick Multilibs.push_back(Multilib("compat", {}, {}, 12).flag("+fc++-abi=itanium"));
267a9ac8606Spatrick
268e5dd7070Spatrick Multilibs.FilterOut([&](const Multilib &M) {
269e5dd7070Spatrick std::vector<std::string> RD = FilePaths(M);
270*12c85518Srobert return llvm::all_of(RD, [&](std::string P) { return !getVFS().exists(P); });
271e5dd7070Spatrick });
272e5dd7070Spatrick
273e5dd7070Spatrick Multilib::flags_list Flags;
274e5dd7070Spatrick addMultilibFlag(
275e5dd7070Spatrick Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions, true),
276e5dd7070Spatrick "fexceptions", Flags);
277*12c85518Srobert addMultilibFlag(getSanitizerArgs(Args).needsAsanRt(), "fsanitize=address",
278*12c85518Srobert Flags);
279*12c85518Srobert addMultilibFlag(getSanitizerArgs(Args).needsHwasanRt(), "fsanitize=hwaddress",
280a9ac8606Spatrick Flags);
281a9ac8606Spatrick
282a9ac8606Spatrick addMultilibFlag(
283a9ac8606Spatrick Args.hasFlag(options::OPT_fexperimental_relative_cxx_abi_vtables,
284a9ac8606Spatrick options::OPT_fno_experimental_relative_cxx_abi_vtables,
285a9ac8606Spatrick /*default=*/false),
286a9ac8606Spatrick "fexperimental-relative-c++-abi-vtables", Flags);
287a9ac8606Spatrick addMultilibFlag(Args.getLastArgValue(options::OPT_fcxx_abi_EQ) == "itanium",
288a9ac8606Spatrick "fc++-abi=itanium", Flags);
289a9ac8606Spatrick
290e5dd7070Spatrick Multilibs.setFilePathsCallback(FilePaths);
291e5dd7070Spatrick
292e5dd7070Spatrick if (Multilibs.select(Flags, SelectedMultilib))
293e5dd7070Spatrick if (!SelectedMultilib.isDefault())
294e5dd7070Spatrick if (const auto &PathsCallback = Multilibs.filePathsCallback())
295e5dd7070Spatrick for (const auto &Path : PathsCallback(SelectedMultilib))
296e5dd7070Spatrick // Prepend the multilib path to ensure it takes the precedence.
297e5dd7070Spatrick getFilePaths().insert(getFilePaths().begin(), Path);
298e5dd7070Spatrick }
299e5dd7070Spatrick
ComputeEffectiveClangTriple(const ArgList & Args,types::ID InputType) const300e5dd7070Spatrick std::string Fuchsia::ComputeEffectiveClangTriple(const ArgList &Args,
301e5dd7070Spatrick types::ID InputType) const {
302e5dd7070Spatrick llvm::Triple Triple(ComputeLLVMTriple(Args, InputType));
303e5dd7070Spatrick return Triple.str();
304e5dd7070Spatrick }
305e5dd7070Spatrick
buildLinker() const306e5dd7070Spatrick Tool *Fuchsia::buildLinker() const {
307e5dd7070Spatrick return new tools::fuchsia::Linker(*this);
308e5dd7070Spatrick }
309e5dd7070Spatrick
GetRuntimeLibType(const ArgList & Args) const310e5dd7070Spatrick ToolChain::RuntimeLibType Fuchsia::GetRuntimeLibType(
311e5dd7070Spatrick const ArgList &Args) const {
312e5dd7070Spatrick if (Arg *A = Args.getLastArg(clang::driver::options::OPT_rtlib_EQ)) {
313e5dd7070Spatrick StringRef Value = A->getValue();
314e5dd7070Spatrick if (Value != "compiler-rt")
315e5dd7070Spatrick getDriver().Diag(clang::diag::err_drv_invalid_rtlib_name)
316e5dd7070Spatrick << A->getAsString(Args);
317e5dd7070Spatrick }
318e5dd7070Spatrick
319e5dd7070Spatrick return ToolChain::RLT_CompilerRT;
320e5dd7070Spatrick }
321e5dd7070Spatrick
322e5dd7070Spatrick ToolChain::CXXStdlibType
GetCXXStdlibType(const ArgList & Args) const323e5dd7070Spatrick Fuchsia::GetCXXStdlibType(const ArgList &Args) const {
324e5dd7070Spatrick if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
325e5dd7070Spatrick StringRef Value = A->getValue();
326e5dd7070Spatrick if (Value != "libc++")
327e5dd7070Spatrick getDriver().Diag(diag::err_drv_invalid_stdlib_name)
328e5dd7070Spatrick << A->getAsString(Args);
329e5dd7070Spatrick }
330e5dd7070Spatrick
331e5dd7070Spatrick return ToolChain::CST_Libcxx;
332e5dd7070Spatrick }
333e5dd7070Spatrick
addClangTargetOptions(const ArgList & DriverArgs,ArgStringList & CC1Args,Action::OffloadKind) const334e5dd7070Spatrick void Fuchsia::addClangTargetOptions(const ArgList &DriverArgs,
335e5dd7070Spatrick ArgStringList &CC1Args,
336e5dd7070Spatrick Action::OffloadKind) const {
337e5dd7070Spatrick if (!DriverArgs.hasFlag(options::OPT_fuse_init_array,
338e5dd7070Spatrick options::OPT_fno_use_init_array, true))
339e5dd7070Spatrick CC1Args.push_back("-fno-use-init-array");
340e5dd7070Spatrick }
341e5dd7070Spatrick
AddClangSystemIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const342e5dd7070Spatrick void Fuchsia::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
343e5dd7070Spatrick ArgStringList &CC1Args) const {
344e5dd7070Spatrick const Driver &D = getDriver();
345e5dd7070Spatrick
346e5dd7070Spatrick if (DriverArgs.hasArg(options::OPT_nostdinc))
347e5dd7070Spatrick return;
348e5dd7070Spatrick
349e5dd7070Spatrick if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
350e5dd7070Spatrick SmallString<128> P(D.ResourceDir);
351e5dd7070Spatrick llvm::sys::path::append(P, "include");
352e5dd7070Spatrick addSystemInclude(DriverArgs, CC1Args, P);
353e5dd7070Spatrick }
354e5dd7070Spatrick
355e5dd7070Spatrick if (DriverArgs.hasArg(options::OPT_nostdlibinc))
356e5dd7070Spatrick return;
357e5dd7070Spatrick
358e5dd7070Spatrick // Check for configure-time C include directories.
359e5dd7070Spatrick StringRef CIncludeDirs(C_INCLUDE_DIRS);
360e5dd7070Spatrick if (CIncludeDirs != "") {
361e5dd7070Spatrick SmallVector<StringRef, 5> dirs;
362e5dd7070Spatrick CIncludeDirs.split(dirs, ":");
363e5dd7070Spatrick for (StringRef dir : dirs) {
364e5dd7070Spatrick StringRef Prefix =
365ec727ea7Spatrick llvm::sys::path::is_absolute(dir) ? "" : StringRef(D.SysRoot);
366e5dd7070Spatrick addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir);
367e5dd7070Spatrick }
368e5dd7070Spatrick return;
369e5dd7070Spatrick }
370e5dd7070Spatrick
371e5dd7070Spatrick if (!D.SysRoot.empty()) {
372e5dd7070Spatrick SmallString<128> P(D.SysRoot);
373e5dd7070Spatrick llvm::sys::path::append(P, "include");
374e5dd7070Spatrick addExternCSystemInclude(DriverArgs, CC1Args, P.str());
375e5dd7070Spatrick }
376e5dd7070Spatrick }
377e5dd7070Spatrick
AddClangCXXStdlibIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const378e5dd7070Spatrick void Fuchsia::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
379e5dd7070Spatrick ArgStringList &CC1Args) const {
380*12c85518Srobert if (DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdlibinc,
381*12c85518Srobert options::OPT_nostdincxx))
382e5dd7070Spatrick return;
383e5dd7070Spatrick
384a9ac8606Spatrick const Driver &D = getDriver();
385a9ac8606Spatrick std::string Target = getTripleString();
386a9ac8606Spatrick
387a9ac8606Spatrick auto AddCXXIncludePath = [&](StringRef Path) {
388a9ac8606Spatrick std::string Version = detectLibcxxVersion(Path);
389a9ac8606Spatrick if (Version.empty())
390a9ac8606Spatrick return;
391a9ac8606Spatrick
392a9ac8606Spatrick // First add the per-target include path.
393a9ac8606Spatrick SmallString<128> TargetDir(Path);
394a9ac8606Spatrick llvm::sys::path::append(TargetDir, Target, "c++", Version);
395a9ac8606Spatrick if (getVFS().exists(TargetDir))
396a9ac8606Spatrick addSystemInclude(DriverArgs, CC1Args, TargetDir);
397a9ac8606Spatrick
398a9ac8606Spatrick // Second add the generic one.
399a9ac8606Spatrick SmallString<128> Dir(Path);
400a9ac8606Spatrick llvm::sys::path::append(Dir, "c++", Version);
401a9ac8606Spatrick addSystemInclude(DriverArgs, CC1Args, Dir);
402a9ac8606Spatrick };
403a9ac8606Spatrick
404e5dd7070Spatrick switch (GetCXXStdlibType(DriverArgs)) {
405e5dd7070Spatrick case ToolChain::CST_Libcxx: {
406a9ac8606Spatrick SmallString<128> P(D.Dir);
407a9ac8606Spatrick llvm::sys::path::append(P, "..", "include");
408a9ac8606Spatrick AddCXXIncludePath(P);
409e5dd7070Spatrick break;
410e5dd7070Spatrick }
411e5dd7070Spatrick
412e5dd7070Spatrick default:
413e5dd7070Spatrick llvm_unreachable("invalid stdlib name");
414e5dd7070Spatrick }
415e5dd7070Spatrick }
416e5dd7070Spatrick
AddCXXStdlibLibArgs(const ArgList & Args,ArgStringList & CmdArgs) const417e5dd7070Spatrick void Fuchsia::AddCXXStdlibLibArgs(const ArgList &Args,
418e5dd7070Spatrick ArgStringList &CmdArgs) const {
419e5dd7070Spatrick switch (GetCXXStdlibType(Args)) {
420e5dd7070Spatrick case ToolChain::CST_Libcxx:
421e5dd7070Spatrick CmdArgs.push_back("-lc++");
422*12c85518Srobert if (Args.hasArg(options::OPT_fexperimental_library))
423*12c85518Srobert CmdArgs.push_back("-lc++experimental");
424e5dd7070Spatrick break;
425e5dd7070Spatrick
426e5dd7070Spatrick case ToolChain::CST_Libstdcxx:
427e5dd7070Spatrick llvm_unreachable("invalid stdlib name");
428e5dd7070Spatrick }
429e5dd7070Spatrick }
430e5dd7070Spatrick
getSupportedSanitizers() const431e5dd7070Spatrick SanitizerMask Fuchsia::getSupportedSanitizers() const {
432e5dd7070Spatrick SanitizerMask Res = ToolChain::getSupportedSanitizers();
433e5dd7070Spatrick Res |= SanitizerKind::Address;
434a9ac8606Spatrick Res |= SanitizerKind::HWAddress;
435e5dd7070Spatrick Res |= SanitizerKind::PointerCompare;
436e5dd7070Spatrick Res |= SanitizerKind::PointerSubtract;
437e5dd7070Spatrick Res |= SanitizerKind::Fuzzer;
438e5dd7070Spatrick Res |= SanitizerKind::FuzzerNoLink;
439ec727ea7Spatrick Res |= SanitizerKind::Leak;
440e5dd7070Spatrick Res |= SanitizerKind::SafeStack;
441e5dd7070Spatrick Res |= SanitizerKind::Scudo;
442a9ac8606Spatrick Res |= SanitizerKind::Thread;
443e5dd7070Spatrick return Res;
444e5dd7070Spatrick }
445e5dd7070Spatrick
getDefaultSanitizers() const446e5dd7070Spatrick SanitizerMask Fuchsia::getDefaultSanitizers() const {
447e5dd7070Spatrick SanitizerMask Res;
448e5dd7070Spatrick switch (getTriple().getArch()) {
449e5dd7070Spatrick case llvm::Triple::aarch64:
450*12c85518Srobert case llvm::Triple::riscv64:
451e5dd7070Spatrick Res |= SanitizerKind::ShadowCallStack;
452e5dd7070Spatrick break;
453e5dd7070Spatrick case llvm::Triple::x86_64:
454e5dd7070Spatrick Res |= SanitizerKind::SafeStack;
455e5dd7070Spatrick break;
456e5dd7070Spatrick default:
457e5dd7070Spatrick break;
458e5dd7070Spatrick }
459e5dd7070Spatrick return Res;
460e5dd7070Spatrick }
461