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