17330f729Sjoerg //===--- Fuchsia.cpp - Fuchsia ToolChain Implementations --------*- C++ -*-===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg
97330f729Sjoerg #include "Fuchsia.h"
107330f729Sjoerg #include "CommonArgs.h"
117330f729Sjoerg #include "clang/Config/config.h"
127330f729Sjoerg #include "clang/Driver/Compilation.h"
137330f729Sjoerg #include "clang/Driver/Driver.h"
147330f729Sjoerg #include "clang/Driver/DriverDiagnostic.h"
157330f729Sjoerg #include "clang/Driver/Options.h"
167330f729Sjoerg #include "clang/Driver/SanitizerArgs.h"
177330f729Sjoerg #include "llvm/Option/ArgList.h"
18*e038c9c4Sjoerg #include "llvm/ProfileData/InstrProf.h"
197330f729Sjoerg #include "llvm/Support/FileSystem.h"
207330f729Sjoerg #include "llvm/Support/Path.h"
217330f729Sjoerg #include "llvm/Support/VirtualFileSystem.h"
227330f729Sjoerg
237330f729Sjoerg using namespace clang::driver;
247330f729Sjoerg using namespace clang::driver::toolchains;
257330f729Sjoerg using namespace clang::driver::tools;
267330f729Sjoerg using namespace clang;
277330f729Sjoerg using namespace llvm::opt;
287330f729Sjoerg
297330f729Sjoerg using tools::addMultilibFlag;
307330f729Sjoerg
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const317330f729Sjoerg void fuchsia::Linker::ConstructJob(Compilation &C, const JobAction &JA,
327330f729Sjoerg const InputInfo &Output,
337330f729Sjoerg const InputInfoList &Inputs,
347330f729Sjoerg const ArgList &Args,
357330f729Sjoerg const char *LinkingOutput) const {
367330f729Sjoerg const toolchains::Fuchsia &ToolChain =
377330f729Sjoerg static_cast<const toolchains::Fuchsia &>(getToolChain());
387330f729Sjoerg const Driver &D = ToolChain.getDriver();
397330f729Sjoerg
407330f729Sjoerg ArgStringList CmdArgs;
417330f729Sjoerg
427330f729Sjoerg // Silence warning for "clang -g foo.o -o foo"
437330f729Sjoerg Args.ClaimAllArgs(options::OPT_g_Group);
447330f729Sjoerg // and "clang -emit-llvm foo.o -o foo"
457330f729Sjoerg Args.ClaimAllArgs(options::OPT_emit_llvm);
467330f729Sjoerg // and for "clang -w foo.o -o foo". Other warning options are already
477330f729Sjoerg // handled somewhere else.
487330f729Sjoerg Args.ClaimAllArgs(options::OPT_w);
497330f729Sjoerg
50*e038c9c4Sjoerg CmdArgs.push_back("-z");
51*e038c9c4Sjoerg CmdArgs.push_back("max-page-size=4096");
52*e038c9c4Sjoerg
53*e038c9c4Sjoerg CmdArgs.push_back("-z");
54*e038c9c4Sjoerg CmdArgs.push_back("now");
55*e038c9c4Sjoerg
567330f729Sjoerg const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());
577330f729Sjoerg if (llvm::sys::path::filename(Exec).equals_lower("ld.lld") ||
587330f729Sjoerg llvm::sys::path::stem(Exec).equals_lower("ld.lld")) {
597330f729Sjoerg CmdArgs.push_back("-z");
607330f729Sjoerg CmdArgs.push_back("rodynamic");
617330f729Sjoerg CmdArgs.push_back("-z");
627330f729Sjoerg CmdArgs.push_back("separate-loadable-segments");
63*e038c9c4Sjoerg CmdArgs.push_back("--pack-dyn-relocs=relr");
647330f729Sjoerg }
657330f729Sjoerg
667330f729Sjoerg if (!D.SysRoot.empty())
677330f729Sjoerg CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
687330f729Sjoerg
697330f729Sjoerg if (!Args.hasArg(options::OPT_shared) && !Args.hasArg(options::OPT_r))
707330f729Sjoerg CmdArgs.push_back("-pie");
717330f729Sjoerg
727330f729Sjoerg if (Args.hasArg(options::OPT_rdynamic))
737330f729Sjoerg CmdArgs.push_back("-export-dynamic");
747330f729Sjoerg
757330f729Sjoerg if (Args.hasArg(options::OPT_s))
767330f729Sjoerg CmdArgs.push_back("-s");
777330f729Sjoerg
787330f729Sjoerg if (Args.hasArg(options::OPT_r)) {
797330f729Sjoerg CmdArgs.push_back("-r");
807330f729Sjoerg } else {
817330f729Sjoerg CmdArgs.push_back("--build-id");
827330f729Sjoerg CmdArgs.push_back("--hash-style=gnu");
837330f729Sjoerg }
847330f729Sjoerg
857330f729Sjoerg CmdArgs.push_back("--eh-frame-hdr");
867330f729Sjoerg
877330f729Sjoerg if (Args.hasArg(options::OPT_static))
887330f729Sjoerg CmdArgs.push_back("-Bstatic");
897330f729Sjoerg else if (Args.hasArg(options::OPT_shared))
907330f729Sjoerg CmdArgs.push_back("-shared");
917330f729Sjoerg
927330f729Sjoerg const SanitizerArgs &SanArgs = ToolChain.getSanitizerArgs();
937330f729Sjoerg
947330f729Sjoerg if (!Args.hasArg(options::OPT_shared)) {
957330f729Sjoerg std::string Dyld = D.DyldPrefix;
967330f729Sjoerg if (SanArgs.needsAsanRt() && SanArgs.needsSharedRt())
977330f729Sjoerg Dyld += "asan/";
98*e038c9c4Sjoerg if (SanArgs.needsHwasanRt() && SanArgs.needsSharedRt())
99*e038c9c4Sjoerg Dyld += "hwasan/";
100*e038c9c4Sjoerg if (SanArgs.needsTsanRt() && SanArgs.needsSharedRt())
101*e038c9c4Sjoerg Dyld += "tsan/";
1027330f729Sjoerg Dyld += "ld.so.1";
1037330f729Sjoerg CmdArgs.push_back("-dynamic-linker");
1047330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(Dyld));
1057330f729Sjoerg }
1067330f729Sjoerg
1077330f729Sjoerg CmdArgs.push_back("-o");
1087330f729Sjoerg CmdArgs.push_back(Output.getFilename());
1097330f729Sjoerg
1107330f729Sjoerg if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
1117330f729Sjoerg if (!Args.hasArg(options::OPT_shared)) {
1127330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("Scrt1.o")));
1137330f729Sjoerg }
1147330f729Sjoerg }
1157330f729Sjoerg
1167330f729Sjoerg Args.AddAllArgs(CmdArgs, options::OPT_L);
1177330f729Sjoerg Args.AddAllArgs(CmdArgs, options::OPT_u);
1187330f729Sjoerg
1197330f729Sjoerg ToolChain.AddFilePathLibArgs(Args, CmdArgs);
1207330f729Sjoerg
1217330f729Sjoerg if (D.isUsingLTO()) {
1227330f729Sjoerg assert(!Inputs.empty() && "Must have at least one input.");
123*e038c9c4Sjoerg addLTOOptions(ToolChain, Args, CmdArgs, Output, Inputs[0],
1247330f729Sjoerg D.getLTOMode() == LTOK_Thin);
1257330f729Sjoerg }
1267330f729Sjoerg
1277330f729Sjoerg bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs);
1287330f729Sjoerg bool NeedsXRayDeps = addXRayRuntime(ToolChain, Args, CmdArgs);
1297330f729Sjoerg AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
1307330f729Sjoerg ToolChain.addProfileRTLibs(Args, CmdArgs);
1317330f729Sjoerg
1327330f729Sjoerg if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
1337330f729Sjoerg if (Args.hasArg(options::OPT_static))
1347330f729Sjoerg CmdArgs.push_back("-Bdynamic");
1357330f729Sjoerg
1367330f729Sjoerg if (D.CCCIsCXX()) {
1377330f729Sjoerg if (ToolChain.ShouldLinkCXXStdlib(Args)) {
1387330f729Sjoerg bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
1397330f729Sjoerg !Args.hasArg(options::OPT_static);
1407330f729Sjoerg CmdArgs.push_back("--push-state");
1417330f729Sjoerg CmdArgs.push_back("--as-needed");
1427330f729Sjoerg if (OnlyLibstdcxxStatic)
1437330f729Sjoerg CmdArgs.push_back("-Bstatic");
1447330f729Sjoerg ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
1457330f729Sjoerg if (OnlyLibstdcxxStatic)
1467330f729Sjoerg CmdArgs.push_back("-Bdynamic");
1477330f729Sjoerg CmdArgs.push_back("-lm");
1487330f729Sjoerg CmdArgs.push_back("--pop-state");
1497330f729Sjoerg }
1507330f729Sjoerg }
1517330f729Sjoerg
1527330f729Sjoerg if (NeedsSanitizerDeps)
1537330f729Sjoerg linkSanitizerRuntimeDeps(ToolChain, CmdArgs);
1547330f729Sjoerg
1557330f729Sjoerg if (NeedsXRayDeps)
1567330f729Sjoerg linkXRayRuntimeDeps(ToolChain, CmdArgs);
1577330f729Sjoerg
1587330f729Sjoerg AddRunTimeLibs(ToolChain, D, CmdArgs, Args);
1597330f729Sjoerg
1607330f729Sjoerg if (Args.hasArg(options::OPT_pthread) ||
1617330f729Sjoerg Args.hasArg(options::OPT_pthreads))
1627330f729Sjoerg CmdArgs.push_back("-lpthread");
1637330f729Sjoerg
1647330f729Sjoerg if (Args.hasArg(options::OPT_fsplit_stack))
1657330f729Sjoerg CmdArgs.push_back("--wrap=pthread_create");
1667330f729Sjoerg
1677330f729Sjoerg if (!Args.hasArg(options::OPT_nolibc))
1687330f729Sjoerg CmdArgs.push_back("-lc");
1697330f729Sjoerg }
1707330f729Sjoerg
171*e038c9c4Sjoerg C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
172*e038c9c4Sjoerg Exec, CmdArgs, Inputs, Output));
1737330f729Sjoerg }
1747330f729Sjoerg
1757330f729Sjoerg /// Fuchsia - Fuchsia tool chain which can call as(1) and ld(1) directly.
1767330f729Sjoerg
Fuchsia(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)1777330f729Sjoerg Fuchsia::Fuchsia(const Driver &D, const llvm::Triple &Triple,
1787330f729Sjoerg const ArgList &Args)
1797330f729Sjoerg : ToolChain(D, Triple, Args) {
1807330f729Sjoerg getProgramPaths().push_back(getDriver().getInstalledDir());
1817330f729Sjoerg if (getDriver().getInstalledDir() != D.Dir)
1827330f729Sjoerg getProgramPaths().push_back(D.Dir);
1837330f729Sjoerg
1847330f729Sjoerg if (!D.SysRoot.empty()) {
1857330f729Sjoerg SmallString<128> P(D.SysRoot);
1867330f729Sjoerg llvm::sys::path::append(P, "lib");
187*e038c9c4Sjoerg getFilePaths().push_back(std::string(P.str()));
1887330f729Sjoerg }
1897330f729Sjoerg
1907330f729Sjoerg auto FilePaths = [&](const Multilib &M) -> std::vector<std::string> {
1917330f729Sjoerg std::vector<std::string> FP;
192*e038c9c4Sjoerg SmallString<128> P(getStdlibPath());
1937330f729Sjoerg llvm::sys::path::append(P, M.gccSuffix());
194*e038c9c4Sjoerg FP.push_back(std::string(P.str()));
1957330f729Sjoerg return FP;
1967330f729Sjoerg };
1977330f729Sjoerg
1987330f729Sjoerg Multilibs.push_back(Multilib());
1997330f729Sjoerg // Use the noexcept variant with -fno-exceptions to avoid the extra overhead.
2007330f729Sjoerg Multilibs.push_back(Multilib("noexcept", {}, {}, 1)
2017330f729Sjoerg .flag("-fexceptions")
2027330f729Sjoerg .flag("+fno-exceptions"));
2037330f729Sjoerg // ASan has higher priority because we always want the instrumentated version.
2047330f729Sjoerg Multilibs.push_back(Multilib("asan", {}, {}, 2)
2057330f729Sjoerg .flag("+fsanitize=address"));
2067330f729Sjoerg // Use the asan+noexcept variant with ASan and -fno-exceptions.
2077330f729Sjoerg Multilibs.push_back(Multilib("asan+noexcept", {}, {}, 3)
2087330f729Sjoerg .flag("+fsanitize=address")
2097330f729Sjoerg .flag("-fexceptions")
2107330f729Sjoerg .flag("+fno-exceptions"));
211*e038c9c4Sjoerg // HWASan has higher priority because we always want the instrumentated
212*e038c9c4Sjoerg // version.
213*e038c9c4Sjoerg Multilibs.push_back(
214*e038c9c4Sjoerg Multilib("hwasan", {}, {}, 4).flag("+fsanitize=hwaddress"));
215*e038c9c4Sjoerg // Use the hwasan+noexcept variant with HWASan and -fno-exceptions.
216*e038c9c4Sjoerg Multilibs.push_back(Multilib("hwasan+noexcept", {}, {}, 5)
217*e038c9c4Sjoerg .flag("+fsanitize=hwaddress")
218*e038c9c4Sjoerg .flag("-fexceptions")
219*e038c9c4Sjoerg .flag("+fno-exceptions"));
220*e038c9c4Sjoerg // Use the relative vtables ABI.
221*e038c9c4Sjoerg // TODO: Remove these multilibs once relative vtables are enabled by default
222*e038c9c4Sjoerg // for Fuchsia.
223*e038c9c4Sjoerg Multilibs.push_back(Multilib("relative-vtables", {}, {}, 6)
224*e038c9c4Sjoerg .flag("+fexperimental-relative-c++-abi-vtables"));
225*e038c9c4Sjoerg Multilibs.push_back(Multilib("relative-vtables+noexcept", {}, {}, 7)
226*e038c9c4Sjoerg .flag("+fexperimental-relative-c++-abi-vtables")
227*e038c9c4Sjoerg .flag("-fexceptions")
228*e038c9c4Sjoerg .flag("+fno-exceptions"));
229*e038c9c4Sjoerg Multilibs.push_back(Multilib("relative-vtables+asan", {}, {}, 8)
230*e038c9c4Sjoerg .flag("+fexperimental-relative-c++-abi-vtables")
231*e038c9c4Sjoerg .flag("+fsanitize=address"));
232*e038c9c4Sjoerg Multilibs.push_back(Multilib("relative-vtables+asan+noexcept", {}, {}, 9)
233*e038c9c4Sjoerg .flag("+fexperimental-relative-c++-abi-vtables")
234*e038c9c4Sjoerg .flag("+fsanitize=address")
235*e038c9c4Sjoerg .flag("-fexceptions")
236*e038c9c4Sjoerg .flag("+fno-exceptions"));
237*e038c9c4Sjoerg Multilibs.push_back(Multilib("relative-vtables+hwasan", {}, {}, 10)
238*e038c9c4Sjoerg .flag("+fexperimental-relative-c++-abi-vtables")
239*e038c9c4Sjoerg .flag("+fsanitize=hwaddress"));
240*e038c9c4Sjoerg Multilibs.push_back(Multilib("relative-vtables+hwasan+noexcept", {}, {}, 11)
241*e038c9c4Sjoerg .flag("+fexperimental-relative-c++-abi-vtables")
242*e038c9c4Sjoerg .flag("+fsanitize=hwaddress")
243*e038c9c4Sjoerg .flag("-fexceptions")
244*e038c9c4Sjoerg .flag("+fno-exceptions"));
245*e038c9c4Sjoerg // Use Itanium C++ ABI for the compat multilib.
246*e038c9c4Sjoerg Multilibs.push_back(Multilib("compat", {}, {}, 12).flag("+fc++-abi=itanium"));
247*e038c9c4Sjoerg
2487330f729Sjoerg Multilibs.FilterOut([&](const Multilib &M) {
2497330f729Sjoerg std::vector<std::string> RD = FilePaths(M);
2507330f729Sjoerg return std::all_of(RD.begin(), RD.end(), [&](std::string P) {
2517330f729Sjoerg return !getVFS().exists(P);
2527330f729Sjoerg });
2537330f729Sjoerg });
2547330f729Sjoerg
2557330f729Sjoerg Multilib::flags_list Flags;
2567330f729Sjoerg addMultilibFlag(
2577330f729Sjoerg Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions, true),
2587330f729Sjoerg "fexceptions", Flags);
2597330f729Sjoerg addMultilibFlag(getSanitizerArgs().needsAsanRt(), "fsanitize=address", Flags);
260*e038c9c4Sjoerg addMultilibFlag(getSanitizerArgs().needsHwasanRt(), "fsanitize=hwaddress",
261*e038c9c4Sjoerg Flags);
262*e038c9c4Sjoerg
263*e038c9c4Sjoerg addMultilibFlag(
264*e038c9c4Sjoerg Args.hasFlag(options::OPT_fexperimental_relative_cxx_abi_vtables,
265*e038c9c4Sjoerg options::OPT_fno_experimental_relative_cxx_abi_vtables,
266*e038c9c4Sjoerg /*default=*/false),
267*e038c9c4Sjoerg "fexperimental-relative-c++-abi-vtables", Flags);
268*e038c9c4Sjoerg addMultilibFlag(Args.getLastArgValue(options::OPT_fcxx_abi_EQ) == "itanium",
269*e038c9c4Sjoerg "fc++-abi=itanium", Flags);
270*e038c9c4Sjoerg
2717330f729Sjoerg Multilibs.setFilePathsCallback(FilePaths);
2727330f729Sjoerg
2737330f729Sjoerg if (Multilibs.select(Flags, SelectedMultilib))
2747330f729Sjoerg if (!SelectedMultilib.isDefault())
2757330f729Sjoerg if (const auto &PathsCallback = Multilibs.filePathsCallback())
2767330f729Sjoerg for (const auto &Path : PathsCallback(SelectedMultilib))
2777330f729Sjoerg // Prepend the multilib path to ensure it takes the precedence.
2787330f729Sjoerg getFilePaths().insert(getFilePaths().begin(), Path);
2797330f729Sjoerg }
2807330f729Sjoerg
ComputeEffectiveClangTriple(const ArgList & Args,types::ID InputType) const2817330f729Sjoerg std::string Fuchsia::ComputeEffectiveClangTriple(const ArgList &Args,
2827330f729Sjoerg types::ID InputType) const {
2837330f729Sjoerg llvm::Triple Triple(ComputeLLVMTriple(Args, InputType));
284*e038c9c4Sjoerg return Triple.str();
2857330f729Sjoerg }
2867330f729Sjoerg
buildLinker() const2877330f729Sjoerg Tool *Fuchsia::buildLinker() const {
2887330f729Sjoerg return new tools::fuchsia::Linker(*this);
2897330f729Sjoerg }
2907330f729Sjoerg
GetRuntimeLibType(const ArgList & Args) const2917330f729Sjoerg ToolChain::RuntimeLibType Fuchsia::GetRuntimeLibType(
2927330f729Sjoerg const ArgList &Args) const {
2937330f729Sjoerg if (Arg *A = Args.getLastArg(clang::driver::options::OPT_rtlib_EQ)) {
2947330f729Sjoerg StringRef Value = A->getValue();
2957330f729Sjoerg if (Value != "compiler-rt")
2967330f729Sjoerg getDriver().Diag(clang::diag::err_drv_invalid_rtlib_name)
2977330f729Sjoerg << A->getAsString(Args);
2987330f729Sjoerg }
2997330f729Sjoerg
3007330f729Sjoerg return ToolChain::RLT_CompilerRT;
3017330f729Sjoerg }
3027330f729Sjoerg
3037330f729Sjoerg ToolChain::CXXStdlibType
GetCXXStdlibType(const ArgList & Args) const3047330f729Sjoerg Fuchsia::GetCXXStdlibType(const ArgList &Args) const {
3057330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
3067330f729Sjoerg StringRef Value = A->getValue();
3077330f729Sjoerg if (Value != "libc++")
3087330f729Sjoerg getDriver().Diag(diag::err_drv_invalid_stdlib_name)
3097330f729Sjoerg << A->getAsString(Args);
3107330f729Sjoerg }
3117330f729Sjoerg
3127330f729Sjoerg return ToolChain::CST_Libcxx;
3137330f729Sjoerg }
3147330f729Sjoerg
addClangTargetOptions(const ArgList & DriverArgs,ArgStringList & CC1Args,Action::OffloadKind) const3157330f729Sjoerg void Fuchsia::addClangTargetOptions(const ArgList &DriverArgs,
3167330f729Sjoerg ArgStringList &CC1Args,
3177330f729Sjoerg Action::OffloadKind) const {
318*e038c9c4Sjoerg if (!DriverArgs.hasFlag(options::OPT_fuse_init_array,
3197330f729Sjoerg options::OPT_fno_use_init_array, true))
320*e038c9c4Sjoerg CC1Args.push_back("-fno-use-init-array");
3217330f729Sjoerg }
3227330f729Sjoerg
AddClangSystemIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const3237330f729Sjoerg void Fuchsia::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
3247330f729Sjoerg ArgStringList &CC1Args) const {
3257330f729Sjoerg const Driver &D = getDriver();
3267330f729Sjoerg
3277330f729Sjoerg if (DriverArgs.hasArg(options::OPT_nostdinc))
3287330f729Sjoerg return;
3297330f729Sjoerg
3307330f729Sjoerg if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
3317330f729Sjoerg SmallString<128> P(D.ResourceDir);
3327330f729Sjoerg llvm::sys::path::append(P, "include");
3337330f729Sjoerg addSystemInclude(DriverArgs, CC1Args, P);
3347330f729Sjoerg }
3357330f729Sjoerg
3367330f729Sjoerg if (DriverArgs.hasArg(options::OPT_nostdlibinc))
3377330f729Sjoerg return;
3387330f729Sjoerg
3397330f729Sjoerg // Check for configure-time C include directories.
3407330f729Sjoerg StringRef CIncludeDirs(C_INCLUDE_DIRS);
3417330f729Sjoerg if (CIncludeDirs != "") {
3427330f729Sjoerg SmallVector<StringRef, 5> dirs;
3437330f729Sjoerg CIncludeDirs.split(dirs, ":");
3447330f729Sjoerg for (StringRef dir : dirs) {
3457330f729Sjoerg StringRef Prefix =
346*e038c9c4Sjoerg llvm::sys::path::is_absolute(dir) ? "" : StringRef(D.SysRoot);
3477330f729Sjoerg addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir);
3487330f729Sjoerg }
3497330f729Sjoerg return;
3507330f729Sjoerg }
3517330f729Sjoerg
3527330f729Sjoerg if (!D.SysRoot.empty()) {
3537330f729Sjoerg SmallString<128> P(D.SysRoot);
3547330f729Sjoerg llvm::sys::path::append(P, "include");
3557330f729Sjoerg addExternCSystemInclude(DriverArgs, CC1Args, P.str());
3567330f729Sjoerg }
3577330f729Sjoerg }
3587330f729Sjoerg
AddClangCXXStdlibIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const3597330f729Sjoerg void Fuchsia::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
3607330f729Sjoerg ArgStringList &CC1Args) const {
3617330f729Sjoerg if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
3627330f729Sjoerg DriverArgs.hasArg(options::OPT_nostdincxx))
3637330f729Sjoerg return;
3647330f729Sjoerg
365*e038c9c4Sjoerg const Driver &D = getDriver();
366*e038c9c4Sjoerg std::string Target = getTripleString();
367*e038c9c4Sjoerg
368*e038c9c4Sjoerg auto AddCXXIncludePath = [&](StringRef Path) {
369*e038c9c4Sjoerg std::string Version = detectLibcxxVersion(Path);
370*e038c9c4Sjoerg if (Version.empty())
371*e038c9c4Sjoerg return;
372*e038c9c4Sjoerg
373*e038c9c4Sjoerg // First add the per-target include path.
374*e038c9c4Sjoerg SmallString<128> TargetDir(Path);
375*e038c9c4Sjoerg llvm::sys::path::append(TargetDir, Target, "c++", Version);
376*e038c9c4Sjoerg if (getVFS().exists(TargetDir))
377*e038c9c4Sjoerg addSystemInclude(DriverArgs, CC1Args, TargetDir);
378*e038c9c4Sjoerg
379*e038c9c4Sjoerg // Second add the generic one.
380*e038c9c4Sjoerg SmallString<128> Dir(Path);
381*e038c9c4Sjoerg llvm::sys::path::append(Dir, "c++", Version);
382*e038c9c4Sjoerg addSystemInclude(DriverArgs, CC1Args, Dir);
383*e038c9c4Sjoerg };
384*e038c9c4Sjoerg
3857330f729Sjoerg switch (GetCXXStdlibType(DriverArgs)) {
3867330f729Sjoerg case ToolChain::CST_Libcxx: {
387*e038c9c4Sjoerg SmallString<128> P(D.Dir);
388*e038c9c4Sjoerg llvm::sys::path::append(P, "..", "include");
389*e038c9c4Sjoerg AddCXXIncludePath(P);
3907330f729Sjoerg break;
3917330f729Sjoerg }
3927330f729Sjoerg
3937330f729Sjoerg default:
3947330f729Sjoerg llvm_unreachable("invalid stdlib name");
3957330f729Sjoerg }
3967330f729Sjoerg }
3977330f729Sjoerg
AddCXXStdlibLibArgs(const ArgList & Args,ArgStringList & CmdArgs) const3987330f729Sjoerg void Fuchsia::AddCXXStdlibLibArgs(const ArgList &Args,
3997330f729Sjoerg ArgStringList &CmdArgs) const {
4007330f729Sjoerg switch (GetCXXStdlibType(Args)) {
4017330f729Sjoerg case ToolChain::CST_Libcxx:
4027330f729Sjoerg CmdArgs.push_back("-lc++");
4037330f729Sjoerg break;
4047330f729Sjoerg
4057330f729Sjoerg case ToolChain::CST_Libstdcxx:
4067330f729Sjoerg llvm_unreachable("invalid stdlib name");
4077330f729Sjoerg }
4087330f729Sjoerg }
4097330f729Sjoerg
getSupportedSanitizers() const4107330f729Sjoerg SanitizerMask Fuchsia::getSupportedSanitizers() const {
4117330f729Sjoerg SanitizerMask Res = ToolChain::getSupportedSanitizers();
4127330f729Sjoerg Res |= SanitizerKind::Address;
413*e038c9c4Sjoerg Res |= SanitizerKind::HWAddress;
4147330f729Sjoerg Res |= SanitizerKind::PointerCompare;
4157330f729Sjoerg Res |= SanitizerKind::PointerSubtract;
4167330f729Sjoerg Res |= SanitizerKind::Fuzzer;
4177330f729Sjoerg Res |= SanitizerKind::FuzzerNoLink;
418*e038c9c4Sjoerg Res |= SanitizerKind::Leak;
4197330f729Sjoerg Res |= SanitizerKind::SafeStack;
4207330f729Sjoerg Res |= SanitizerKind::Scudo;
421*e038c9c4Sjoerg Res |= SanitizerKind::Thread;
4227330f729Sjoerg return Res;
4237330f729Sjoerg }
4247330f729Sjoerg
getDefaultSanitizers() const4257330f729Sjoerg SanitizerMask Fuchsia::getDefaultSanitizers() const {
4267330f729Sjoerg SanitizerMask Res;
427*e038c9c4Sjoerg switch (getTriple().getArch()) {
428*e038c9c4Sjoerg case llvm::Triple::aarch64:
4297330f729Sjoerg Res |= SanitizerKind::ShadowCallStack;
430*e038c9c4Sjoerg break;
431*e038c9c4Sjoerg case llvm::Triple::x86_64:
4327330f729Sjoerg Res |= SanitizerKind::SafeStack;
433*e038c9c4Sjoerg break;
434*e038c9c4Sjoerg default:
435*e038c9c4Sjoerg // TODO: Enable SafeStack on RISC-V once tested.
436*e038c9c4Sjoerg break;
437*e038c9c4Sjoerg }
4387330f729Sjoerg return Res;
4397330f729Sjoerg }
440*e038c9c4Sjoerg
addProfileRTLibs(const llvm::opt::ArgList & Args,llvm::opt::ArgStringList & CmdArgs) const441*e038c9c4Sjoerg void Fuchsia::addProfileRTLibs(const llvm::opt::ArgList &Args,
442*e038c9c4Sjoerg llvm::opt::ArgStringList &CmdArgs) const {
443*e038c9c4Sjoerg // Add linker option -u__llvm_profile_runtime to cause runtime
444*e038c9c4Sjoerg // initialization module to be linked in.
445*e038c9c4Sjoerg if (needsProfileRT(Args))
446*e038c9c4Sjoerg CmdArgs.push_back(Args.MakeArgString(
447*e038c9c4Sjoerg Twine("-u", llvm::getInstrProfRuntimeHookVarName())));
448*e038c9c4Sjoerg ToolChain::addProfileRTLibs(Args, CmdArgs);
449*e038c9c4Sjoerg }
450