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