1 //===--- Mips.cpp - Mips ToolChain Implementations --------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "MipsLinux.h" 11 #include "Arch/Mips.h" 12 #include "CommonArgs.h" 13 #include "clang/Config/config.h" 14 #include "clang/Driver/Driver.h" 15 #include "clang/Driver/DriverDiagnostic.h" 16 #include "clang/Driver/Options.h" 17 #include "llvm/Option/ArgList.h" 18 #include "llvm/Support/FileSystem.h" 19 #include "llvm/Support/Path.h" 20 21 using namespace clang::driver; 22 using namespace clang::driver::toolchains; 23 using namespace clang; 24 using namespace llvm::opt; 25 26 /// Mips Toolchain 27 MipsLLVMToolChain::MipsLLVMToolChain(const Driver &D, 28 const llvm::Triple &Triple, 29 const ArgList &Args) 30 : Linux(D, Triple, Args) { 31 // Select the correct multilib according to the given arguments. 32 DetectedMultilibs Result; 33 findMIPSMultilibs(D, Triple, "", Args, Result); 34 Multilibs = Result.Multilibs; 35 SelectedMultilib = Result.SelectedMultilib; 36 37 // Find out the library suffix based on the ABI. 38 LibSuffix = tools::mips::getMipsABILibSuffix(Args, Triple); 39 getFilePaths().clear(); 40 getFilePaths().push_back(computeSysRoot() + "/usr/lib" + LibSuffix); 41 } 42 43 void MipsLLVMToolChain::AddClangSystemIncludeArgs( 44 const ArgList &DriverArgs, ArgStringList &CC1Args) const { 45 if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc)) 46 return; 47 48 const Driver &D = getDriver(); 49 50 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { 51 SmallString<128> P(D.ResourceDir); 52 llvm::sys::path::append(P, "include"); 53 addSystemInclude(DriverArgs, CC1Args, P); 54 } 55 56 if (DriverArgs.hasArg(options::OPT_nostdlibinc)) 57 return; 58 59 const auto &Callback = Multilibs.includeDirsCallback(); 60 if (Callback) { 61 for (const auto &Path : Callback(SelectedMultilib)) 62 addExternCSystemIncludeIfExists(DriverArgs, CC1Args, 63 D.getInstalledDir() + Path); 64 } 65 } 66 67 Tool *MipsLLVMToolChain::buildLinker() const { 68 return new tools::gnutools::Linker(*this); 69 } 70 71 std::string MipsLLVMToolChain::computeSysRoot() const { 72 if (!getDriver().SysRoot.empty()) 73 return getDriver().SysRoot + SelectedMultilib.osSuffix(); 74 75 const std::string InstalledDir(getDriver().getInstalledDir()); 76 std::string SysRootPath = 77 InstalledDir + "/../sysroot" + SelectedMultilib.osSuffix(); 78 if (llvm::sys::fs::exists(SysRootPath)) 79 return SysRootPath; 80 81 return std::string(); 82 } 83 84 ToolChain::CXXStdlibType 85 MipsLLVMToolChain::GetCXXStdlibType(const ArgList &Args) const { 86 Arg *A = Args.getLastArg(options::OPT_stdlib_EQ); 87 if (A) { 88 StringRef Value = A->getValue(); 89 if (Value != "libc++") 90 getDriver().Diag(clang::diag::err_drv_invalid_stdlib_name) 91 << A->getAsString(Args); 92 } 93 94 return ToolChain::CST_Libcxx; 95 } 96 97 void MipsLLVMToolChain::addLibCxxIncludePaths( 98 const llvm::opt::ArgList &DriverArgs, 99 llvm::opt::ArgStringList &CC1Args) const { 100 if (const auto &Callback = Multilibs.includeDirsCallback()) { 101 for (std::string Path : Callback(SelectedMultilib)) { 102 Path = getDriver().getInstalledDir() + Path + "/c++/v1"; 103 if (llvm::sys::fs::exists(Path)) { 104 addSystemInclude(DriverArgs, CC1Args, Path); 105 return; 106 } 107 } 108 } 109 } 110 111 void MipsLLVMToolChain::AddCXXStdlibLibArgs(const ArgList &Args, 112 ArgStringList &CmdArgs) const { 113 assert((GetCXXStdlibType(Args) == ToolChain::CST_Libcxx) && 114 "Only -lc++ (aka libxx) is supported in this toolchain."); 115 116 CmdArgs.push_back("-lc++"); 117 CmdArgs.push_back("-lc++abi"); 118 CmdArgs.push_back("-lunwind"); 119 } 120 121 std::string MipsLLVMToolChain::getCompilerRT(const ArgList &Args, 122 StringRef Component, 123 bool Shared) const { 124 SmallString<128> Path(getDriver().ResourceDir); 125 llvm::sys::path::append(Path, SelectedMultilib.osSuffix(), "lib" + LibSuffix, 126 getOS()); 127 llvm::sys::path::append(Path, Twine("libclang_rt." + Component + "-" + 128 "mips" + (Shared ? ".so" : ".a"))); 129 return Path.str(); 130 } 131