summaryrefslogtreecommitdiff
path: root/lib/Driver/ToolChains
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Driver/ToolChains')
-rw-r--r--lib/Driver/ToolChains/Ananas.cpp120
-rw-r--r--lib/Driver/ToolChains/Ananas.h67
-rw-r--r--lib/Driver/ToolChains/Clang.cpp55
-rw-r--r--lib/Driver/ToolChains/Gnu.cpp27
-rw-r--r--lib/Driver/ToolChains/WebAssembly.cpp5
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; }