Index: lib/Basic/Targets.cpp =================================================================== --- lib/Basic/Targets.cpp +++ lib/Basic/Targets.cpp @@ -111,6 +111,21 @@ : OSTargetInfo(Triple, Opts) {} }; +// Ananas target +template +class AnanasTargetInfo : public OSTargetInfo { +protected: + void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, + MacroBuilder &Builder) const override { + // Ananas defines + Builder.defineMacro("__Ananas__"); + Builder.defineMacro("__ELF__"); + } +public: + AnanasTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : OSTargetInfo(Triple, Opts) {} +}; + static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, const llvm::Triple &Triple, StringRef &PlatformName, @@ -9378,6 +9393,8 @@ return new DarwinI386TargetInfo(Triple, Opts); switch (os) { + case llvm::Triple::Ananas: + return new AnanasTargetInfo(Triple, Opts); case llvm::Triple::CloudABI: return new CloudABITargetInfo(Triple, Opts); case llvm::Triple::Linux: { @@ -9433,6 +9450,8 @@ return new DarwinX86_64TargetInfo(Triple, Opts); switch (os) { + case llvm::Triple::Ananas: + return new AnanasTargetInfo(Triple, Opts); case llvm::Triple::CloudABI: return new CloudABITargetInfo(Triple, Opts); case llvm::Triple::Linux: { Index: lib/Driver/CMakeLists.txt =================================================================== --- lib/Driver/CMakeLists.txt +++ lib/Driver/CMakeLists.txt @@ -27,6 +27,7 @@ ToolChains/Arch/Sparc.cpp ToolChains/Arch/SystemZ.cpp ToolChains/Arch/X86.cpp + ToolChains/Ananas.cpp ToolChains/AMDGPU.cpp ToolChains/AVR.cpp ToolChains/Bitrig.cpp Index: lib/Driver/Driver.cpp =================================================================== --- lib/Driver/Driver.cpp +++ lib/Driver/Driver.cpp @@ -11,6 +11,7 @@ #include "InputInfo.h" #include "ToolChains/AMDGPU.h" #include "ToolChains/AVR.h" +#include "ToolChains/Ananas.h" #include "ToolChains/Bitrig.h" #include "ToolChains/Clang.h" #include "ToolChains/CloudABI.h" @@ -3707,6 +3708,9 @@ case llvm::Triple::Haiku: TC = llvm::make_unique(*this, Target, Args); break; + case llvm::Triple::Ananas: + TC = llvm::make_unique(*this, Target, Args); + break; case llvm::Triple::CloudABI: TC = llvm::make_unique(*this, Target, Args); break; Index: lib/Driver/ToolChains/Ananas.h =================================================================== --- lib/Driver/ToolChains/Ananas.h +++ 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 Index: lib/Driver/ToolChains/Ananas.cpp =================================================================== --- lib/Driver/ToolChains/Ananas.cpp +++ 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(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(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); } Index: test/Driver/ananas.c =================================================================== --- test/Driver/ananas.c +++ test/Driver/ananas.c @@ -0,0 +1,9 @@ +// RUN: %clang -no-canonical-prefixes -target x86_64-unknown-ananas -static %s \ +// RUN: --sysroot=%S/Inputs/ananas-tree -### 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-STATIC %s +// CHECK-STATIC: ld{{.*}}" "-Bstatic" +// CHECK-STATIC: crt0.o +// CHECK-STATIC: crti.o +// CHECK-STATIC: crtbegin.o +// CHECK-STATIC: crtend.o +// CHECK-STATIC: crtn.o