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