1 //===-- PPCLinux.cpp - PowerPC ToolChain Implementations --------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
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"
16 using namespace clang::driver
;
17 using namespace clang::driver::toolchains
;
18 using namespace llvm::opt
;
19 using namespace llvm::sys
;
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 static bool GlibcSupportsFloat128(const std::string
&Linker
) {
24 llvm::SmallVector
<char, 16> Path
;
26 // Resolve potential symlinks to linker.
27 if (fs::real_path(Linker
, Path
))
29 llvm::StringRef LinkerName
=
30 path::filename(llvm::StringRef(Path
.data(), Path
.size()));
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 if (LinkerName
.startswith("ld64.so"))
37 if (!LinkerName
.startswith("ld-2."))
39 unsigned Minor
= (LinkerName
[5] - '0') * 10 + (LinkerName
[6] - '0');
46 PPCLinuxToolChain::PPCLinuxToolChain(const Driver
&D
,
47 const llvm::Triple
&Triple
,
48 const llvm::opt::ArgList
&Args
)
49 : Linux(D
, Triple
, Args
) {
50 if (Arg
*A
= Args
.getLastArg(options::OPT_mabi_EQ
)) {
51 StringRef ABIName
= A
->getValue();
52 if (ABIName
== "ieeelongdouble" && !SupportIEEEFloat128(D
, Triple
, Args
))
53 D
.Diag(diag::warn_drv_unsupported_float_abi_by_lib
) << ABIName
;
57 void PPCLinuxToolChain::AddClangSystemIncludeArgs(const ArgList
&DriverArgs
,
58 ArgStringList
&CC1Args
) const {
59 if (!DriverArgs
.hasArg(clang::driver::options::OPT_nostdinc
) &&
60 !DriverArgs
.hasArg(options::OPT_nobuiltininc
)) {
61 const Driver
&D
= getDriver();
62 SmallString
<128> P(D
.ResourceDir
);
63 llvm::sys::path::append(P
, "include", "ppc_wrappers");
64 addSystemInclude(DriverArgs
, CC1Args
, P
);
67 Linux::AddClangSystemIncludeArgs(DriverArgs
, CC1Args
);
70 bool PPCLinuxToolChain::SupportIEEEFloat128(
71 const Driver
&D
, const llvm::Triple
&Triple
,
72 const llvm::opt::ArgList
&Args
) const {
73 if (!Triple
.isLittleEndian() || !Triple
.isPPC64())
76 if (Args
.hasArg(options::OPT_nostdlib
, options::OPT_nostdlibxx
))
79 CXXStdlibType StdLib
= ToolChain::GetCXXStdlibType(Args
);
80 bool HasUnsupportedCXXLib
=
81 StdLib
== CST_Libcxx
||
82 (StdLib
== CST_Libstdcxx
&&
83 GCCInstallation
.getVersion().isOlderThan(12, 1, 0));
85 return GlibcSupportsFloat128(Linux::getDynamicLinker(Args
)) &&
86 !(D
.CCCIsCXX() && HasUnsupportedCXXLib
);