| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,395 @@ | ||
| //===--- FreeBSD.cpp - FreeBSD ToolChain Implementations --------*- C++ -*-===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "FreeBSD.h" | ||
| #include "Arch/ARM.h" | ||
| #include "Arch/Mips.h" | ||
| #include "Arch/Sparc.h" | ||
| #include "CommonArgs.h" | ||
| #include "clang/Basic/VirtualFileSystem.h" | ||
| #include "clang/Driver/Compilation.h" | ||
| #include "clang/Driver/Options.h" | ||
| #include "clang/Driver/SanitizerArgs.h" | ||
| #include "llvm/Option/ArgList.h" | ||
|
|
||
| using namespace clang::driver; | ||
| using namespace clang::driver::tools; | ||
| using namespace clang::driver::toolchains; | ||
| using namespace clang; | ||
| using namespace llvm::opt; | ||
|
|
||
| void freebsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA, | ||
| const InputInfo &Output, | ||
| const InputInfoList &Inputs, | ||
| const ArgList &Args, | ||
| const char *LinkingOutput) const { | ||
| claimNoWarnArgs(Args); | ||
| ArgStringList CmdArgs; | ||
|
|
||
| // When building 32-bit code on FreeBSD/amd64, we have to explicitly | ||
| // instruct as in the base system to assemble 32-bit code. | ||
| switch (getToolChain().getArch()) { | ||
| default: | ||
| break; | ||
| case llvm::Triple::x86: | ||
| CmdArgs.push_back("--32"); | ||
| break; | ||
| case llvm::Triple::ppc: | ||
| CmdArgs.push_back("-a32"); | ||
| break; | ||
| case llvm::Triple::mips: | ||
| case llvm::Triple::mipsel: | ||
| case llvm::Triple::mips64: | ||
| case llvm::Triple::mips64el: { | ||
| StringRef CPUName; | ||
| StringRef ABIName; | ||
| mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName); | ||
|
|
||
| CmdArgs.push_back("-march"); | ||
| CmdArgs.push_back(CPUName.data()); | ||
|
|
||
| CmdArgs.push_back("-mabi"); | ||
| CmdArgs.push_back(mips::getGnuCompatibleMipsABIName(ABIName).data()); | ||
|
|
||
| if (getToolChain().getArch() == llvm::Triple::mips || | ||
| getToolChain().getArch() == llvm::Triple::mips64) | ||
| CmdArgs.push_back("-EB"); | ||
| else | ||
| CmdArgs.push_back("-EL"); | ||
|
|
||
| if (Arg *A = Args.getLastArg(options::OPT_G)) { | ||
| StringRef v = A->getValue(); | ||
| CmdArgs.push_back(Args.MakeArgString("-G" + v)); | ||
| A->claim(); | ||
| } | ||
|
|
||
| AddAssemblerKPIC(getToolChain(), Args, CmdArgs); | ||
| break; | ||
| } | ||
| case llvm::Triple::arm: | ||
| case llvm::Triple::armeb: | ||
| case llvm::Triple::thumb: | ||
| case llvm::Triple::thumbeb: { | ||
| arm::FloatABI ABI = arm::getARMFloatABI(getToolChain(), Args); | ||
|
|
||
| if (ABI == arm::FloatABI::Hard) | ||
| CmdArgs.push_back("-mfpu=vfp"); | ||
| else | ||
| CmdArgs.push_back("-mfpu=softvfp"); | ||
|
|
||
| switch (getToolChain().getTriple().getEnvironment()) { | ||
| case llvm::Triple::GNUEABIHF: | ||
| case llvm::Triple::GNUEABI: | ||
| case llvm::Triple::EABI: | ||
| CmdArgs.push_back("-meabi=5"); | ||
| break; | ||
|
|
||
| default: | ||
| CmdArgs.push_back("-matpcs"); | ||
| } | ||
| break; | ||
| } | ||
| case llvm::Triple::sparc: | ||
| case llvm::Triple::sparcel: | ||
| case llvm::Triple::sparcv9: { | ||
| std::string CPU = getCPUName(Args, getToolChain().getTriple()); | ||
| CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple())); | ||
| AddAssemblerKPIC(getToolChain(), Args, CmdArgs); | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); | ||
|
|
||
| CmdArgs.push_back("-o"); | ||
| CmdArgs.push_back(Output.getFilename()); | ||
|
|
||
| for (const auto &II : Inputs) | ||
| CmdArgs.push_back(II.getFilename()); | ||
|
|
||
| const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); | ||
| C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); | ||
| } | ||
|
|
||
| void freebsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, | ||
| const InputInfo &Output, | ||
| const InputInfoList &Inputs, | ||
| const ArgList &Args, | ||
| const char *LinkingOutput) const { | ||
| const toolchains::FreeBSD &ToolChain = | ||
| static_cast<const toolchains::FreeBSD &>(getToolChain()); | ||
| const Driver &D = ToolChain.getDriver(); | ||
| const llvm::Triple::ArchType Arch = ToolChain.getArch(); | ||
| const bool IsPIE = | ||
| !Args.hasArg(options::OPT_shared) && | ||
| (Args.hasArg(options::OPT_pie) || ToolChain.isPIEDefault()); | ||
| ArgStringList CmdArgs; | ||
|
|
||
| // Silence warning for "clang -g foo.o -o foo" | ||
| Args.ClaimAllArgs(options::OPT_g_Group); | ||
| // and "clang -emit-llvm foo.o -o foo" | ||
| Args.ClaimAllArgs(options::OPT_emit_llvm); | ||
| // and for "clang -w foo.o -o foo". Other warning options are already | ||
| // handled somewhere else. | ||
| Args.ClaimAllArgs(options::OPT_w); | ||
|
|
||
| if (!D.SysRoot.empty()) | ||
| CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); | ||
|
|
||
| if (IsPIE) | ||
| CmdArgs.push_back("-pie"); | ||
|
|
||
| CmdArgs.push_back("--eh-frame-hdr"); | ||
| if (Args.hasArg(options::OPT_static)) { | ||
| CmdArgs.push_back("-Bstatic"); | ||
| } else { | ||
| if (Args.hasArg(options::OPT_rdynamic)) | ||
| CmdArgs.push_back("-export-dynamic"); | ||
| if (Args.hasArg(options::OPT_shared)) { | ||
| CmdArgs.push_back("-Bshareable"); | ||
| } else { | ||
| CmdArgs.push_back("-dynamic-linker"); | ||
| CmdArgs.push_back("/libexec/ld-elf.so.1"); | ||
| } | ||
| if (ToolChain.getTriple().getOSMajorVersion() >= 9) { | ||
| if (Arch == llvm::Triple::arm || Arch == llvm::Triple::sparc || | ||
| Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64) { | ||
| CmdArgs.push_back("--hash-style=both"); | ||
| } | ||
| } | ||
| CmdArgs.push_back("--enable-new-dtags"); | ||
| } | ||
|
|
||
| // When building 32-bit code on FreeBSD/amd64, we have to explicitly | ||
| // instruct ld in the base system to link 32-bit code. | ||
| if (Arch == llvm::Triple::x86) { | ||
| CmdArgs.push_back("-m"); | ||
| CmdArgs.push_back("elf_i386_fbsd"); | ||
| } | ||
|
|
||
| if (Arch == llvm::Triple::ppc) { | ||
| CmdArgs.push_back("-m"); | ||
| CmdArgs.push_back("elf32ppc_fbsd"); | ||
| } | ||
|
|
||
| if (Arg *A = Args.getLastArg(options::OPT_G)) { | ||
| if (ToolChain.getArch() == llvm::Triple::mips || | ||
| ToolChain.getArch() == llvm::Triple::mipsel || | ||
| ToolChain.getArch() == llvm::Triple::mips64 || | ||
| ToolChain.getArch() == llvm::Triple::mips64el) { | ||
| StringRef v = A->getValue(); | ||
| CmdArgs.push_back(Args.MakeArgString("-G" + v)); | ||
| A->claim(); | ||
| } | ||
| } | ||
|
|
||
| if (Output.isFilename()) { | ||
| CmdArgs.push_back("-o"); | ||
| CmdArgs.push_back(Output.getFilename()); | ||
| } else { | ||
| assert(Output.isNothing() && "Invalid output."); | ||
| } | ||
|
|
||
| if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { | ||
| const char *crt1 = nullptr; | ||
| if (!Args.hasArg(options::OPT_shared)) { | ||
| if (Args.hasArg(options::OPT_pg)) | ||
| crt1 = "gcrt1.o"; | ||
| else if (IsPIE) | ||
| crt1 = "Scrt1.o"; | ||
| else | ||
| crt1 = "crt1.o"; | ||
| } | ||
| if (crt1) | ||
| CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt1))); | ||
|
|
||
| CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o"))); | ||
|
|
||
| const char *crtbegin = nullptr; | ||
| if (Args.hasArg(options::OPT_static)) | ||
| crtbegin = "crtbeginT.o"; | ||
| else if (Args.hasArg(options::OPT_shared) || IsPIE) | ||
| crtbegin = "crtbeginS.o"; | ||
| else | ||
| crtbegin = "crtbegin.o"; | ||
|
|
||
| CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin))); | ||
| } | ||
|
|
||
| Args.AddAllArgs(CmdArgs, options::OPT_L); | ||
| ToolChain.AddFilePathLibArgs(Args, CmdArgs); | ||
| Args.AddAllArgs(CmdArgs, options::OPT_T_Group); | ||
| Args.AddAllArgs(CmdArgs, options::OPT_e); | ||
| Args.AddAllArgs(CmdArgs, options::OPT_s); | ||
| Args.AddAllArgs(CmdArgs, options::OPT_t); | ||
| Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag); | ||
| Args.AddAllArgs(CmdArgs, options::OPT_r); | ||
|
|
||
| if (D.isUsingLTO()) | ||
| AddGoldPlugin(ToolChain, Args, CmdArgs, D.getLTOMode() == LTOK_Thin, D); | ||
|
|
||
| bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs); | ||
| AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA); | ||
|
|
||
| if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { | ||
| addOpenMPRuntime(CmdArgs, ToolChain, Args); | ||
| if (D.CCCIsCXX()) { | ||
| ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs); | ||
| if (Args.hasArg(options::OPT_pg)) | ||
| CmdArgs.push_back("-lm_p"); | ||
| else | ||
| CmdArgs.push_back("-lm"); | ||
| } | ||
| if (NeedsSanitizerDeps) | ||
| linkSanitizerRuntimeDeps(ToolChain, CmdArgs); | ||
| // FIXME: For some reason GCC passes -lgcc and -lgcc_s before adding | ||
| // the default system libraries. Just mimic this for now. | ||
| if (Args.hasArg(options::OPT_pg)) | ||
| CmdArgs.push_back("-lgcc_p"); | ||
| else | ||
| CmdArgs.push_back("-lgcc"); | ||
| if (Args.hasArg(options::OPT_static)) { | ||
| CmdArgs.push_back("-lgcc_eh"); | ||
| } else if (Args.hasArg(options::OPT_pg)) { | ||
| CmdArgs.push_back("-lgcc_eh_p"); | ||
| } else { | ||
| CmdArgs.push_back("--as-needed"); | ||
| CmdArgs.push_back("-lgcc_s"); | ||
| CmdArgs.push_back("--no-as-needed"); | ||
| } | ||
|
|
||
| if (Args.hasArg(options::OPT_pthread)) { | ||
| if (Args.hasArg(options::OPT_pg)) | ||
| CmdArgs.push_back("-lpthread_p"); | ||
| else | ||
| CmdArgs.push_back("-lpthread"); | ||
| } | ||
|
|
||
| if (Args.hasArg(options::OPT_pg)) { | ||
| if (Args.hasArg(options::OPT_shared)) | ||
| CmdArgs.push_back("-lc"); | ||
| else | ||
| CmdArgs.push_back("-lc_p"); | ||
| CmdArgs.push_back("-lgcc_p"); | ||
| } else { | ||
| CmdArgs.push_back("-lc"); | ||
| CmdArgs.push_back("-lgcc"); | ||
| } | ||
|
|
||
| if (Args.hasArg(options::OPT_static)) { | ||
| CmdArgs.push_back("-lgcc_eh"); | ||
| } else if (Args.hasArg(options::OPT_pg)) { | ||
| CmdArgs.push_back("-lgcc_eh_p"); | ||
| } else { | ||
| CmdArgs.push_back("--as-needed"); | ||
| CmdArgs.push_back("-lgcc_s"); | ||
| CmdArgs.push_back("--no-as-needed"); | ||
| } | ||
| } | ||
|
|
||
| if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { | ||
| if (Args.hasArg(options::OPT_shared) || IsPIE) | ||
| CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtendS.o"))); | ||
| else | ||
| CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o"))); | ||
| CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o"))); | ||
| } | ||
|
|
||
| ToolChain.addProfileRTLibs(Args, CmdArgs); | ||
|
|
||
| const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath()); | ||
| C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); | ||
| } | ||
|
|
||
| /// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly. | ||
|
|
||
| FreeBSD::FreeBSD(const Driver &D, const llvm::Triple &Triple, | ||
| const ArgList &Args) | ||
| : Generic_ELF(D, Triple, Args) { | ||
|
|
||
| // When targeting 32-bit platforms, look for '/usr/lib32/crt1.o' and fall | ||
| // back to '/usr/lib' if it doesn't exist. | ||
| if ((Triple.getArch() == llvm::Triple::x86 || | ||
| Triple.getArch() == llvm::Triple::ppc) && | ||
| D.getVFS().exists(getDriver().SysRoot + "/usr/lib32/crt1.o")) | ||
| getFilePaths().push_back(getDriver().SysRoot + "/usr/lib32"); | ||
| else | ||
| getFilePaths().push_back(getDriver().SysRoot + "/usr/lib"); | ||
| } | ||
|
|
||
| ToolChain::CXXStdlibType FreeBSD::GetDefaultCXXStdlibType() const { | ||
| if (getTriple().getOSMajorVersion() >= 10) | ||
| return ToolChain::CST_Libcxx; | ||
| return ToolChain::CST_Libstdcxx; | ||
| } | ||
|
|
||
| void FreeBSD::addLibStdCxxIncludePaths( | ||
| const llvm::opt::ArgList &DriverArgs, | ||
| llvm::opt::ArgStringList &CC1Args) const { | ||
| addLibStdCXXIncludePaths(getDriver().SysRoot, "/usr/include/c++/4.2", "", "", | ||
| "", "", DriverArgs, CC1Args); | ||
| } | ||
|
|
||
| void FreeBSD::AddCXXStdlibLibArgs(const ArgList &Args, | ||
| ArgStringList &CmdArgs) const { | ||
| CXXStdlibType Type = GetCXXStdlibType(Args); | ||
| bool Profiling = Args.hasArg(options::OPT_pg); | ||
|
|
||
| switch (Type) { | ||
| case ToolChain::CST_Libcxx: | ||
| CmdArgs.push_back(Profiling ? "-lc++_p" : "-lc++"); | ||
| break; | ||
|
|
||
| case ToolChain::CST_Libstdcxx: | ||
| CmdArgs.push_back(Profiling ? "-lstdc++_p" : "-lstdc++"); | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| Tool *FreeBSD::buildAssembler() const { | ||
| return new tools::freebsd::Assembler(*this); | ||
| } | ||
|
|
||
| Tool *FreeBSD::buildLinker() const { return new tools::freebsd::Linker(*this); } | ||
|
|
||
| bool FreeBSD::UseSjLjExceptions(const ArgList &Args) const { | ||
| // FreeBSD uses SjLj exceptions on ARM oabi. | ||
| switch (getTriple().getEnvironment()) { | ||
| case llvm::Triple::GNUEABIHF: | ||
| case llvm::Triple::GNUEABI: | ||
| case llvm::Triple::EABI: | ||
| return false; | ||
|
|
||
| default: | ||
| return (getTriple().getArch() == llvm::Triple::arm || | ||
| getTriple().getArch() == llvm::Triple::thumb); | ||
| } | ||
| } | ||
|
|
||
| bool FreeBSD::HasNativeLLVMSupport() const { return true; } | ||
|
|
||
| bool FreeBSD::isPIEDefault() const { return getSanitizerArgs().requiresPIE(); } | ||
|
|
||
| SanitizerMask FreeBSD::getSupportedSanitizers() const { | ||
| const bool IsX86 = getTriple().getArch() == llvm::Triple::x86; | ||
| const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64; | ||
| const bool IsMIPS64 = getTriple().getArch() == llvm::Triple::mips64 || | ||
| getTriple().getArch() == llvm::Triple::mips64el; | ||
| SanitizerMask Res = ToolChain::getSupportedSanitizers(); | ||
| Res |= SanitizerKind::Address; | ||
| Res |= SanitizerKind::Vptr; | ||
| if (IsX86_64 || IsMIPS64) { | ||
| Res |= SanitizerKind::Leak; | ||
| Res |= SanitizerKind::Thread; | ||
| } | ||
| if (IsX86 || IsX86_64) { | ||
| Res |= SanitizerKind::SafeStack; | ||
| } | ||
| return Res; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
| //===--- FreeBSD.h - FreeBSD ToolChain Implementations ----------*- C++ -*-===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_FREEBSD_H | ||
| #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_FREEBSD_H | ||
|
|
||
| #include "Gnu.h" | ||
| #include "clang/Driver/Driver.h" | ||
| #include "clang/Driver/ToolChain.h" | ||
|
|
||
| namespace clang { | ||
| namespace driver { | ||
| namespace tools { | ||
|
|
||
| /// freebsd -- Directly call GNU Binutils assembler and linker | ||
| namespace freebsd { | ||
| class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool { | ||
| public: | ||
| Assembler(const ToolChain &TC) | ||
| : GnuTool("freebsd::Assembler", "assembler", TC) {} | ||
|
|
||
| bool hasIntegratedCPP() const override { return false; } | ||
|
|
||
| void ConstructJob(Compilation &C, const JobAction &JA, | ||
| const InputInfo &Output, const InputInfoList &Inputs, | ||
| const llvm::opt::ArgList &TCArgs, | ||
| const char *LinkingOutput) const override; | ||
| }; | ||
|
|
||
| class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { | ||
| public: | ||
| Linker(const ToolChain &TC) : GnuTool("freebsd::Linker", "linker", TC) {} | ||
|
|
||
| bool hasIntegratedCPP() const override { return false; } | ||
| bool isLinkJob() const override { return true; } | ||
|
|
||
| void ConstructJob(Compilation &C, const JobAction &JA, | ||
| const InputInfo &Output, const InputInfoList &Inputs, | ||
| const llvm::opt::ArgList &TCArgs, | ||
| const char *LinkingOutput) const override; | ||
| }; | ||
| } // end namespace freebsd | ||
| } // end namespace tools | ||
|
|
||
| namespace toolchains { | ||
|
|
||
| class LLVM_LIBRARY_VISIBILITY FreeBSD : public Generic_ELF { | ||
| public: | ||
| FreeBSD(const Driver &D, const llvm::Triple &Triple, | ||
| const llvm::opt::ArgList &Args); | ||
| bool HasNativeLLVMSupport() const override; | ||
|
|
||
| bool IsMathErrnoDefault() const override { return false; } | ||
| bool IsObjCNonFragileABIDefault() const override { return true; } | ||
|
|
||
| CXXStdlibType GetDefaultCXXStdlibType() const override; | ||
| void addLibStdCxxIncludePaths( | ||
| const llvm::opt::ArgList &DriverArgs, | ||
| llvm::opt::ArgStringList &CC1Args) const override; | ||
| void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, | ||
| llvm::opt::ArgStringList &CmdArgs) const override; | ||
|
|
||
| bool UseSjLjExceptions(const llvm::opt::ArgList &Args) const override; | ||
| bool isPIEDefault() const override; | ||
| SanitizerMask getSupportedSanitizers() const override; | ||
| unsigned GetDefaultDwarfVersion() const override { return 2; } | ||
| // Until dtrace (via CTF) and LLDB can deal with distributed debug info, | ||
| // FreeBSD defaults to standalone/full debug info. | ||
| bool GetDefaultStandaloneDebug() const override { return true; } | ||
|
|
||
| protected: | ||
| Tool *buildAssembler() const override; | ||
| Tool *buildLinker() const override; | ||
| }; | ||
|
|
||
| } // end namespace toolchains | ||
| } // end namespace driver | ||
| } // end namespace clang | ||
|
|
||
| #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_FREEBSD_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,229 @@ | ||
| //===--- Fuchsia.cpp - Fuchsia ToolChain Implementations --------*- C++ -*-===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "Fuchsia.h" | ||
| #include "CommonArgs.h" | ||
| #include "clang/Config/config.h" | ||
| #include "clang/Driver/Compilation.h" | ||
| #include "clang/Driver/Driver.h" | ||
| #include "clang/Driver/DriverDiagnostic.h" | ||
| #include "clang/Driver/Options.h" | ||
| #include "llvm/Option/ArgList.h" | ||
| #include "llvm/Support/Path.h" | ||
|
|
||
| using namespace clang::driver; | ||
| using namespace clang::driver::toolchains; | ||
| using namespace clang::driver::tools; | ||
| using namespace clang; | ||
| using namespace llvm::opt; | ||
|
|
||
| void fuchsia::Linker::ConstructJob(Compilation &C, const JobAction &JA, | ||
| const InputInfo &Output, | ||
| const InputInfoList &Inputs, | ||
| const ArgList &Args, | ||
| const char *LinkingOutput) const { | ||
| const toolchains::Fuchsia &ToolChain = | ||
| static_cast<const toolchains::Fuchsia &>(getToolChain()); | ||
| const Driver &D = ToolChain.getDriver(); | ||
|
|
||
| ArgStringList CmdArgs; | ||
|
|
||
| // Silence warning for "clang -g foo.o -o foo" | ||
| Args.ClaimAllArgs(options::OPT_g_Group); | ||
| // and "clang -emit-llvm foo.o -o foo" | ||
| Args.ClaimAllArgs(options::OPT_emit_llvm); | ||
| // and for "clang -w foo.o -o foo". Other warning options are already | ||
| // handled somewhere else. | ||
| Args.ClaimAllArgs(options::OPT_w); | ||
|
|
||
| const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath()); | ||
| if (llvm::sys::path::stem(Exec).equals_lower("lld")) { | ||
| CmdArgs.push_back("-flavor"); | ||
| CmdArgs.push_back("gnu"); | ||
| } | ||
|
|
||
| if (!D.SysRoot.empty()) | ||
| CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); | ||
|
|
||
| if (!Args.hasArg(options::OPT_shared) && !Args.hasArg(options::OPT_r)) | ||
| CmdArgs.push_back("-pie"); | ||
|
|
||
| if (Args.hasArg(options::OPT_rdynamic)) | ||
| CmdArgs.push_back("-export-dynamic"); | ||
|
|
||
| if (Args.hasArg(options::OPT_s)) | ||
| CmdArgs.push_back("-s"); | ||
|
|
||
| if (Args.hasArg(options::OPT_r)) | ||
| CmdArgs.push_back("-r"); | ||
| else | ||
| CmdArgs.push_back("--build-id"); | ||
|
|
||
| if (!Args.hasArg(options::OPT_static)) | ||
| CmdArgs.push_back("--eh-frame-hdr"); | ||
|
|
||
| if (Args.hasArg(options::OPT_static)) | ||
| CmdArgs.push_back("-Bstatic"); | ||
| else if (Args.hasArg(options::OPT_shared)) | ||
| CmdArgs.push_back("-shared"); | ||
|
|
||
| if (!Args.hasArg(options::OPT_static)) { | ||
| if (Args.hasArg(options::OPT_rdynamic)) | ||
| CmdArgs.push_back("-export-dynamic"); | ||
|
|
||
| if (!Args.hasArg(options::OPT_shared)) { | ||
| CmdArgs.push_back("-dynamic-linker"); | ||
| CmdArgs.push_back(Args.MakeArgString(D.DyldPrefix + "ld.so.1")); | ||
| } | ||
| } | ||
|
|
||
| CmdArgs.push_back("-o"); | ||
| CmdArgs.push_back(Output.getFilename()); | ||
|
|
||
| if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { | ||
| if (!Args.hasArg(options::OPT_shared)) { | ||
| CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("Scrt1.o"))); | ||
| } | ||
| } | ||
|
|
||
| Args.AddAllArgs(CmdArgs, options::OPT_L); | ||
| Args.AddAllArgs(CmdArgs, options::OPT_u); | ||
|
|
||
| ToolChain.AddFilePathLibArgs(Args, CmdArgs); | ||
|
|
||
| AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA); | ||
|
|
||
| if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { | ||
| if (Args.hasArg(options::OPT_static)) | ||
| CmdArgs.push_back("-Bdynamic"); | ||
|
|
||
| if (D.CCCIsCXX()) { | ||
| bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) && | ||
| !Args.hasArg(options::OPT_static); | ||
| if (OnlyLibstdcxxStatic) | ||
| CmdArgs.push_back("-Bstatic"); | ||
| ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs); | ||
| if (OnlyLibstdcxxStatic) | ||
| CmdArgs.push_back("-Bdynamic"); | ||
| CmdArgs.push_back("-lm"); | ||
| } | ||
|
|
||
| AddRunTimeLibs(ToolChain, D, CmdArgs, Args); | ||
|
|
||
| if (Args.hasArg(options::OPT_pthread) || | ||
| Args.hasArg(options::OPT_pthreads)) | ||
| CmdArgs.push_back("-lpthread"); | ||
|
|
||
| if (Args.hasArg(options::OPT_fsplit_stack)) | ||
| CmdArgs.push_back("--wrap=pthread_create"); | ||
|
|
||
| CmdArgs.push_back("-lc"); | ||
| } | ||
|
|
||
| C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); | ||
| } | ||
|
|
||
| /// Fuchsia - Fuchsia tool chain which can call as(1) and ld(1) directly. | ||
|
|
||
| Fuchsia::Fuchsia(const Driver &D, const llvm::Triple &Triple, | ||
| const ArgList &Args) | ||
| : Generic_ELF(D, Triple, Args) { | ||
|
|
||
| getFilePaths().push_back(D.SysRoot + "/lib"); | ||
| getFilePaths().push_back(D.ResourceDir + "/lib/fuchsia"); | ||
| } | ||
|
|
||
| Tool *Fuchsia::buildAssembler() const { | ||
| return new tools::gnutools::Assembler(*this); | ||
| } | ||
|
|
||
| Tool *Fuchsia::buildLinker() const { | ||
| return new tools::fuchsia::Linker(*this); | ||
| } | ||
|
|
||
| ToolChain::RuntimeLibType Fuchsia::GetRuntimeLibType( | ||
| const ArgList &Args) const { | ||
| if (Arg *A = Args.getLastArg(clang::driver::options::OPT_rtlib_EQ)) { | ||
| StringRef Value = A->getValue(); | ||
| if (Value != "compiler-rt") | ||
| getDriver().Diag(clang::diag::err_drv_invalid_rtlib_name) | ||
| << A->getAsString(Args); | ||
| } | ||
|
|
||
| return ToolChain::RLT_CompilerRT; | ||
| } | ||
|
|
||
| ToolChain::CXXStdlibType | ||
| Fuchsia::GetCXXStdlibType(const ArgList &Args) const { | ||
| if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) { | ||
| StringRef Value = A->getValue(); | ||
| if (Value != "libc++") | ||
| getDriver().Diag(diag::err_drv_invalid_stdlib_name) | ||
| << A->getAsString(Args); | ||
| } | ||
|
|
||
| return ToolChain::CST_Libcxx; | ||
| } | ||
|
|
||
| void Fuchsia::addClangTargetOptions(const ArgList &DriverArgs, | ||
| ArgStringList &CC1Args) const { | ||
| if (DriverArgs.hasFlag(options::OPT_fuse_init_array, | ||
| options::OPT_fno_use_init_array, true)) | ||
| CC1Args.push_back("-fuse-init-array"); | ||
| } | ||
|
|
||
| void Fuchsia::AddClangSystemIncludeArgs(const ArgList &DriverArgs, | ||
| ArgStringList &CC1Args) const { | ||
| const Driver &D = getDriver(); | ||
|
|
||
| if (DriverArgs.hasArg(options::OPT_nostdinc)) | ||
| return; | ||
|
|
||
| if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { | ||
| SmallString<128> P(D.ResourceDir); | ||
| llvm::sys::path::append(P, "include"); | ||
| addSystemInclude(DriverArgs, CC1Args, P); | ||
| } | ||
|
|
||
| if (DriverArgs.hasArg(options::OPT_nostdlibinc)) | ||
| return; | ||
|
|
||
| // Check for configure-time C include directories. | ||
| StringRef CIncludeDirs(C_INCLUDE_DIRS); | ||
| if (CIncludeDirs != "") { | ||
| SmallVector<StringRef, 5> dirs; | ||
| CIncludeDirs.split(dirs, ":"); | ||
| for (StringRef dir : dirs) { | ||
| StringRef Prefix = | ||
| llvm::sys::path::is_absolute(dir) ? StringRef(D.SysRoot) : ""; | ||
| addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir); | ||
| } | ||
| return; | ||
| } | ||
|
|
||
| addExternCSystemInclude(DriverArgs, CC1Args, D.SysRoot + "/include"); | ||
| } | ||
|
|
||
| std::string Fuchsia::findLibCxxIncludePath() const { | ||
| return getDriver().SysRoot + "/include/c++/v1"; | ||
| } | ||
|
|
||
| void Fuchsia::AddCXXStdlibLibArgs(const ArgList &Args, | ||
| ArgStringList &CmdArgs) const { | ||
| (void) GetCXXStdlibType(Args); | ||
| CmdArgs.push_back("-lc++"); | ||
| CmdArgs.push_back("-lc++abi"); | ||
| CmdArgs.push_back("-lunwind"); | ||
| } | ||
|
|
||
| SanitizerMask Fuchsia::getSupportedSanitizers() const { | ||
| SanitizerMask Res = ToolChain::getSupportedSanitizers(); | ||
| Res |= SanitizerKind::SafeStack; | ||
| return Res; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| //===--- Fuchsia.h - Fuchsia ToolChain Implementations ----------*- C++ -*-===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_FUCHSIA_H | ||
| #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_FUCHSIA_H | ||
|
|
||
| #include "Gnu.h" | ||
| #include "clang/Driver/Tool.h" | ||
| #include "clang/Driver/ToolChain.h" | ||
|
|
||
| namespace clang { | ||
| namespace driver { | ||
| namespace tools { | ||
| namespace fuchsia { | ||
| class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { | ||
| public: | ||
| Linker(const ToolChain &TC) : GnuTool("fuchsia::Linker", "ld.lld", TC) {} | ||
|
|
||
| bool hasIntegratedCPP() const override { return false; } | ||
| bool isLinkJob() const override { return true; } | ||
|
|
||
| void ConstructJob(Compilation &C, const JobAction &JA, | ||
| const InputInfo &Output, const InputInfoList &Inputs, | ||
| const llvm::opt::ArgList &TCArgs, | ||
| const char *LinkingOutput) const override; | ||
| }; | ||
| } // end namespace fuchsia | ||
| } // end namespace tools | ||
|
|
||
| namespace toolchains { | ||
|
|
||
| class LLVM_LIBRARY_VISIBILITY Fuchsia : public Generic_ELF { | ||
| public: | ||
| Fuchsia(const Driver &D, const llvm::Triple &Triple, | ||
| const llvm::opt::ArgList &Args); | ||
|
|
||
| bool isPIEDefault() const override { return true; } | ||
| bool HasNativeLLVMSupport() const override { return true; } | ||
| bool IsIntegratedAssemblerDefault() const override { return true; } | ||
| llvm::DebuggerKind getDefaultDebuggerTuning() const override { | ||
| return llvm::DebuggerKind::GDB; | ||
| } | ||
|
|
||
| SanitizerMask getSupportedSanitizers() const override; | ||
|
|
||
| RuntimeLibType | ||
| GetRuntimeLibType(const llvm::opt::ArgList &Args) const override; | ||
| CXXStdlibType | ||
| GetCXXStdlibType(const llvm::opt::ArgList &Args) const override; | ||
|
|
||
| void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, | ||
| llvm::opt::ArgStringList &CC1Args) const override; | ||
| void | ||
| AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, | ||
| llvm::opt::ArgStringList &CC1Args) const override; | ||
| std::string findLibCxxIncludePath() const override; | ||
| void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, | ||
| llvm::opt::ArgStringList &CmdArgs) const override; | ||
|
|
||
| const char *getDefaultLinker() const override { | ||
| return "lld"; | ||
| } | ||
|
|
||
| protected: | ||
| Tool *buildAssembler() const override; | ||
| Tool *buildLinker() const override; | ||
| }; | ||
|
|
||
| } // end namespace toolchains | ||
| } // end namespace driver | ||
| } // end namespace clang | ||
|
|
||
| #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_FUCHSIA_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,351 @@ | ||
| //===--- Gnu.h - Gnu Tool and ToolChain Implementations ---------*- C++ -*-===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_GNU_H | ||
| #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_GNU_H | ||
|
|
||
| #include "Cuda.h" | ||
| #include "clang/Driver/Tool.h" | ||
| #include "clang/Driver/ToolChain.h" | ||
| #include <set> | ||
|
|
||
| namespace clang { | ||
| namespace driver { | ||
|
|
||
| struct DetectedMultilibs { | ||
| /// The set of multilibs that the detected installation supports. | ||
| MultilibSet Multilibs; | ||
|
|
||
| /// The primary multilib appropriate for the given flags. | ||
| Multilib SelectedMultilib; | ||
|
|
||
| /// On Biarch systems, this corresponds to the default multilib when | ||
| /// targeting the non-default multilib. Otherwise, it is empty. | ||
| llvm::Optional<Multilib> BiarchSibling; | ||
| }; | ||
|
|
||
| bool findMIPSMultilibs(const Driver &D, const llvm::Triple &TargetTriple, | ||
| StringRef Path, const llvm::opt::ArgList &Args, | ||
| DetectedMultilibs &Result); | ||
|
|
||
| namespace tools { | ||
|
|
||
| /// \brief Base class for all GNU tools that provide the same behavior when | ||
| /// it comes to response files support | ||
| class LLVM_LIBRARY_VISIBILITY GnuTool : public Tool { | ||
| virtual void anchor(); | ||
|
|
||
| public: | ||
| GnuTool(const char *Name, const char *ShortName, const ToolChain &TC) | ||
| : Tool(Name, ShortName, TC, RF_Full, llvm::sys::WEM_CurrentCodePage) {} | ||
| }; | ||
|
|
||
| /// Directly call GNU Binutils' assembler and linker. | ||
| namespace gnutools { | ||
| class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool { | ||
| public: | ||
| Assembler(const ToolChain &TC) : GnuTool("GNU::Assembler", "assembler", TC) {} | ||
|
|
||
| bool hasIntegratedCPP() const override { return false; } | ||
|
|
||
| void ConstructJob(Compilation &C, const JobAction &JA, | ||
| const InputInfo &Output, const InputInfoList &Inputs, | ||
| const llvm::opt::ArgList &TCArgs, | ||
| const char *LinkingOutput) const override; | ||
| }; | ||
|
|
||
| class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { | ||
| public: | ||
| Linker(const ToolChain &TC) : GnuTool("GNU::Linker", "linker", TC) {} | ||
|
|
||
| bool hasIntegratedCPP() const override { return false; } | ||
| bool isLinkJob() const override { return true; } | ||
|
|
||
| void ConstructJob(Compilation &C, const JobAction &JA, | ||
| const InputInfo &Output, const InputInfoList &Inputs, | ||
| const llvm::opt::ArgList &TCArgs, | ||
| const char *LinkingOutput) const override; | ||
| }; | ||
| } // end namespace gnutools | ||
|
|
||
| /// gcc - Generic GCC tool implementations. | ||
| namespace gcc { | ||
| class LLVM_LIBRARY_VISIBILITY Common : public GnuTool { | ||
| public: | ||
| Common(const char *Name, const char *ShortName, const ToolChain &TC) | ||
| : GnuTool(Name, ShortName, TC) {} | ||
|
|
||
| // A gcc tool has an "integrated" assembler that it will call to produce an | ||
| // object. Let it use that assembler so that we don't have to deal with | ||
| // assembly syntax incompatibilities. | ||
| bool hasIntegratedAssembler() const override { return true; } | ||
| void ConstructJob(Compilation &C, const JobAction &JA, | ||
| const InputInfo &Output, const InputInfoList &Inputs, | ||
| const llvm::opt::ArgList &TCArgs, | ||
| const char *LinkingOutput) const override; | ||
|
|
||
| /// RenderExtraToolArgs - Render any arguments necessary to force | ||
| /// the particular tool mode. | ||
| virtual void RenderExtraToolArgs(const JobAction &JA, | ||
| llvm::opt::ArgStringList &CmdArgs) const = 0; | ||
| }; | ||
|
|
||
| class LLVM_LIBRARY_VISIBILITY Preprocessor : public Common { | ||
| public: | ||
| Preprocessor(const ToolChain &TC) | ||
| : Common("gcc::Preprocessor", "gcc preprocessor", TC) {} | ||
|
|
||
| bool hasGoodDiagnostics() const override { return true; } | ||
| bool hasIntegratedCPP() const override { return false; } | ||
|
|
||
| void RenderExtraToolArgs(const JobAction &JA, | ||
| llvm::opt::ArgStringList &CmdArgs) const override; | ||
| }; | ||
|
|
||
| class LLVM_LIBRARY_VISIBILITY Compiler : public Common { | ||
| public: | ||
| Compiler(const ToolChain &TC) : Common("gcc::Compiler", "gcc frontend", TC) {} | ||
|
|
||
| bool hasGoodDiagnostics() const override { return true; } | ||
| bool hasIntegratedCPP() const override { return true; } | ||
|
|
||
| void RenderExtraToolArgs(const JobAction &JA, | ||
| llvm::opt::ArgStringList &CmdArgs) const override; | ||
| }; | ||
|
|
||
| class LLVM_LIBRARY_VISIBILITY Linker : public Common { | ||
| public: | ||
| Linker(const ToolChain &TC) : Common("gcc::Linker", "linker (via gcc)", TC) {} | ||
|
|
||
| bool hasIntegratedCPP() const override { return false; } | ||
| bool isLinkJob() const override { return true; } | ||
|
|
||
| void RenderExtraToolArgs(const JobAction &JA, | ||
| llvm::opt::ArgStringList &CmdArgs) const override; | ||
| }; | ||
| } // end namespace gcc | ||
| } // end namespace tools | ||
|
|
||
| namespace toolchains { | ||
|
|
||
| /// Generic_GCC - A tool chain using the 'gcc' command to perform | ||
| /// all subcommands; this relies on gcc translating the majority of | ||
| /// command line options. | ||
| class LLVM_LIBRARY_VISIBILITY Generic_GCC : public ToolChain { | ||
| public: | ||
| /// \brief Struct to store and manipulate GCC versions. | ||
| /// | ||
| /// We rely on assumptions about the form and structure of GCC version | ||
| /// numbers: they consist of at most three '.'-separated components, and each | ||
| /// component is a non-negative integer except for the last component. For | ||
| /// the last component we are very flexible in order to tolerate release | ||
| /// candidates or 'x' wildcards. | ||
| /// | ||
| /// Note that the ordering established among GCCVersions is based on the | ||
| /// preferred version string to use. For example we prefer versions without | ||
| /// a hard-coded patch number to those with a hard coded patch number. | ||
| /// | ||
| /// Currently this doesn't provide any logic for textual suffixes to patches | ||
| /// in the way that (for example) Debian's version format does. If that ever | ||
| /// becomes necessary, it can be added. | ||
| struct GCCVersion { | ||
| /// \brief The unparsed text of the version. | ||
| std::string Text; | ||
|
|
||
| /// \brief The parsed major, minor, and patch numbers. | ||
| int Major, Minor, Patch; | ||
|
|
||
| /// \brief The text of the parsed major, and major+minor versions. | ||
| std::string MajorStr, MinorStr; | ||
|
|
||
| /// \brief Any textual suffix on the patch number. | ||
| std::string PatchSuffix; | ||
|
|
||
| static GCCVersion Parse(StringRef VersionText); | ||
| bool isOlderThan(int RHSMajor, int RHSMinor, int RHSPatch, | ||
| StringRef RHSPatchSuffix = StringRef()) const; | ||
| bool operator<(const GCCVersion &RHS) const { | ||
| return isOlderThan(RHS.Major, RHS.Minor, RHS.Patch, RHS.PatchSuffix); | ||
| } | ||
| bool operator>(const GCCVersion &RHS) const { return RHS < *this; } | ||
| bool operator<=(const GCCVersion &RHS) const { return !(*this > RHS); } | ||
| bool operator>=(const GCCVersion &RHS) const { return !(*this < RHS); } | ||
| }; | ||
|
|
||
| /// \brief This is a class to find a viable GCC installation for Clang to | ||
| /// use. | ||
| /// | ||
| /// This class tries to find a GCC installation on the system, and report | ||
| /// information about it. It starts from the host information provided to the | ||
| /// Driver, and has logic for fuzzing that where appropriate. | ||
| class GCCInstallationDetector { | ||
| bool IsValid; | ||
| llvm::Triple GCCTriple; | ||
| const Driver &D; | ||
|
|
||
| // FIXME: These might be better as path objects. | ||
| std::string GCCInstallPath; | ||
| std::string GCCParentLibPath; | ||
|
|
||
| /// The primary multilib appropriate for the given flags. | ||
| Multilib SelectedMultilib; | ||
| /// On Biarch systems, this corresponds to the default multilib when | ||
| /// targeting the non-default multilib. Otherwise, it is empty. | ||
| llvm::Optional<Multilib> BiarchSibling; | ||
|
|
||
| GCCVersion Version; | ||
|
|
||
| // We retain the list of install paths that were considered and rejected in | ||
| // order to print out detailed information in verbose mode. | ||
| std::set<std::string> CandidateGCCInstallPaths; | ||
|
|
||
| /// The set of multilibs that the detected installation supports. | ||
| MultilibSet Multilibs; | ||
|
|
||
| public: | ||
| explicit GCCInstallationDetector(const Driver &D) : IsValid(false), D(D) {} | ||
| void init(const llvm::Triple &TargetTriple, const llvm::opt::ArgList &Args, | ||
| ArrayRef<std::string> ExtraTripleAliases = None); | ||
|
|
||
| /// \brief Check whether we detected a valid GCC install. | ||
| bool isValid() const { return IsValid; } | ||
|
|
||
| /// \brief Get the GCC triple for the detected install. | ||
| const llvm::Triple &getTriple() const { return GCCTriple; } | ||
|
|
||
| /// \brief Get the detected GCC installation path. | ||
| StringRef getInstallPath() const { return GCCInstallPath; } | ||
|
|
||
| /// \brief Get the detected GCC parent lib path. | ||
| StringRef getParentLibPath() const { return GCCParentLibPath; } | ||
|
|
||
| /// \brief Get the detected Multilib | ||
| const Multilib &getMultilib() const { return SelectedMultilib; } | ||
|
|
||
| /// \brief Get the whole MultilibSet | ||
| const MultilibSet &getMultilibs() const { return Multilibs; } | ||
|
|
||
| /// Get the biarch sibling multilib (if it exists). | ||
| /// \return true iff such a sibling exists | ||
| bool getBiarchSibling(Multilib &M) const; | ||
|
|
||
| /// \brief Get the detected GCC version string. | ||
| const GCCVersion &getVersion() const { return Version; } | ||
|
|
||
| /// \brief Print information about the detected GCC installation. | ||
| void print(raw_ostream &OS) const; | ||
|
|
||
| private: | ||
| static void | ||
| CollectLibDirsAndTriples(const llvm::Triple &TargetTriple, | ||
| const llvm::Triple &BiarchTriple, | ||
| SmallVectorImpl<StringRef> &LibDirs, | ||
| SmallVectorImpl<StringRef> &TripleAliases, | ||
| SmallVectorImpl<StringRef> &BiarchLibDirs, | ||
| SmallVectorImpl<StringRef> &BiarchTripleAliases); | ||
|
|
||
| bool ScanGCCForMultilibs(const llvm::Triple &TargetTriple, | ||
| const llvm::opt::ArgList &Args, | ||
| StringRef Path, | ||
| bool NeedsBiarchSuffix = false); | ||
|
|
||
| void ScanLibDirForGCCTriple(const llvm::Triple &TargetArch, | ||
| const llvm::opt::ArgList &Args, | ||
| const std::string &LibDir, | ||
| StringRef CandidateTriple, | ||
| bool NeedsBiarchSuffix = false); | ||
|
|
||
| void scanLibDirForGCCTripleSolaris(const llvm::Triple &TargetArch, | ||
| const llvm::opt::ArgList &Args, | ||
| const std::string &LibDir, | ||
| StringRef CandidateTriple, | ||
| bool NeedsBiarchSuffix = false); | ||
|
|
||
| bool ScanGentooGccConfig(const llvm::Triple &TargetTriple, | ||
| const llvm::opt::ArgList &Args, | ||
| StringRef CandidateTriple, | ||
| bool NeedsBiarchSuffix = false); | ||
| }; | ||
|
|
||
| protected: | ||
| GCCInstallationDetector GCCInstallation; | ||
| CudaInstallationDetector CudaInstallation; | ||
|
|
||
| public: | ||
| Generic_GCC(const Driver &D, const llvm::Triple &Triple, | ||
| const llvm::opt::ArgList &Args); | ||
| ~Generic_GCC() override; | ||
|
|
||
| void printVerboseInfo(raw_ostream &OS) const override; | ||
|
|
||
| bool IsUnwindTablesDefault() const override; | ||
| bool isPICDefault() const override; | ||
| bool isPIEDefault() const override; | ||
| bool isPICDefaultForced() const override; | ||
| bool IsIntegratedAssemblerDefault() const override; | ||
| llvm::opt::DerivedArgList * | ||
| TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, | ||
| Action::OffloadKind DeviceOffloadKind) const override; | ||
|
|
||
| protected: | ||
| Tool *getTool(Action::ActionClass AC) const override; | ||
| Tool *buildAssembler() const override; | ||
| Tool *buildLinker() const override; | ||
|
|
||
| /// \name ToolChain Implementation Helper Functions | ||
| /// @{ | ||
|
|
||
| /// \brief Check whether the target triple's architecture is 64-bits. | ||
| bool isTarget64Bit() const { return getTriple().isArch64Bit(); } | ||
|
|
||
| /// \brief Check whether the target triple's architecture is 32-bits. | ||
| bool isTarget32Bit() const { return getTriple().isArch32Bit(); } | ||
|
|
||
| // FIXME: This should be final, but the Solaris tool chain does weird | ||
| // things we can't easily represent. | ||
| void AddClangCXXStdlibIncludeArgs( | ||
| const llvm::opt::ArgList &DriverArgs, | ||
| llvm::opt::ArgStringList &CC1Args) const override; | ||
|
|
||
| virtual std::string findLibCxxIncludePath() const; | ||
| virtual void | ||
| addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, | ||
| llvm::opt::ArgStringList &CC1Args) const; | ||
|
|
||
| bool addLibStdCXXIncludePaths(Twine Base, Twine Suffix, StringRef GCCTriple, | ||
| StringRef GCCMultiarchTriple, | ||
| StringRef TargetMultiarchTriple, | ||
| Twine IncludeSuffix, | ||
| const llvm::opt::ArgList &DriverArgs, | ||
| llvm::opt::ArgStringList &CC1Args) const; | ||
|
|
||
| /// @} | ||
|
|
||
| private: | ||
| mutable std::unique_ptr<tools::gcc::Preprocessor> Preprocess; | ||
| mutable std::unique_ptr<tools::gcc::Compiler> Compile; | ||
| }; | ||
|
|
||
| class LLVM_LIBRARY_VISIBILITY Generic_ELF : public Generic_GCC { | ||
| virtual void anchor(); | ||
|
|
||
| public: | ||
| Generic_ELF(const Driver &D, const llvm::Triple &Triple, | ||
| const llvm::opt::ArgList &Args) | ||
| : Generic_GCC(D, Triple, Args) {} | ||
|
|
||
| void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, | ||
| llvm::opt::ArgStringList &CC1Args) const override; | ||
| }; | ||
|
|
||
| } // end namespace toolchains | ||
| } // end namespace driver | ||
| } // end namespace clang | ||
|
|
||
| #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_GNU_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| //===--- Haiku.cpp - Haiku ToolChain Implementations ------------*- C++ -*-===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "Haiku.h" | ||
| #include "CommonArgs.h" | ||
|
|
||
| using namespace clang::driver; | ||
| using namespace clang::driver::toolchains;; | ||
| using namespace clang; | ||
| using namespace llvm::opt; | ||
|
|
||
| /// Haiku - Haiku tool chain which can call as(1) and ld(1) directly. | ||
|
|
||
| Haiku::Haiku(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) | ||
| : Generic_ELF(D, Triple, Args) { | ||
|
|
||
| } | ||
|
|
||
| std::string Haiku::findLibCxxIncludePath() const { | ||
| return getDriver().SysRoot + "/system/develop/headers/c++/v1"; | ||
| } | ||
|
|
||
| void Haiku::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, | ||
| llvm::opt::ArgStringList &CC1Args) const { | ||
| addLibStdCXXIncludePaths(getDriver().SysRoot, "/system/develop/headers/c++", | ||
| getTriple().str(), "", "", "", DriverArgs, CC1Args); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| //===--- Haiku.h - Haiku ToolChain Implementations --------------*- C++ -*-===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_HAIKU_H | ||
| #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_HAIKU_H | ||
|
|
||
| #include "Gnu.h" | ||
| #include "clang/Driver/Driver.h" | ||
| #include "clang/Driver/ToolChain.h" | ||
|
|
||
| namespace clang { | ||
| namespace driver { | ||
| namespace toolchains { | ||
|
|
||
| class LLVM_LIBRARY_VISIBILITY Haiku : public Generic_ELF { | ||
| public: | ||
| Haiku(const Driver &D, const llvm::Triple &Triple, | ||
| const llvm::opt::ArgList &Args); | ||
|
|
||
| bool isPIEDefault() const override { | ||
| return getTriple().getArch() == llvm::Triple::x86_64; | ||
| } | ||
|
|
||
| std::string findLibCxxIncludePath() const override; | ||
| void addLibStdCxxIncludePaths( | ||
| const llvm::opt::ArgList &DriverArgs, | ||
| llvm::opt::ArgStringList &CC1Args) const override; | ||
| }; | ||
|
|
||
| } // end namespace toolchains | ||
| } // end namespace driver | ||
| } // end namespace clang | ||
|
|
||
| #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_HAIKU_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,99 @@ | ||
| //===--- Hexagon.h - Hexagon ToolChain Implementations ----------*- C++ -*-===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_HEXAGON_H | ||
| #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_HEXAGON_H | ||
|
|
||
| #include "Linux.h" | ||
| #include "clang/Driver/Tool.h" | ||
| #include "clang/Driver/ToolChain.h" | ||
|
|
||
| namespace clang { | ||
| namespace driver { | ||
| namespace tools { | ||
| namespace hexagon { | ||
| // For Hexagon, we do not need to instantiate tools for PreProcess, PreCompile | ||
| // and Compile. | ||
| // We simply use "clang -cc1" for those actions. | ||
| class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool { | ||
| public: | ||
| Assembler(const ToolChain &TC) | ||
| : GnuTool("hexagon::Assembler", "hexagon-as", TC) {} | ||
|
|
||
| bool hasIntegratedCPP() const override { return false; } | ||
|
|
||
| void RenderExtraToolArgs(const JobAction &JA, | ||
| llvm::opt::ArgStringList &CmdArgs) const; | ||
| void ConstructJob(Compilation &C, const JobAction &JA, | ||
| const InputInfo &Output, const InputInfoList &Inputs, | ||
| const llvm::opt::ArgList &TCArgs, | ||
| const char *LinkingOutput) const override; | ||
| }; | ||
|
|
||
| class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { | ||
| public: | ||
| Linker(const ToolChain &TC) : GnuTool("hexagon::Linker", "hexagon-ld", TC) {} | ||
|
|
||
| bool hasIntegratedCPP() const override { return false; } | ||
| bool isLinkJob() const override { return true; } | ||
|
|
||
| virtual void RenderExtraToolArgs(const JobAction &JA, | ||
| llvm::opt::ArgStringList &CmdArgs) const; | ||
| void ConstructJob(Compilation &C, const JobAction &JA, | ||
| const InputInfo &Output, const InputInfoList &Inputs, | ||
| const llvm::opt::ArgList &TCArgs, | ||
| const char *LinkingOutput) const override; | ||
| }; | ||
| } // end namespace hexagon. | ||
| } // end namespace tools | ||
|
|
||
| namespace toolchains { | ||
|
|
||
| class LLVM_LIBRARY_VISIBILITY HexagonToolChain : public Linux { | ||
| protected: | ||
| GCCVersion GCCLibAndIncVersion; | ||
| Tool *buildAssembler() const override; | ||
| Tool *buildLinker() const override; | ||
|
|
||
| public: | ||
| HexagonToolChain(const Driver &D, const llvm::Triple &Triple, | ||
| const llvm::opt::ArgList &Args); | ||
| ~HexagonToolChain() override; | ||
|
|
||
| void | ||
| AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, | ||
| llvm::opt::ArgStringList &CC1Args) const override; | ||
| void addLibStdCxxIncludePaths( | ||
| const llvm::opt::ArgList &DriverArgs, | ||
| llvm::opt::ArgStringList &CC1Args) const override; | ||
| CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override; | ||
|
|
||
| StringRef GetGCCLibAndIncVersion() const { return GCCLibAndIncVersion.Text; } | ||
| bool IsIntegratedAssemblerDefault() const override { | ||
| return true; | ||
| } | ||
|
|
||
| std::string getHexagonTargetDir( | ||
| const std::string &InstalledDir, | ||
| const SmallVectorImpl<std::string> &PrefixDirs) const; | ||
| void getHexagonLibraryPaths(const llvm::opt::ArgList &Args, | ||
| ToolChain::path_list &LibPaths) const; | ||
|
|
||
| static const StringRef GetDefaultCPU(); | ||
| static const StringRef GetTargetCPUVersion(const llvm::opt::ArgList &Args); | ||
|
|
||
| static Optional<unsigned> getSmallDataThreshold( | ||
| const llvm::opt::ArgList &Args); | ||
| }; | ||
|
|
||
| } // end namespace toolchains | ||
| } // end namespace driver | ||
| } // end namespace clang | ||
|
|
||
| #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_HEXAGON_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| //===--- Lanai.h - Lanai ToolChain Implementations --------------*- C++ -*-===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_LANAI_H | ||
| #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_LANAI_H | ||
|
|
||
| #include "Gnu.h" | ||
| #include "clang/Driver/ToolChain.h" | ||
|
|
||
| namespace clang { | ||
| namespace driver { | ||
| namespace toolchains { | ||
|
|
||
| class LLVM_LIBRARY_VISIBILITY LanaiToolChain : public Generic_ELF { | ||
| public: | ||
| LanaiToolChain(const Driver &D, const llvm::Triple &Triple, | ||
| const llvm::opt::ArgList &Args) | ||
| : Generic_ELF(D, Triple, Args) {} | ||
|
|
||
| // No support for finding a C++ standard library yet. | ||
| std::string findLibCxxIncludePath() const override { return ""; } | ||
| void addLibStdCxxIncludePaths( | ||
| const llvm::opt::ArgList &DriverArgs, | ||
| llvm::opt::ArgStringList &CC1Args) const override {} | ||
|
|
||
| bool IsIntegratedAssemblerDefault() const override { return true; } | ||
| }; | ||
|
|
||
| } // end namespace toolchains | ||
| } // end namespace driver | ||
| } // end namespace clang | ||
|
|
||
| #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_LANAI_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| //===--- Linux.h - Linux ToolChain Implementations --------------*- C++ -*-===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_LINUX_H | ||
| #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_LINUX_H | ||
|
|
||
| #include "Gnu.h" | ||
| #include "clang/Driver/ToolChain.h" | ||
|
|
||
| namespace clang { | ||
| namespace driver { | ||
| namespace toolchains { | ||
|
|
||
| class LLVM_LIBRARY_VISIBILITY Linux : public Generic_ELF { | ||
| public: | ||
| Linux(const Driver &D, const llvm::Triple &Triple, | ||
| const llvm::opt::ArgList &Args); | ||
|
|
||
| bool HasNativeLLVMSupport() const override; | ||
|
|
||
| void | ||
| AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, | ||
| llvm::opt::ArgStringList &CC1Args) const override; | ||
| std::string findLibCxxIncludePath() const override; | ||
| void addLibStdCxxIncludePaths( | ||
| const llvm::opt::ArgList &DriverArgs, | ||
| llvm::opt::ArgStringList &CC1Args) const override; | ||
| void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, | ||
| llvm::opt::ArgStringList &CC1Args) const override; | ||
| void AddIAMCUIncludeArgs(const llvm::opt::ArgList &DriverArgs, | ||
| llvm::opt::ArgStringList &CC1Args) const override; | ||
| bool isPIEDefault() const override; | ||
| SanitizerMask getSupportedSanitizers() const override; | ||
| void addProfileRTLibs(const llvm::opt::ArgList &Args, | ||
| llvm::opt::ArgStringList &CmdArgs) const override; | ||
| virtual std::string computeSysRoot() const; | ||
|
|
||
| virtual std::string getDynamicLinker(const llvm::opt::ArgList &Args) const; | ||
|
|
||
| std::vector<std::string> ExtraOpts; | ||
|
|
||
| protected: | ||
| Tool *buildAssembler() const override; | ||
| Tool *buildLinker() const override; | ||
| }; | ||
|
|
||
| } // end namespace toolchains | ||
| } // end namespace driver | ||
| } // end namespace clang | ||
|
|
||
| #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_LINUX_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,133 @@ | ||
| //===--- MSVC.h - MSVC ToolChain Implementations ----------------*- C++ -*-===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MSVC_H | ||
| #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MSVC_H | ||
|
|
||
| #include "Cuda.h" | ||
| #include "clang/Driver/Compilation.h" | ||
| #include "clang/Driver/Tool.h" | ||
| #include "clang/Driver/ToolChain.h" | ||
|
|
||
| namespace clang { | ||
| namespace driver { | ||
| namespace tools { | ||
|
|
||
| /// Visual studio tools. | ||
| namespace visualstudio { | ||
| class LLVM_LIBRARY_VISIBILITY Linker : public Tool { | ||
| public: | ||
| Linker(const ToolChain &TC) | ||
| : Tool("visualstudio::Linker", "linker", TC, RF_Full, | ||
| llvm::sys::WEM_UTF16) {} | ||
|
|
||
| bool hasIntegratedCPP() const override { return false; } | ||
| bool isLinkJob() const override { return true; } | ||
|
|
||
| void ConstructJob(Compilation &C, const JobAction &JA, | ||
| const InputInfo &Output, const InputInfoList &Inputs, | ||
| const llvm::opt::ArgList &TCArgs, | ||
| const char *LinkingOutput) const override; | ||
| }; | ||
|
|
||
| class LLVM_LIBRARY_VISIBILITY Compiler : public Tool { | ||
| public: | ||
| Compiler(const ToolChain &TC) | ||
| : Tool("visualstudio::Compiler", "compiler", TC, RF_Full, | ||
| llvm::sys::WEM_UTF16) {} | ||
|
|
||
| bool hasIntegratedAssembler() const override { return true; } | ||
| bool hasIntegratedCPP() const override { return true; } | ||
| bool isLinkJob() const override { return false; } | ||
|
|
||
| void ConstructJob(Compilation &C, const JobAction &JA, | ||
| const InputInfo &Output, const InputInfoList &Inputs, | ||
| const llvm::opt::ArgList &TCArgs, | ||
| const char *LinkingOutput) const override; | ||
|
|
||
| std::unique_ptr<Command> GetCommand(Compilation &C, const JobAction &JA, | ||
| const InputInfo &Output, | ||
| const InputInfoList &Inputs, | ||
| const llvm::opt::ArgList &TCArgs, | ||
| const char *LinkingOutput) const; | ||
| }; | ||
| } // end namespace visualstudio | ||
|
|
||
| } // end namespace tools | ||
|
|
||
| namespace toolchains { | ||
|
|
||
| class LLVM_LIBRARY_VISIBILITY MSVCToolChain : public ToolChain { | ||
| public: | ||
| MSVCToolChain(const Driver &D, const llvm::Triple &Triple, | ||
| const llvm::opt::ArgList &Args); | ||
|
|
||
| llvm::opt::DerivedArgList * | ||
| TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, | ||
| Action::OffloadKind DeviceOffloadKind) const override; | ||
|
|
||
| bool IsIntegratedAssemblerDefault() const override; | ||
| bool IsUnwindTablesDefault() const override; | ||
| bool isPICDefault() const override; | ||
| bool isPIEDefault() const override; | ||
| bool isPICDefaultForced() const override; | ||
|
|
||
| void | ||
| AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, | ||
| llvm::opt::ArgStringList &CC1Args) const override; | ||
| void AddClangCXXStdlibIncludeArgs( | ||
| const llvm::opt::ArgList &DriverArgs, | ||
| llvm::opt::ArgStringList &CC1Args) const override; | ||
|
|
||
| void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, | ||
| llvm::opt::ArgStringList &CC1Args) const override; | ||
|
|
||
| bool getWindowsSDKDir(std::string &path, int &major, | ||
| std::string &windowsSDKIncludeVersion, | ||
| std::string &windowsSDKLibVersion) const; | ||
| bool getWindowsSDKLibraryPath(std::string &path) const; | ||
| /// \brief Check if Universal CRT should be used if available | ||
| bool useUniversalCRT(std::string &visualStudioDir) const; | ||
| bool getUniversalCRTSdkDir(std::string &path, std::string &ucrtVersion) const; | ||
| bool getUniversalCRTLibraryPath(std::string &path) const; | ||
| bool getVisualStudioInstallDir(std::string &path) const; | ||
| bool getVisualStudioBinariesFolder(const char *clangProgramPath, | ||
| std::string &path) const; | ||
| VersionTuple | ||
| computeMSVCVersion(const Driver *D, | ||
| const llvm::opt::ArgList &Args) const override; | ||
|
|
||
| std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args, | ||
| types::ID InputType) const override; | ||
| SanitizerMask getSupportedSanitizers() const override; | ||
|
|
||
| void printVerboseInfo(raw_ostream &OS) const override; | ||
|
|
||
| protected: | ||
| void AddSystemIncludeWithSubfolder(const llvm::opt::ArgList &DriverArgs, | ||
| llvm::opt::ArgStringList &CC1Args, | ||
| const std::string &folder, | ||
| const Twine &subfolder1, | ||
| const Twine &subfolder2 = "", | ||
| const Twine &subfolder3 = "") const; | ||
|
|
||
| Tool *buildLinker() const override; | ||
| Tool *buildAssembler() const override; | ||
| private: | ||
| VersionTuple getMSVCVersionFromTriple() const; | ||
| VersionTuple getMSVCVersionFromExe() const; | ||
|
|
||
| CudaInstallationDetector CudaInstallation; | ||
| }; | ||
|
|
||
| } // end namespace toolchains | ||
| } // end namespace driver | ||
| } // end namespace clang | ||
|
|
||
| #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MSVC_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,102 @@ | ||
| //===--- MinGW.h - MinGW ToolChain Implementations --------------*- C++ -*-===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MINGW_H | ||
| #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MINGW_H | ||
|
|
||
| #include "Cuda.h" | ||
| #include "Gnu.h" | ||
| #include "clang/Driver/Tool.h" | ||
| #include "clang/Driver/ToolChain.h" | ||
|
|
||
| namespace clang { | ||
| namespace driver { | ||
| namespace tools { | ||
|
|
||
| /// MinGW -- Directly call GNU Binutils assembler and linker | ||
| namespace MinGW { | ||
| class LLVM_LIBRARY_VISIBILITY Assembler : public Tool { | ||
| public: | ||
| Assembler(const ToolChain &TC) : Tool("MinGW::Assemble", "assembler", TC) {} | ||
|
|
||
| bool hasIntegratedCPP() const override { return false; } | ||
|
|
||
| void ConstructJob(Compilation &C, const JobAction &JA, | ||
| const InputInfo &Output, const InputInfoList &Inputs, | ||
| const llvm::opt::ArgList &TCArgs, | ||
| const char *LinkingOutput) const override; | ||
| }; | ||
|
|
||
| class LLVM_LIBRARY_VISIBILITY Linker : public Tool { | ||
| public: | ||
| Linker(const ToolChain &TC) : Tool("MinGW::Linker", "linker", TC) {} | ||
|
|
||
| bool hasIntegratedCPP() const override { return false; } | ||
| bool isLinkJob() const override { return true; } | ||
|
|
||
| void ConstructJob(Compilation &C, const JobAction &JA, | ||
| const InputInfo &Output, const InputInfoList &Inputs, | ||
| const llvm::opt::ArgList &TCArgs, | ||
| const char *LinkingOutput) const override; | ||
|
|
||
| private: | ||
| void AddLibGCC(const llvm::opt::ArgList &Args, | ||
| llvm::opt::ArgStringList &CmdArgs) const; | ||
| }; | ||
| } // end namespace MinGW | ||
| } // end namespace tools | ||
|
|
||
| namespace toolchains { | ||
|
|
||
| class LLVM_LIBRARY_VISIBILITY MinGW : public ToolChain { | ||
| public: | ||
| MinGW(const Driver &D, const llvm::Triple &Triple, | ||
| const llvm::opt::ArgList &Args); | ||
|
|
||
| bool IsIntegratedAssemblerDefault() const override; | ||
| bool IsUnwindTablesDefault() const override; | ||
| bool isPICDefault() const override; | ||
| bool isPIEDefault() const override; | ||
| bool isPICDefaultForced() const override; | ||
| bool UseSEHExceptions() const; | ||
|
|
||
| void | ||
| AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, | ||
| llvm::opt::ArgStringList &CC1Args) const override; | ||
| void AddClangCXXStdlibIncludeArgs( | ||
| const llvm::opt::ArgList &DriverArgs, | ||
| llvm::opt::ArgStringList &CC1Args) const override; | ||
|
|
||
| void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, | ||
| llvm::opt::ArgStringList &CC1Args) const override; | ||
|
|
||
| void printVerboseInfo(raw_ostream &OS) const override; | ||
|
|
||
| protected: | ||
| Tool *getTool(Action::ActionClass AC) const override; | ||
| Tool *buildLinker() const override; | ||
| Tool *buildAssembler() const override; | ||
|
|
||
| private: | ||
| CudaInstallationDetector CudaInstallation; | ||
|
|
||
| std::string Base; | ||
| std::string GccLibDir; | ||
| std::string Ver; | ||
| std::string Arch; | ||
| mutable std::unique_ptr<tools::gcc::Preprocessor> Preprocessor; | ||
| mutable std::unique_ptr<tools::gcc::Compiler> Compiler; | ||
| void findGccLibDir(); | ||
| }; | ||
|
|
||
| } // end namespace toolchains | ||
| } // end namespace driver | ||
| } // end namespace clang | ||
|
|
||
| #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MINGW_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| //===--- Minix.cpp - Minix ToolChain Implementations ------------*- C++ -*-===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "Minix.h" | ||
| #include "InputInfo.h" | ||
| #include "CommonArgs.h" | ||
| #include "clang/Basic/VirtualFileSystem.h" | ||
| #include "clang/Driver/Compilation.h" | ||
| #include "clang/Driver/Driver.h" | ||
| #include "clang/Driver/Options.h" | ||
| #include "llvm/Option/ArgList.h" | ||
|
|
||
| using namespace clang::driver; | ||
| using namespace clang; | ||
| using namespace llvm::opt; | ||
|
|
||
| void tools::minix::Assembler::ConstructJob(Compilation &C, const JobAction &JA, | ||
| const InputInfo &Output, | ||
| const InputInfoList &Inputs, | ||
| const ArgList &Args, | ||
| const char *LinkingOutput) const { | ||
| claimNoWarnArgs(Args); | ||
| ArgStringList CmdArgs; | ||
|
|
||
| Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); | ||
|
|
||
| CmdArgs.push_back("-o"); | ||
| CmdArgs.push_back(Output.getFilename()); | ||
|
|
||
| for (const auto &II : Inputs) | ||
| CmdArgs.push_back(II.getFilename()); | ||
|
|
||
| const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); | ||
| C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); | ||
| } | ||
|
|
||
| void tools::minix::Linker::ConstructJob(Compilation &C, const JobAction &JA, | ||
| const InputInfo &Output, | ||
| const InputInfoList &Inputs, | ||
| const ArgList &Args, | ||
| const char *LinkingOutput) const { | ||
| const Driver &D = getToolChain().getDriver(); | ||
| ArgStringList CmdArgs; | ||
|
|
||
| if (Output.isFilename()) { | ||
| CmdArgs.push_back("-o"); | ||
| CmdArgs.push_back(Output.getFilename()); | ||
| } else { | ||
| assert(Output.isNothing() && "Invalid output."); | ||
| } | ||
|
|
||
| if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { | ||
| CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crt1.o"))); | ||
| CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crti.o"))); | ||
| CmdArgs.push_back( | ||
| Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o"))); | ||
| CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o"))); | ||
| } | ||
|
|
||
| Args.AddAllArgs(CmdArgs, | ||
| {options::OPT_L, options::OPT_T_Group, options::OPT_e}); | ||
|
|
||
| AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA); | ||
|
|
||
| getToolChain().addProfileRTLibs(Args, CmdArgs); | ||
|
|
||
| if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { | ||
| if (D.CCCIsCXX()) { | ||
| getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs); | ||
| CmdArgs.push_back("-lm"); | ||
| } | ||
| } | ||
|
|
||
| if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { | ||
| if (Args.hasArg(options::OPT_pthread)) | ||
| CmdArgs.push_back("-lpthread"); | ||
| CmdArgs.push_back("-lc"); | ||
| CmdArgs.push_back("-lCompilerRT-Generic"); | ||
| CmdArgs.push_back("-L/usr/pkg/compiler-rt/lib"); | ||
| CmdArgs.push_back( | ||
| Args.MakeArgString(getToolChain().GetFilePath("crtend.o"))); | ||
| } | ||
|
|
||
| const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath()); | ||
| C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); | ||
| } | ||
|
|
||
| /// Minix - Minix tool chain which can call as(1) and ld(1) directly. | ||
|
|
||
| toolchains::Minix::Minix(const Driver &D, const llvm::Triple &Triple, | ||
| const ArgList &Args) | ||
| : Generic_ELF(D, Triple, Args) { | ||
| getFilePaths().push_back(getDriver().Dir + "/../lib"); | ||
| getFilePaths().push_back("/usr/lib"); | ||
| } | ||
|
|
||
| Tool *toolchains::Minix::buildAssembler() const { | ||
| return new tools::minix::Assembler(*this); | ||
| } | ||
|
|
||
| Tool *toolchains::Minix::buildLinker() const { | ||
| return new tools::minix::Linker(*this); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| //===--- Minix.h - Minix ToolChain Implementations --------------*- C++ -*-===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MINIX_H | ||
| #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MINIX_H | ||
|
|
||
| #include "Gnu.h" | ||
| #include "clang/Driver/Tool.h" | ||
| #include "clang/Driver/ToolChain.h" | ||
|
|
||
| namespace clang { | ||
| namespace driver { | ||
| namespace tools { | ||
| /// minix -- Directly call GNU Binutils assembler and linker | ||
| namespace minix { | ||
| class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool { | ||
| public: | ||
| Assembler(const ToolChain &TC) | ||
| : GnuTool("minix::Assembler", "assembler", TC) {} | ||
|
|
||
| bool hasIntegratedCPP() const override { return false; } | ||
|
|
||
| void ConstructJob(Compilation &C, const JobAction &JA, | ||
| const InputInfo &Output, const InputInfoList &Inputs, | ||
| const llvm::opt::ArgList &TCArgs, | ||
| const char *LinkingOutput) const override; | ||
| }; | ||
|
|
||
| class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { | ||
| public: | ||
| Linker(const ToolChain &TC) : GnuTool("minix::Linker", "linker", TC) {} | ||
|
|
||
| bool hasIntegratedCPP() const override { return false; } | ||
| bool isLinkJob() const override { return true; } | ||
|
|
||
| void ConstructJob(Compilation &C, const JobAction &JA, | ||
| const InputInfo &Output, const InputInfoList &Inputs, | ||
| const llvm::opt::ArgList &TCArgs, | ||
| const char *LinkingOutput) const override; | ||
| }; | ||
| } // end namespace minix | ||
| } // end namespace tools | ||
|
|
||
| namespace toolchains { | ||
|
|
||
| class LLVM_LIBRARY_VISIBILITY Minix : public Generic_ELF { | ||
| public: | ||
| Minix(const Driver &D, const llvm::Triple &Triple, | ||
| const llvm::opt::ArgList &Args); | ||
|
|
||
| protected: | ||
| Tool *buildAssembler() const override; | ||
| Tool *buildLinker() const override; | ||
| }; | ||
|
|
||
| } // end namespace toolchains | ||
| } // end namespace driver | ||
| } // end namespace clang | ||
|
|
||
| #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MINIX_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,128 @@ | ||
| //===--- Mips.cpp - Mips ToolChain Implementations --------------*- C++ -*-===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "Mips.h" | ||
| #include "Arch/Mips.h" | ||
| #include "CommonArgs.h" | ||
| #include "clang/Config/config.h" | ||
| #include "clang/Driver/Driver.h" | ||
| #include "clang/Driver/DriverDiagnostic.h" | ||
| #include "clang/Driver/Options.h" | ||
| #include "llvm/Option/ArgList.h" | ||
| #include "llvm/Support/FileSystem.h" | ||
| #include "llvm/Support/Path.h" | ||
|
|
||
| using namespace clang::driver; | ||
| using namespace clang::driver::toolchains; | ||
| using namespace clang; | ||
| using namespace llvm::opt; | ||
|
|
||
| /// Mips Toolchain | ||
| MipsLLVMToolChain::MipsLLVMToolChain(const Driver &D, | ||
| const llvm::Triple &Triple, | ||
| const ArgList &Args) | ||
| : Linux(D, Triple, Args) { | ||
| // Select the correct multilib according to the given arguments. | ||
| DetectedMultilibs Result; | ||
| findMIPSMultilibs(D, Triple, "", Args, Result); | ||
| Multilibs = Result.Multilibs; | ||
| SelectedMultilib = Result.SelectedMultilib; | ||
|
|
||
| // Find out the library suffix based on the ABI. | ||
| LibSuffix = tools::mips::getMipsABILibSuffix(Args, Triple); | ||
| getFilePaths().clear(); | ||
| getFilePaths().push_back(computeSysRoot() + "/usr/lib" + LibSuffix); | ||
| } | ||
|
|
||
| void MipsLLVMToolChain::AddClangSystemIncludeArgs( | ||
| const ArgList &DriverArgs, ArgStringList &CC1Args) const { | ||
| if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc)) | ||
| return; | ||
|
|
||
| const Driver &D = getDriver(); | ||
|
|
||
| if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { | ||
| SmallString<128> P(D.ResourceDir); | ||
| llvm::sys::path::append(P, "include"); | ||
| addSystemInclude(DriverArgs, CC1Args, P); | ||
| } | ||
|
|
||
| if (DriverArgs.hasArg(options::OPT_nostdlibinc)) | ||
| return; | ||
|
|
||
| const auto &Callback = Multilibs.includeDirsCallback(); | ||
| if (Callback) { | ||
| for (const auto &Path : Callback(SelectedMultilib)) | ||
| addExternCSystemIncludeIfExists(DriverArgs, CC1Args, | ||
| D.getInstalledDir() + Path); | ||
| } | ||
| } | ||
|
|
||
| Tool *MipsLLVMToolChain::buildLinker() const { | ||
| return new tools::gnutools::Linker(*this); | ||
| } | ||
|
|
||
| std::string MipsLLVMToolChain::computeSysRoot() const { | ||
| if (!getDriver().SysRoot.empty()) | ||
| return getDriver().SysRoot + SelectedMultilib.osSuffix(); | ||
|
|
||
| const std::string InstalledDir(getDriver().getInstalledDir()); | ||
| std::string SysRootPath = | ||
| InstalledDir + "/../sysroot" + SelectedMultilib.osSuffix(); | ||
| if (llvm::sys::fs::exists(SysRootPath)) | ||
| return SysRootPath; | ||
|
|
||
| return std::string(); | ||
| } | ||
|
|
||
| ToolChain::CXXStdlibType | ||
| MipsLLVMToolChain::GetCXXStdlibType(const ArgList &Args) const { | ||
| Arg *A = Args.getLastArg(options::OPT_stdlib_EQ); | ||
| if (A) { | ||
| StringRef Value = A->getValue(); | ||
| if (Value != "libc++") | ||
| getDriver().Diag(clang::diag::err_drv_invalid_stdlib_name) | ||
| << A->getAsString(Args); | ||
| } | ||
|
|
||
| return ToolChain::CST_Libcxx; | ||
| } | ||
|
|
||
| std::string MipsLLVMToolChain::findLibCxxIncludePath() const { | ||
| if (const auto &Callback = Multilibs.includeDirsCallback()) { | ||
| for (std::string Path : Callback(SelectedMultilib)) { | ||
| Path = getDriver().getInstalledDir() + Path + "/c++/v1"; | ||
| if (llvm::sys::fs::exists(Path)) { | ||
| return Path; | ||
| } | ||
| } | ||
| } | ||
| return ""; | ||
| } | ||
|
|
||
| void MipsLLVMToolChain::AddCXXStdlibLibArgs(const ArgList &Args, | ||
| ArgStringList &CmdArgs) const { | ||
| assert((GetCXXStdlibType(Args) == ToolChain::CST_Libcxx) && | ||
| "Only -lc++ (aka libxx) is suported in this toolchain."); | ||
|
|
||
| CmdArgs.push_back("-lc++"); | ||
| CmdArgs.push_back("-lc++abi"); | ||
| CmdArgs.push_back("-lunwind"); | ||
| } | ||
|
|
||
| std::string MipsLLVMToolChain::getCompilerRT(const ArgList &Args, | ||
| StringRef Component, | ||
| bool Shared) const { | ||
| SmallString<128> Path(getDriver().ResourceDir); | ||
| llvm::sys::path::append(Path, SelectedMultilib.osSuffix(), "lib" + LibSuffix, | ||
| getOS()); | ||
| llvm::sys::path::append(Path, Twine("libclang_rt." + Component + "-" + | ||
| "mips" + (Shared ? ".so" : ".a"))); | ||
| return Path.str(); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| //===--- Mips.h - Mips ToolChain Implementations ----------------*- C++ -*-===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MIPS_H | ||
| #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MIPS_H | ||
|
|
||
| #include "Linux.h" | ||
| #include "clang/Driver/ToolChain.h" | ||
|
|
||
| namespace clang { | ||
| namespace driver { | ||
| namespace toolchains { | ||
|
|
||
| class LLVM_LIBRARY_VISIBILITY MipsLLVMToolChain : public Linux { | ||
| protected: | ||
| Tool *buildLinker() const override; | ||
|
|
||
| public: | ||
| MipsLLVMToolChain(const Driver &D, const llvm::Triple &Triple, | ||
| const llvm::opt::ArgList &Args); | ||
|
|
||
| void | ||
| AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, | ||
| llvm::opt::ArgStringList &CC1Args) const override; | ||
|
|
||
| CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override; | ||
|
|
||
| std::string findLibCxxIncludePath() const override; | ||
|
|
||
| void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, | ||
| llvm::opt::ArgStringList &CmdArgs) const override; | ||
|
|
||
| std::string getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component, | ||
| bool Shared = false) const override; | ||
|
|
||
| std::string computeSysRoot() const override; | ||
|
|
||
| RuntimeLibType GetDefaultRuntimeLibType() const override { | ||
| return GCCInstallation.isValid() ? RuntimeLibType::RLT_Libgcc | ||
| : RuntimeLibType::RLT_CompilerRT; | ||
| } | ||
|
|
||
| const char *getDefaultLinker() const override { | ||
| return "lld"; | ||
| } | ||
|
|
||
| private: | ||
| Multilib SelectedMultilib; | ||
| std::string LibSuffix; | ||
| }; | ||
|
|
||
| } // end namespace toolchains | ||
| } // end namespace driver | ||
| } // end namespace clang | ||
|
|
||
| #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MIPS_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,286 @@ | ||
| //===--- Myriad.cpp - Myriad ToolChain Implementations ----------*- C++ -*-===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "Myriad.h" | ||
| #include "CommonArgs.h" | ||
| #include "clang/Driver/Compilation.h" | ||
| #include "clang/Driver/Driver.h" | ||
| #include "clang/Driver/DriverDiagnostic.h" | ||
| #include "clang/Driver/Options.h" | ||
| #include "llvm/Option/ArgList.h" | ||
|
|
||
| using namespace clang::driver; | ||
| using namespace clang::driver::toolchains; | ||
| using namespace clang; | ||
| using namespace llvm::opt; | ||
|
|
||
| using tools::addPathIfExists; | ||
|
|
||
| void tools::SHAVE::Compiler::ConstructJob(Compilation &C, const JobAction &JA, | ||
| const InputInfo &Output, | ||
| const InputInfoList &Inputs, | ||
| const ArgList &Args, | ||
| const char *LinkingOutput) const { | ||
| ArgStringList CmdArgs; | ||
| assert(Inputs.size() == 1); | ||
| const InputInfo &II = Inputs[0]; | ||
| assert(II.getType() == types::TY_C || II.getType() == types::TY_CXX || | ||
| II.getType() == types::TY_PP_CXX); | ||
|
|
||
| if (JA.getKind() == Action::PreprocessJobClass) { | ||
| Args.ClaimAllArgs(); | ||
| CmdArgs.push_back("-E"); | ||
| } else { | ||
| assert(Output.getType() == types::TY_PP_Asm); // Require preprocessed asm. | ||
| CmdArgs.push_back("-S"); | ||
| CmdArgs.push_back("-fno-exceptions"); // Always do this even if unspecified. | ||
| } | ||
| CmdArgs.push_back("-DMYRIAD2"); | ||
|
|
||
| // Append all -I, -iquote, -isystem paths, defines/undefines, | ||
| // 'f' flags, optimize flags, and warning options. | ||
| // These are spelled the same way in clang and moviCompile. | ||
| Args.AddAllArgsExcept( | ||
| CmdArgs, | ||
| {options::OPT_I_Group, options::OPT_clang_i_Group, options::OPT_std_EQ, | ||
| options::OPT_D, options::OPT_U, options::OPT_f_Group, | ||
| options::OPT_f_clang_Group, options::OPT_g_Group, options::OPT_M_Group, | ||
| options::OPT_O_Group, options::OPT_W_Group, options::OPT_mcpu_EQ}, | ||
| {options::OPT_fno_split_dwarf_inlining}); | ||
| Args.hasArg(options::OPT_fno_split_dwarf_inlining); // Claim it if present. | ||
|
|
||
| // If we're producing a dependency file, and assembly is the final action, | ||
| // then the name of the target in the dependency file should be the '.o' | ||
| // file, not the '.s' file produced by this step. For example, instead of | ||
| // /tmp/mumble.s: mumble.c .../someheader.h | ||
| // the filename on the lefthand side should be "mumble.o" | ||
| if (Args.getLastArg(options::OPT_MF) && !Args.getLastArg(options::OPT_MT) && | ||
| C.getActions().size() == 1 && | ||
| C.getActions()[0]->getKind() == Action::AssembleJobClass) { | ||
| Arg *A = Args.getLastArg(options::OPT_o); | ||
| if (A) { | ||
| CmdArgs.push_back("-MT"); | ||
| CmdArgs.push_back(Args.MakeArgString(A->getValue())); | ||
| } | ||
| } | ||
|
|
||
| CmdArgs.push_back(II.getFilename()); | ||
| CmdArgs.push_back("-o"); | ||
| CmdArgs.push_back(Output.getFilename()); | ||
|
|
||
| std::string Exec = | ||
| Args.MakeArgString(getToolChain().GetProgramPath("moviCompile")); | ||
| C.addCommand(llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Exec), | ||
| CmdArgs, Inputs)); | ||
| } | ||
|
|
||
| void tools::SHAVE::Assembler::ConstructJob(Compilation &C, const JobAction &JA, | ||
| const InputInfo &Output, | ||
| const InputInfoList &Inputs, | ||
| const ArgList &Args, | ||
| const char *LinkingOutput) const { | ||
| ArgStringList CmdArgs; | ||
|
|
||
| assert(Inputs.size() == 1); | ||
| const InputInfo &II = Inputs[0]; | ||
| assert(II.getType() == types::TY_PP_Asm); // Require preprocessed asm input. | ||
| assert(Output.getType() == types::TY_Object); | ||
|
|
||
| CmdArgs.push_back("-no6thSlotCompression"); | ||
| const Arg *CPUArg = Args.getLastArg(options::OPT_mcpu_EQ); | ||
| if (CPUArg) | ||
| CmdArgs.push_back( | ||
| Args.MakeArgString("-cv:" + StringRef(CPUArg->getValue()))); | ||
| CmdArgs.push_back("-noSPrefixing"); | ||
| CmdArgs.push_back("-a"); // Mystery option. | ||
| Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); | ||
| for (const Arg *A : Args.filtered(options::OPT_I, options::OPT_isystem)) { | ||
| A->claim(); | ||
| CmdArgs.push_back( | ||
| Args.MakeArgString(std::string("-i:") + A->getValue(0))); | ||
| } | ||
| CmdArgs.push_back("-elf"); // Output format. | ||
| CmdArgs.push_back(II.getFilename()); | ||
| CmdArgs.push_back( | ||
| Args.MakeArgString(std::string("-o:") + Output.getFilename())); | ||
|
|
||
| std::string Exec = | ||
| Args.MakeArgString(getToolChain().GetProgramPath("moviAsm")); | ||
| C.addCommand(llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Exec), | ||
| CmdArgs, Inputs)); | ||
| } | ||
|
|
||
| void tools::Myriad::Linker::ConstructJob(Compilation &C, const JobAction &JA, | ||
| const InputInfo &Output, | ||
| const InputInfoList &Inputs, | ||
| const ArgList &Args, | ||
| const char *LinkingOutput) const { | ||
| const auto &TC = | ||
| static_cast<const toolchains::MyriadToolChain &>(getToolChain()); | ||
| const llvm::Triple &T = TC.getTriple(); | ||
| ArgStringList CmdArgs; | ||
| bool UseStartfiles = | ||
| !Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles); | ||
| bool UseDefaultLibs = | ||
| !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs); | ||
| // Silence warning if the args contain both -nostdlib and -stdlib=. | ||
| Args.getLastArg(options::OPT_stdlib_EQ); | ||
|
|
||
| if (T.getArch() == llvm::Triple::sparc) | ||
| CmdArgs.push_back("-EB"); | ||
| else // SHAVE assumes little-endian, and sparcel is expressly so. | ||
| CmdArgs.push_back("-EL"); | ||
|
|
||
| // The remaining logic is mostly like gnutools::Linker::ConstructJob, | ||
| // but we never pass through a --sysroot option and various other bits. | ||
| // For example, there are no sanitizers (yet) nor gold linker. | ||
|
|
||
| // Eat some arguments that may be present but have no effect. | ||
| Args.ClaimAllArgs(options::OPT_g_Group); | ||
| Args.ClaimAllArgs(options::OPT_w); | ||
| Args.ClaimAllArgs(options::OPT_static_libgcc); | ||
|
|
||
| if (Args.hasArg(options::OPT_s)) // Pass the 'strip' option. | ||
| CmdArgs.push_back("-s"); | ||
|
|
||
| CmdArgs.push_back("-o"); | ||
| CmdArgs.push_back(Output.getFilename()); | ||
|
|
||
| if (UseStartfiles) { | ||
| // If you want startfiles, it means you want the builtin crti and crtbegin, | ||
| // but not crt0. Myriad link commands provide their own crt0.o as needed. | ||
| CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crti.o"))); | ||
| CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtbegin.o"))); | ||
| } | ||
|
|
||
| Args.AddAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group, | ||
| options::OPT_e, options::OPT_s, options::OPT_t, | ||
| options::OPT_Z_Flag, options::OPT_r}); | ||
|
|
||
| TC.AddFilePathLibArgs(Args, CmdArgs); | ||
|
|
||
| bool NeedsSanitizerDeps = addSanitizerRuntimes(TC, Args, CmdArgs); | ||
| AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA); | ||
|
|
||
| if (UseDefaultLibs) { | ||
| if (NeedsSanitizerDeps) | ||
| linkSanitizerRuntimeDeps(TC, CmdArgs); | ||
| if (C.getDriver().CCCIsCXX()) { | ||
| if (TC.GetCXXStdlibType(Args) == ToolChain::CST_Libcxx) { | ||
| CmdArgs.push_back("-lc++"); | ||
| CmdArgs.push_back("-lc++abi"); | ||
| } else | ||
| CmdArgs.push_back("-lstdc++"); | ||
| } | ||
| if (T.getOS() == llvm::Triple::RTEMS) { | ||
| CmdArgs.push_back("--start-group"); | ||
| CmdArgs.push_back("-lc"); | ||
| CmdArgs.push_back("-lgcc"); // circularly dependent on rtems | ||
| // You must provide your own "-L" option to enable finding these. | ||
| CmdArgs.push_back("-lrtemscpu"); | ||
| CmdArgs.push_back("-lrtemsbsp"); | ||
| CmdArgs.push_back("--end-group"); | ||
| } else { | ||
| CmdArgs.push_back("-lc"); | ||
| CmdArgs.push_back("-lgcc"); | ||
| } | ||
| } | ||
| if (UseStartfiles) { | ||
| CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtend.o"))); | ||
| CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtn.o"))); | ||
| } | ||
|
|
||
| std::string Exec = | ||
| Args.MakeArgString(TC.GetProgramPath("sparc-myriad-elf-ld")); | ||
| C.addCommand(llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Exec), | ||
| CmdArgs, Inputs)); | ||
| } | ||
|
|
||
| MyriadToolChain::MyriadToolChain(const Driver &D, const llvm::Triple &Triple, | ||
| const ArgList &Args) | ||
| : Generic_ELF(D, Triple, Args) { | ||
| // If a target of 'sparc-myriad-elf' is specified to clang, it wants to use | ||
| // 'sparc-myriad--elf' (note the unknown OS) as the canonical triple. | ||
| // This won't work to find gcc. Instead we give the installation detector an | ||
| // extra triple, which is preferable to further hacks of the logic that at | ||
| // present is based solely on getArch(). In particular, it would be wrong to | ||
| // choose the myriad installation when targeting a non-myriad sparc install. | ||
| switch (Triple.getArch()) { | ||
| default: | ||
| D.Diag(clang::diag::err_target_unsupported_arch) | ||
| << Triple.getArchName() << "myriad"; | ||
| case llvm::Triple::sparc: | ||
| case llvm::Triple::sparcel: | ||
| case llvm::Triple::shave: | ||
| GCCInstallation.init(Triple, Args, {"sparc-myriad-elf"}); | ||
| } | ||
|
|
||
| if (GCCInstallation.isValid()) { | ||
| // This directory contains crt{i,n,begin,end}.o as well as libgcc. | ||
| // These files are tied to a particular version of gcc. | ||
| SmallString<128> CompilerSupportDir(GCCInstallation.getInstallPath()); | ||
| addPathIfExists(D, CompilerSupportDir, getFilePaths()); | ||
| } | ||
| // libstd++ and libc++ must both be found in this one place. | ||
| addPathIfExists(D, D.Dir + "/../sparc-myriad-elf/lib", getFilePaths()); | ||
| } | ||
|
|
||
| MyriadToolChain::~MyriadToolChain() {} | ||
|
|
||
| void MyriadToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, | ||
| ArgStringList &CC1Args) const { | ||
| if (!DriverArgs.hasArg(clang::driver::options::OPT_nostdinc)) | ||
| addSystemInclude(DriverArgs, CC1Args, getDriver().SysRoot + "/include"); | ||
| } | ||
|
|
||
| std::string MyriadToolChain::findLibCxxIncludePath() const { | ||
| std::string Path(getDriver().getInstalledDir()); | ||
| return Path + "/../include/c++/v1"; | ||
| } | ||
|
|
||
| void MyriadToolChain::addLibStdCxxIncludePaths( | ||
| const llvm::opt::ArgList &DriverArgs, | ||
| llvm::opt::ArgStringList &CC1Args) const { | ||
| StringRef LibDir = GCCInstallation.getParentLibPath(); | ||
| const GCCVersion &Version = GCCInstallation.getVersion(); | ||
| StringRef TripleStr = GCCInstallation.getTriple().str(); | ||
| const Multilib &Multilib = GCCInstallation.getMultilib(); | ||
| addLibStdCXXIncludePaths( | ||
| LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text, | ||
| "", TripleStr, "", "", Multilib.includeSuffix(), DriverArgs, CC1Args); | ||
| } | ||
|
|
||
| // MyriadToolChain handles several triples: | ||
| // {shave,sparc{,el}}-myriad-{rtems,unknown}-elf | ||
| Tool *MyriadToolChain::SelectTool(const JobAction &JA) const { | ||
| // The inherited method works fine if not targeting the SHAVE. | ||
| if (!isShaveCompilation(getTriple())) | ||
| return ToolChain::SelectTool(JA); | ||
| switch (JA.getKind()) { | ||
| case Action::PreprocessJobClass: | ||
| case Action::CompileJobClass: | ||
| if (!Compiler) | ||
| Compiler.reset(new tools::SHAVE::Compiler(*this)); | ||
| return Compiler.get(); | ||
| case Action::AssembleJobClass: | ||
| if (!Assembler) | ||
| Assembler.reset(new tools::SHAVE::Assembler(*this)); | ||
| return Assembler.get(); | ||
| default: | ||
| return ToolChain::getTool(JA.getKind()); | ||
| } | ||
| } | ||
|
|
||
| Tool *MyriadToolChain::buildLinker() const { | ||
| return new tools::Myriad::Linker(*this); | ||
| } | ||
|
|
||
| SanitizerMask MyriadToolChain::getSupportedSanitizers() const { | ||
| return SanitizerKind::Address; | ||
| } |