/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Driver/ToolChains/PPCLinux.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- PPCLinux.cpp - PowerPC 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 "PPCLinux.h" |
10 | | #include "clang/Driver/Driver.h" |
11 | | #include "clang/Driver/DriverDiagnostic.h" |
12 | | #include "clang/Driver/Options.h" |
13 | | #include "llvm/Support/FileSystem.h" |
14 | | #include "llvm/Support/Path.h" |
15 | | |
16 | | using namespace clang::driver; |
17 | | using namespace clang::driver::toolchains; |
18 | | using namespace llvm::opt; |
19 | | using namespace llvm::sys; |
20 | | |
21 | | // Glibc older than 2.32 doesn't fully support IEEE float128. Here we check |
22 | | // glibc version by looking at dynamic linker name. |
23 | 3 | static bool GlibcSupportsFloat128(const std::string &Linker) { |
24 | 3 | llvm::SmallVector<char, 16> Path; |
25 | | |
26 | | // Resolve potential symlinks to linker. |
27 | 3 | if (fs::real_path(Linker, Path)) |
28 | 3 | return false; |
29 | 0 | llvm::StringRef LinkerName = |
30 | 0 | path::filename(llvm::StringRef(Path.data(), Path.size())); |
31 | | |
32 | | // Since glibc 2.34, the installed .so file is not symlink anymore. But we can |
33 | | // still safely assume it's newer than 2.32. |
34 | 0 | if (LinkerName.startswith("ld64.so")) |
35 | 0 | return true; |
36 | | |
37 | 0 | if (!LinkerName.startswith("ld-2.")) |
38 | 0 | return false; |
39 | 0 | unsigned Minor = (LinkerName[5] - '0') * 10 + (LinkerName[6] - '0'); |
40 | 0 | if (Minor < 32) |
41 | 0 | return false; |
42 | | |
43 | 0 | return true; |
44 | 0 | } |
45 | | |
46 | | PPCLinuxToolChain::PPCLinuxToolChain(const Driver &D, |
47 | | const llvm::Triple &Triple, |
48 | | const llvm::opt::ArgList &Args) |
49 | 249 | : Linux(D, Triple, Args) { |
50 | 249 | if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) { |
51 | 23 | StringRef ABIName = A->getValue(); |
52 | | |
53 | 23 | if ((ABIName == "ieeelongdouble" && |
54 | 23 | !SupportIEEEFloat128(D, Triple, Args)3 ) || |
55 | 23 | (20 ABIName == "ibmlongdouble"20 && !supportIBMLongDouble(D, Args)5 )) |
56 | 3 | D.Diag(diag::warn_drv_unsupported_float_abi_by_lib) << ABIName; |
57 | 23 | } |
58 | 249 | } |
59 | | |
60 | | void PPCLinuxToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, |
61 | 247 | ArgStringList &CC1Args) const { |
62 | 247 | if (!DriverArgs.hasArg(clang::driver::options::OPT_nostdinc) && |
63 | 247 | !DriverArgs.hasArg(options::OPT_nobuiltininc)) { |
64 | 247 | const Driver &D = getDriver(); |
65 | 247 | SmallString<128> P(D.ResourceDir); |
66 | 247 | llvm::sys::path::append(P, "include", "ppc_wrappers"); |
67 | 247 | addSystemInclude(DriverArgs, CC1Args, P); |
68 | 247 | } |
69 | | |
70 | 247 | Linux::AddClangSystemIncludeArgs(DriverArgs, CC1Args); |
71 | 247 | } |
72 | | |
73 | | bool PPCLinuxToolChain::supportIBMLongDouble( |
74 | 5 | const Driver &D, const llvm::opt::ArgList &Args) const { |
75 | 5 | if (Args.hasArg(options::OPT_nostdlib, options::OPT_nostdlibxx)) |
76 | 0 | return true; |
77 | | |
78 | 5 | CXXStdlibType StdLib = ToolChain::GetCXXStdlibType(Args); |
79 | 5 | if (StdLib == CST_Libstdcxx) |
80 | 5 | return true; |
81 | | |
82 | 0 | return StdLib == CST_Libcxx && !defaultToIEEELongDouble(); |
83 | 5 | } |
84 | | |
85 | | bool PPCLinuxToolChain::SupportIEEEFloat128( |
86 | | const Driver &D, const llvm::Triple &Triple, |
87 | 3 | const llvm::opt::ArgList &Args) const { |
88 | 3 | if (!Triple.isLittleEndian() || !Triple.isPPC64()) |
89 | 0 | return false; |
90 | | |
91 | 3 | if (Args.hasArg(options::OPT_nostdlib, options::OPT_nostdlibxx)) |
92 | 0 | return true; |
93 | | |
94 | 3 | CXXStdlibType StdLib = ToolChain::GetCXXStdlibType(Args); |
95 | 3 | bool HasUnsupportedCXXLib = |
96 | 3 | (StdLib == CST_Libcxx && !defaultToIEEELongDouble()0 ) || |
97 | 3 | (StdLib == CST_Libstdcxx && |
98 | 3 | GCCInstallation.getVersion().isOlderThan(12, 1, 0)); |
99 | | |
100 | 3 | std::string Linker = Linux::getDynamicLinker(Args); |
101 | 3 | return GlibcSupportsFloat128((Twine(D.DyldPrefix) + Linker).str()) && |
102 | 3 | !(0 D.CCCIsCXX()0 && HasUnsupportedCXXLib0 ); |
103 | 3 | } |