xref: /freebsd-src/contrib/llvm-project/clang/lib/Driver/ToolChains/MipsLinux.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===-- MipsLinux.cpp - Mips ToolChain Implementations ----------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "MipsLinux.h"
100b57cec5SDimitry Andric #include "Arch/Mips.h"
110b57cec5SDimitry Andric #include "CommonArgs.h"
120b57cec5SDimitry Andric #include "clang/Driver/Driver.h"
130b57cec5SDimitry Andric #include "clang/Driver/DriverDiagnostic.h"
140b57cec5SDimitry Andric #include "clang/Driver/Options.h"
150b57cec5SDimitry Andric #include "llvm/Option/ArgList.h"
160b57cec5SDimitry Andric #include "llvm/Support/FileSystem.h"
170b57cec5SDimitry Andric #include "llvm/Support/Path.h"
180b57cec5SDimitry Andric 
190b57cec5SDimitry Andric using namespace clang::driver;
200b57cec5SDimitry Andric using namespace clang::driver::toolchains;
210b57cec5SDimitry Andric using namespace clang;
220b57cec5SDimitry Andric using namespace llvm::opt;
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric /// Mips Toolchain
250b57cec5SDimitry Andric MipsLLVMToolChain::MipsLLVMToolChain(const Driver &D,
260b57cec5SDimitry Andric                                      const llvm::Triple &Triple,
270b57cec5SDimitry Andric                                      const ArgList &Args)
280b57cec5SDimitry Andric     : Linux(D, Triple, Args) {
290b57cec5SDimitry Andric   // Select the correct multilib according to the given arguments.
300b57cec5SDimitry Andric   DetectedMultilibs Result;
310b57cec5SDimitry Andric   findMIPSMultilibs(D, Triple, "", Args, Result);
320b57cec5SDimitry Andric   Multilibs = Result.Multilibs;
3306c3fb27SDimitry Andric   SelectedMultilibs = Result.SelectedMultilibs;
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric   // Find out the library suffix based on the ABI.
360b57cec5SDimitry Andric   LibSuffix = tools::mips::getMipsABILibSuffix(Args, Triple);
370b57cec5SDimitry Andric   getFilePaths().clear();
380b57cec5SDimitry Andric   getFilePaths().push_back(computeSysRoot() + "/usr/lib" + LibSuffix);
390b57cec5SDimitry Andric }
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric void MipsLLVMToolChain::AddClangSystemIncludeArgs(
420b57cec5SDimitry Andric     const ArgList &DriverArgs, ArgStringList &CC1Args) const {
430b57cec5SDimitry Andric   if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc))
440b57cec5SDimitry Andric     return;
450b57cec5SDimitry Andric 
460b57cec5SDimitry Andric   const Driver &D = getDriver();
470b57cec5SDimitry Andric 
480b57cec5SDimitry Andric   if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
490b57cec5SDimitry Andric     SmallString<128> P(D.ResourceDir);
500b57cec5SDimitry Andric     llvm::sys::path::append(P, "include");
510b57cec5SDimitry Andric     addSystemInclude(DriverArgs, CC1Args, P);
520b57cec5SDimitry Andric   }
530b57cec5SDimitry Andric 
540b57cec5SDimitry Andric   if (DriverArgs.hasArg(options::OPT_nostdlibinc))
550b57cec5SDimitry Andric     return;
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric   const auto &Callback = Multilibs.includeDirsCallback();
580b57cec5SDimitry Andric   if (Callback) {
5906c3fb27SDimitry Andric     for (const auto &Path : Callback(SelectedMultilibs.back()))
60*0fca6ea1SDimitry Andric       addExternCSystemIncludeIfExists(DriverArgs, CC1Args, D.Dir + Path);
610b57cec5SDimitry Andric   }
620b57cec5SDimitry Andric }
630b57cec5SDimitry Andric 
640b57cec5SDimitry Andric Tool *MipsLLVMToolChain::buildLinker() const {
650b57cec5SDimitry Andric   return new tools::gnutools::Linker(*this);
660b57cec5SDimitry Andric }
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric std::string MipsLLVMToolChain::computeSysRoot() const {
690b57cec5SDimitry Andric   if (!getDriver().SysRoot.empty())
7006c3fb27SDimitry Andric     return getDriver().SysRoot + SelectedMultilibs.back().osSuffix();
710b57cec5SDimitry Andric 
72*0fca6ea1SDimitry Andric   const std::string InstalledDir(getDriver().Dir);
730b57cec5SDimitry Andric   std::string SysRootPath =
7406c3fb27SDimitry Andric       InstalledDir + "/../sysroot" + SelectedMultilibs.back().osSuffix();
750b57cec5SDimitry Andric   if (llvm::sys::fs::exists(SysRootPath))
760b57cec5SDimitry Andric     return SysRootPath;
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric   return std::string();
790b57cec5SDimitry Andric }
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric ToolChain::CXXStdlibType
820b57cec5SDimitry Andric MipsLLVMToolChain::GetCXXStdlibType(const ArgList &Args) const {
830b57cec5SDimitry Andric   Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
840b57cec5SDimitry Andric   if (A) {
850b57cec5SDimitry Andric     StringRef Value = A->getValue();
860b57cec5SDimitry Andric     if (Value != "libc++")
870b57cec5SDimitry Andric       getDriver().Diag(clang::diag::err_drv_invalid_stdlib_name)
880b57cec5SDimitry Andric           << A->getAsString(Args);
890b57cec5SDimitry Andric   }
900b57cec5SDimitry Andric 
910b57cec5SDimitry Andric   return ToolChain::CST_Libcxx;
920b57cec5SDimitry Andric }
930b57cec5SDimitry Andric 
940b57cec5SDimitry Andric void MipsLLVMToolChain::addLibCxxIncludePaths(
950b57cec5SDimitry Andric     const llvm::opt::ArgList &DriverArgs,
960b57cec5SDimitry Andric     llvm::opt::ArgStringList &CC1Args) const {
970b57cec5SDimitry Andric   if (const auto &Callback = Multilibs.includeDirsCallback()) {
9806c3fb27SDimitry Andric     for (std::string Path : Callback(SelectedMultilibs.back())) {
99*0fca6ea1SDimitry Andric       Path = getDriver().Dir + Path + "/c++/v1";
1000b57cec5SDimitry Andric       if (llvm::sys::fs::exists(Path)) {
1010b57cec5SDimitry Andric         addSystemInclude(DriverArgs, CC1Args, Path);
1020b57cec5SDimitry Andric         return;
1030b57cec5SDimitry Andric       }
1040b57cec5SDimitry Andric     }
1050b57cec5SDimitry Andric   }
1060b57cec5SDimitry Andric }
1070b57cec5SDimitry Andric 
1080b57cec5SDimitry Andric void MipsLLVMToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
1090b57cec5SDimitry Andric                                             ArgStringList &CmdArgs) const {
1100b57cec5SDimitry Andric   assert((GetCXXStdlibType(Args) == ToolChain::CST_Libcxx) &&
1110b57cec5SDimitry Andric          "Only -lc++ (aka libxx) is supported in this toolchain.");
1120b57cec5SDimitry Andric 
1130b57cec5SDimitry Andric   CmdArgs.push_back("-lc++");
114fcaf7f86SDimitry Andric   if (Args.hasArg(options::OPT_fexperimental_library))
115fcaf7f86SDimitry Andric     CmdArgs.push_back("-lc++experimental");
1160b57cec5SDimitry Andric   CmdArgs.push_back("-lc++abi");
1170b57cec5SDimitry Andric   CmdArgs.push_back("-lunwind");
1180b57cec5SDimitry Andric }
1190b57cec5SDimitry Andric 
1200b57cec5SDimitry Andric std::string MipsLLVMToolChain::getCompilerRT(const ArgList &Args,
1210b57cec5SDimitry Andric                                              StringRef Component,
1220b57cec5SDimitry Andric                                              FileType Type) const {
1230b57cec5SDimitry Andric   SmallString<128> Path(getDriver().ResourceDir);
12406c3fb27SDimitry Andric   llvm::sys::path::append(Path, SelectedMultilibs.back().osSuffix(), "lib" + LibSuffix,
1250b57cec5SDimitry Andric                           getOS());
1260b57cec5SDimitry Andric   const char *Suffix;
1270b57cec5SDimitry Andric   switch (Type) {
1280b57cec5SDimitry Andric   case ToolChain::FT_Object:
1290b57cec5SDimitry Andric     Suffix = ".o";
1300b57cec5SDimitry Andric     break;
1310b57cec5SDimitry Andric   case ToolChain::FT_Static:
1320b57cec5SDimitry Andric     Suffix = ".a";
1330b57cec5SDimitry Andric     break;
1340b57cec5SDimitry Andric   case ToolChain::FT_Shared:
1350b57cec5SDimitry Andric     Suffix = ".so";
1360b57cec5SDimitry Andric     break;
1370b57cec5SDimitry Andric   }
1380b57cec5SDimitry Andric   llvm::sys::path::append(
1390b57cec5SDimitry Andric       Path, Twine("libclang_rt." + Component + "-" + "mips" + Suffix));
1407a6dacacSDimitry Andric   return std::string(Path);
1410b57cec5SDimitry Andric }
142