Index: cfe/trunk/lib/Driver/Driver.cpp =================================================================== --- cfe/trunk/lib/Driver/Driver.cpp +++ cfe/trunk/lib/Driver/Driver.cpp @@ -2030,6 +2030,9 @@ ToolChain *&TC = ToolChains[Target.str()]; if (!TC) { switch (Target.getOS()) { + case llvm::Triple::CloudABI: + TC = new toolchains::CloudABI(*this, Target, Args); + break; case llvm::Triple::Darwin: case llvm::Triple::MacOSX: case llvm::Triple::IOS: Index: cfe/trunk/lib/Driver/ToolChains.h =================================================================== --- cfe/trunk/lib/Driver/ToolChains.h +++ cfe/trunk/lib/Driver/ToolChains.h @@ -512,6 +512,31 @@ llvm::opt::ArgStringList &CC1Args) const override; }; +class LLVM_LIBRARY_VISIBILITY CloudABI : public Generic_ELF { +public: + CloudABI(const Driver &D, const llvm::Triple &Triple, + const llvm::opt::ArgList &Args); + bool HasNativeLLVMSupport() const override { return true; } + + bool IsMathErrnoDefault() const override { return false; } + bool IsObjCNonFragileABIDefault() const override { return true; } + + CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) + const override { + return ToolChain::CST_Libcxx; + } + void AddClangCXXStdlibIncludeArgs( + 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 isPIEDefault() const override { return false; } + +protected: + Tool *buildLinker() const override; +}; + class LLVM_LIBRARY_VISIBILITY Solaris : public Generic_GCC { public: Solaris(const Driver &D, const llvm::Triple &Triple, Index: cfe/trunk/lib/Driver/ToolChains.cpp =================================================================== --- cfe/trunk/lib/Driver/ToolChains.cpp +++ cfe/trunk/lib/Driver/ToolChains.cpp @@ -2340,6 +2340,36 @@ return false; } +// CloudABI - CloudABI tool chain which can call ld(1) directly. + +CloudABI::CloudABI(const Driver &D, const llvm::Triple &Triple, + const ArgList &Args) + : Generic_ELF(D, Triple, Args) { + SmallString<128> P(getDriver().Dir); + llvm::sys::path::append(P, "..", getTriple().str(), "lib"); + getFilePaths().push_back(P.str()); +} + +void CloudABI::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const { + if (DriverArgs.hasArg(options::OPT_nostdlibinc) && + DriverArgs.hasArg(options::OPT_nostdincxx)) + return; + + SmallString<128> P(getDriver().Dir); + llvm::sys::path::append(P, "..", getTriple().str(), "include/c++/v1"); + addSystemInclude(DriverArgs, CC1Args, P.str()); +} + +void CloudABI::AddCXXStdlibLibArgs(const ArgList &Args, + ArgStringList &CmdArgs) const { + CmdArgs.push_back("-lc++"); + CmdArgs.push_back("-lc++abi"); + CmdArgs.push_back("-lunwind"); +} + +Tool *CloudABI::buildLinker() const { return new tools::cloudabi::Link(*this); } + /// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly. OpenBSD::OpenBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) Index: cfe/trunk/lib/Driver/Tools.h =================================================================== --- cfe/trunk/lib/Driver/Tools.h +++ cfe/trunk/lib/Driver/Tools.h @@ -248,6 +248,22 @@ bool hasPPCAbiArg(const llvm::opt::ArgList &Args, const char *Value); } + /// cloudabi -- Directly call GNU Binutils linker +namespace cloudabi { +class LLVM_LIBRARY_VISIBILITY Link : public GnuTool { +public: + Link(const ToolChain &TC) : GnuTool("cloudabi::Link", "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 cloudabi + namespace darwin { llvm::Triple::ArchType getArchTypeForMachOArchName(StringRef Str); void setTripleTypeForMachOArchName(llvm::Triple &T, StringRef Str); Index: cfe/trunk/lib/Driver/Tools.cpp =================================================================== --- cfe/trunk/lib/Driver/Tools.cpp +++ cfe/trunk/lib/Driver/Tools.cpp @@ -5725,6 +5725,76 @@ return Args.MakeArgString(Res + ".d"); } +void cloudabi::Link::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)); + + // CloudABI only supports static linkage. + CmdArgs.push_back("-Bstatic"); + CmdArgs.push_back("--eh-frame-hdr"); + CmdArgs.push_back("--gc-sections"); + + if (Output.isFilename()) { + CmdArgs.push_back("-o"); + CmdArgs.push_back(Output.getFilename()); + } else { + assert(Output.isNothing() && "Invalid output."); + } + + if (!Args.hasArg(options::OPT_nostdlib) && + !Args.hasArg(options::OPT_nostartfiles)) { + CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o"))); + CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtbegin.o"))); + } + + Args.AddAllArgs(CmdArgs, options::OPT_L); + const ToolChain::path_list &Paths = ToolChain.getFilePaths(); + for (const auto &Path : Paths) + CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + Path)); + 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(ToolChain, Args)) + AddGoldPlugin(ToolChain, Args, CmdArgs); + + AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs); + + if (!Args.hasArg(options::OPT_nostdlib) && + !Args.hasArg(options::OPT_nodefaultlibs)) { + if (D.CCCIsCXX()) + ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs); + CmdArgs.push_back("-lc"); + CmdArgs.push_back("-lcompiler_rt"); + } + + if (!Args.hasArg(options::OPT_nostdlib) && + !Args.hasArg(options::OPT_nostartfiles)) + CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o"))); + + const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath()); + C.addCommand(llvm::make_unique(JA, *this, Exec, CmdArgs)); +} + void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, Index: cfe/trunk/test/Driver/cloudabi.c =================================================================== --- cfe/trunk/test/Driver/cloudabi.c +++ cfe/trunk/test/Driver/cloudabi.c @@ -0,0 +1,3 @@ +// RUN: %clang %s -### -target x86_64-unknown-cloudabi 2>&1 | FileCheck %s +// CHECK: "-cc1" "-triple" "x86_64-unknown-cloudabi" +// CHECK: "-Bstatic" "--eh-frame-hdr" "--gc-sections" "-o" "a.out" "crt0.o" "crtbegin.o" "{{.*}}" "{{.*}}" "-lc" "-lcompiler_rt" "crtend.o" Index: cfe/trunk/test/Driver/cloudabi.cpp =================================================================== --- cfe/trunk/test/Driver/cloudabi.cpp +++ cfe/trunk/test/Driver/cloudabi.cpp @@ -0,0 +1,3 @@ +// RUN: %clangxx %s -### -target x86_64-unknown-cloudabi 2>&1 | FileCheck %s +// CHECK: "-cc1" "-triple" "x86_64-unknown-cloudabi" +// CHECK: "-Bstatic" "--eh-frame-hdr" "--gc-sections" "-o" "a.out" "crt0.o" "crtbegin.o" "{{.*}}" "{{.*}}" "-lc++" "-lc++abi" "-lunwind" "-lc" "-lcompiler_rt" "crtend.o"