diff options
Diffstat (limited to 'lib/Driver/ToolChains')
-rw-r--r-- | lib/Driver/ToolChains/Ananas.cpp | 120 | ||||
-rw-r--r-- | lib/Driver/ToolChains/Ananas.h | 67 | ||||
-rw-r--r-- | lib/Driver/ToolChains/Clang.cpp | 55 | ||||
-rw-r--r-- | lib/Driver/ToolChains/Gnu.cpp | 27 | ||||
-rw-r--r-- | lib/Driver/ToolChains/WebAssembly.cpp | 5 |
5 files changed, 254 insertions, 20 deletions
diff --git a/lib/Driver/ToolChains/Ananas.cpp b/lib/Driver/ToolChains/Ananas.cpp new file mode 100644 index 000000000000..a67e1d2378f5 --- /dev/null +++ b/lib/Driver/ToolChains/Ananas.cpp @@ -0,0 +1,120 @@ +//===--- Ananas.cpp - Ananas 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 "Ananas.h" +#include "InputInfo.h" +#include "CommonArgs.h" +#include "clang/Config/config.h" +#include "clang/Driver/Compilation.h" +#include "clang/Driver/Driver.h" +#include "clang/Driver/Options.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/Option/ArgList.h" +#include "llvm/Support/Path.h" + +using namespace clang::driver; +using namespace clang::driver::tools; +using namespace clang::driver::toolchains; +using namespace clang; +using namespace llvm::opt; + +void ananas::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 ananas::Linker::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { + const ToolChain &ToolChain = 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); + + if (!D.SysRoot.empty()) + CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); + + // Ananas only supports static linkage for now. + CmdArgs.push_back("-Bstatic"); + + 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(ToolChain.GetFilePath("crt0.o"))); + CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o"))); + CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtbegin.o"))); + } + + Args.AddAllArgs(CmdArgs, options::OPT_L); + ToolChain.AddFilePathLibArgs(Args, CmdArgs); + Args.AddAllArgs(CmdArgs, + {options::OPT_T_Group, options::OPT_e, options::OPT_s, + options::OPT_t, options::OPT_Z_Flag, options::OPT_r}); + + if (D.isUsingLTO()) + AddGoldPlugin(ToolChain, Args, CmdArgs, D.getLTOMode() == LTOK_Thin, D); + + AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA); + + if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { + if (D.CCCIsCXX()) + ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs); + CmdArgs.push_back("-lc"); + } + + if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { + CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o"))); + CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o"))); + } + + const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath()); + C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); +} + +// Ananas - Ananas tool chain which can call as(1) and ld(1) directly. + +Ananas::Ananas(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) + : Generic_ELF(D, Triple, Args) { + getFilePaths().push_back(getDriver().SysRoot + "/usr/lib"); +} + +Tool *Ananas::buildAssembler() const { + return new tools::ananas::Assembler(*this); +} + +Tool *Ananas::buildLinker() const { return new tools::ananas::Linker(*this); } diff --git a/lib/Driver/ToolChains/Ananas.h b/lib/Driver/ToolChains/Ananas.h new file mode 100644 index 000000000000..2563dd2d49a9 --- /dev/null +++ b/lib/Driver/ToolChains/Ananas.h @@ -0,0 +1,67 @@ +//===--- Ananas.h - Ananas 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_ANANAS_H +#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ANANAS_H + +#include "Gnu.h" +#include "clang/Driver/Tool.h" +#include "clang/Driver/ToolChain.h" + +namespace clang { +namespace driver { +namespace tools { + +/// ananas -- Directly call GNU Binutils assembler and linker +namespace ananas { +class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool { +public: + Assembler(const ToolChain &TC) + : GnuTool("ananas::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("ananas::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 ananas +} // end namespace tools + +namespace toolchains { + +class LLVM_LIBRARY_VISIBILITY Ananas : public Generic_ELF { +public: + Ananas(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_ANANAS_H diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp index bd4e894d6504..292cf72b56ca 100644 --- a/lib/Driver/ToolChains/Clang.cpp +++ b/lib/Driver/ToolChains/Clang.cpp @@ -910,6 +910,37 @@ static void RenderDebugEnablingArgs(const ArgList &Args, ArgStringList &CmdArgs, } } +static void RenderDebugInfoCompressionArgs(const ArgList &Args, + ArgStringList &CmdArgs, + const Driver &D) { + const Arg *A = Args.getLastArg(options::OPT_gz, options::OPT_gz_EQ); + if (!A) + return; + + if (A->getOption().getID() == options::OPT_gz) { + if (llvm::zlib::isAvailable()) + CmdArgs.push_back("-compress-debug-sections"); + else + D.Diag(diag::warn_debug_compression_unavailable); + return; + } + + StringRef Value = A->getValue(); + if (Value == "none") { + CmdArgs.push_back("-compress-debug-sections=none"); + } else if (Value == "zlib" || Value == "zlib-gnu") { + if (llvm::zlib::isAvailable()) { + CmdArgs.push_back( + Args.MakeArgString("-compress-debug-sections=" + Twine(Value))); + } else { + D.Diag(diag::warn_debug_compression_unavailable); + } + } else { + D.Diag(diag::err_drv_unsupported_option_argument) + << A->getOption().getName() << Value; + } +} + static const char *RelocationModelName(llvm::Reloc::Model Model) { switch (Model) { case llvm::Reloc::Static: @@ -1747,10 +1778,6 @@ static void CollectArgsForIntegratedAssembler(Compilation &C, // arg after parsing the '-I' arg. bool TakeNextArg = false; - // When using an integrated assembler, translate -Wa, and -Xassembler - // options. - bool CompressDebugSections = false; - bool UseRelaxRelocations = ENABLE_X86_RELAX_RELOCATIONS; const char *MipsTargetFeature = nullptr; for (const Arg *A : @@ -1825,12 +1852,11 @@ static void CollectArgsForIntegratedAssembler(Compilation &C, CmdArgs.push_back("-massembler-fatal-warnings"); } else if (Value == "--noexecstack") { CmdArgs.push_back("-mnoexecstack"); - } else if (Value == "-compress-debug-sections" || - Value == "--compress-debug-sections") { - CompressDebugSections = true; - } else if (Value == "-nocompress-debug-sections" || + } else if (Value.startswith("-compress-debug-sections") || + Value.startswith("--compress-debug-sections") || + Value == "-nocompress-debug-sections" || Value == "--nocompress-debug-sections") { - CompressDebugSections = false; + CmdArgs.push_back(Value.data()); } else if (Value == "-mrelax-relocations=yes" || Value == "--mrelax-relocations=yes") { UseRelaxRelocations = true; @@ -1883,12 +1909,6 @@ static void CollectArgsForIntegratedAssembler(Compilation &C, } } } - if (CompressDebugSections) { - if (llvm::zlib::isAvailable()) - CmdArgs.push_back("-compress-debug-sections"); - else - D.Diag(diag::warn_debug_compression_unavailable); - } if (UseRelaxRelocations) CmdArgs.push_back("--mrelax-relocations"); if (MipsTargetFeature != nullptr) { @@ -2824,6 +2844,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-generate-type-units"); } + RenderDebugInfoCompressionArgs(Args, CmdArgs, D); + bool UseSeparateSections = isUseSeparateSections(Triple); if (Args.hasFlag(options::OPT_ffunction_sections, @@ -4927,6 +4949,7 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, const llvm::Triple &Triple = getToolChain().getEffectiveTriple(); const std::string &TripleStr = Triple.getTriple(); + const auto &D = getToolChain().getDriver(); // Don't warn about "clang -w -c foo.s" Args.ClaimAllArgs(options::OPT_w); @@ -5014,6 +5037,8 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, } RenderDebugEnablingArgs(Args, CmdArgs, DebugInfoKind, DwarfVersion, llvm::DebuggerKind::Default); + RenderDebugInfoCompressionArgs(Args, CmdArgs, D); + // Handle -fPIC et al -- the relocation-model affects the assembler // for some targets. diff --git a/lib/Driver/ToolChains/Gnu.cpp b/lib/Driver/ToolChains/Gnu.cpp index d50f8e21f62f..bca5d3a3f28b 100644 --- a/lib/Driver/ToolChains/Gnu.cpp +++ b/lib/Driver/ToolChains/Gnu.cpp @@ -650,6 +650,8 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { + const auto &D = getToolChain().getDriver(); + claimNoWarnArgs(Args); ArgStringList CmdArgs; @@ -660,6 +662,23 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C, std::tie(RelocationModel, PICLevel, IsPIE) = ParsePICArgs(getToolChain(), Args); + if (const Arg *A = Args.getLastArg(options::OPT_gz, options::OPT_gz_EQ)) { + if (A->getOption().getID() == options::OPT_gz) { + CmdArgs.push_back("-compress-debug-sections"); + } else { + StringRef Value = A->getValue(); + if (Value == "none") { + CmdArgs.push_back("-compress-debug-sections=none"); + } else if (Value == "zlib" || Value == "zlib-gnu") { + CmdArgs.push_back( + Args.MakeArgString("-compress-debug-sections=" + Twine(Value))); + } else { + D.Diag(diag::err_drv_unsupported_option_argument) + << A->getOption().getName() << Value; + } + } + } + switch (getToolChain().getArch()) { default: break; @@ -2319,9 +2338,11 @@ bool Generic_GCC::IsIntegratedAssemblerDefault() const { return true; case llvm::Triple::mips64: case llvm::Triple::mips64el: - // Enabled for Debian mips64/mips64el only. Other targets are unable to - // distinguish N32 from N64. - if (getTriple().getEnvironment() == llvm::Triple::GNUABI64) + // Enabled for Debian and Android mips64/mipsel, as they can precisely + // identify the ABI in use (Debian) or only use N64 for MIPS64 (Android). + // Other targets are unable to distinguish N32 from N64. + if (getTriple().getEnvironment() == llvm::Triple::GNUABI64 || + getTriple().isAndroid()) return true; return false; default: diff --git a/lib/Driver/ToolChains/WebAssembly.cpp b/lib/Driver/ToolChains/WebAssembly.cpp index 3471569b6884..fcb6418b2517 100644 --- a/lib/Driver/ToolChains/WebAssembly.cpp +++ b/lib/Driver/ToolChains/WebAssembly.cpp @@ -83,6 +83,8 @@ void wasm::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (Args.hasArg(options::OPT_pthread)) CmdArgs.push_back("-lpthread"); + CmdArgs.push_back("-allow-undefined-file"); + CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("wasm.syms"))); CmdArgs.push_back("-lc"); CmdArgs.push_back("-lcompiler_rt"); } @@ -104,8 +106,7 @@ WebAssembly::WebAssembly(const Driver &D, const llvm::Triple &Triple, getProgramPaths().push_back(getDriver().getInstalledDir()); - getFilePaths().push_back( - getDriver().SysRoot + "/lib" + (Triple.isArch32Bit() ? "32" : "64")); + getFilePaths().push_back(getDriver().SysRoot + "/lib"); } bool WebAssembly::IsMathErrnoDefault() const { return false; } |