diff options
Diffstat (limited to 'clang/lib/Driver/ToolChains/Ananas.cpp')
| -rw-r--r-- | clang/lib/Driver/ToolChains/Ananas.cpp | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/clang/lib/Driver/ToolChains/Ananas.cpp b/clang/lib/Driver/ToolChains/Ananas.cpp new file mode 100644 index 000000000000..2f11c9739a0e --- /dev/null +++ b/clang/lib/Driver/ToolChains/Ananas.cpp @@ -0,0 +1,140 @@ +//===--- Ananas.cpp - Ananas ToolChain Implementations ------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "Ananas.h" +#include "InputInfo.h" +#include "CommonArgs.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(std::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)); + + 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 { + Args.AddAllArgs(CmdArgs, options::OPT_pie); + CmdArgs.push_back("-dynamic-linker"); + CmdArgs.push_back("/lib/ld-ananas.so"); + } + } + + 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)) { + if (!Args.hasArg(options::OPT_shared)) { + CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o"))); + } + CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o"))); + if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie)) { + CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtbeginS.o"))); + } else { + 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()) { + assert(!Inputs.empty() && "Must have at least one input."); + AddGoldPlugin(ToolChain, Args, CmdArgs, Output, Inputs[0], + D.getLTOMode() == LTOK_Thin); + } + + AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA); + + if (ToolChain.ShouldLinkCXXStdlib(Args)) + ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs); + if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) + CmdArgs.push_back("-lc"); + + if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { + if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie)) + 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"))); + } + + const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath()); + C.addCommand(std::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); } |
