10b57cec5SDimitry Andric //===--- XCore.cpp - XCore ToolChain Implementations ------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric
90b57cec5SDimitry Andric #include "XCore.h"
100b57cec5SDimitry Andric #include "CommonArgs.h"
110b57cec5SDimitry Andric #include "clang/Driver/Compilation.h"
120b57cec5SDimitry Andric #include "clang/Driver/Driver.h"
130b57cec5SDimitry Andric #include "clang/Driver/Options.h"
140b57cec5SDimitry Andric #include "llvm/Option/ArgList.h"
150b57cec5SDimitry Andric #include <cstdlib> // ::getenv
160b57cec5SDimitry Andric
170b57cec5SDimitry Andric using namespace clang::driver;
180b57cec5SDimitry Andric using namespace clang::driver::toolchains;
190b57cec5SDimitry Andric using namespace clang;
200b57cec5SDimitry Andric using namespace llvm::opt;
210b57cec5SDimitry Andric
220b57cec5SDimitry Andric /// XCore Tools
230b57cec5SDimitry Andric // We pass assemble and link construction to the xcc tool.
240b57cec5SDimitry Andric
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const250b57cec5SDimitry Andric void tools::XCore::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
260b57cec5SDimitry Andric const InputInfo &Output,
270b57cec5SDimitry Andric const InputInfoList &Inputs,
280b57cec5SDimitry Andric const ArgList &Args,
290b57cec5SDimitry Andric const char *LinkingOutput) const {
300b57cec5SDimitry Andric claimNoWarnArgs(Args);
310b57cec5SDimitry Andric ArgStringList CmdArgs;
320b57cec5SDimitry Andric
330b57cec5SDimitry Andric CmdArgs.push_back("-o");
340b57cec5SDimitry Andric CmdArgs.push_back(Output.getFilename());
350b57cec5SDimitry Andric
360b57cec5SDimitry Andric CmdArgs.push_back("-c");
370b57cec5SDimitry Andric
380b57cec5SDimitry Andric if (Args.hasArg(options::OPT_v))
390b57cec5SDimitry Andric CmdArgs.push_back("-v");
400b57cec5SDimitry Andric
410b57cec5SDimitry Andric if (Arg *A = Args.getLastArg(options::OPT_g_Group))
420b57cec5SDimitry Andric if (!A->getOption().matches(options::OPT_g0))
430b57cec5SDimitry Andric CmdArgs.push_back("-g");
440b57cec5SDimitry Andric
450b57cec5SDimitry Andric if (Args.hasFlag(options::OPT_fverbose_asm, options::OPT_fno_verbose_asm,
460b57cec5SDimitry Andric false))
470b57cec5SDimitry Andric CmdArgs.push_back("-fverbose-asm");
480b57cec5SDimitry Andric
490b57cec5SDimitry Andric Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
500b57cec5SDimitry Andric
510b57cec5SDimitry Andric for (const auto &II : Inputs)
520b57cec5SDimitry Andric CmdArgs.push_back(II.getFilename());
530b57cec5SDimitry Andric
540b57cec5SDimitry Andric const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("xcc"));
555ffd83dbSDimitry Andric C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
56e8d8bef9SDimitry Andric Exec, CmdArgs, Inputs, Output));
570b57cec5SDimitry Andric }
580b57cec5SDimitry Andric
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const590b57cec5SDimitry Andric void tools::XCore::Linker::ConstructJob(Compilation &C, const JobAction &JA,
600b57cec5SDimitry Andric const InputInfo &Output,
610b57cec5SDimitry Andric const InputInfoList &Inputs,
620b57cec5SDimitry Andric const ArgList &Args,
630b57cec5SDimitry Andric const char *LinkingOutput) const {
640b57cec5SDimitry Andric ArgStringList CmdArgs;
650b57cec5SDimitry Andric
66*5f757f3fSDimitry Andric assert((Output.isFilename() || Output.isNothing()) && "Invalid output.");
670b57cec5SDimitry Andric if (Output.isFilename()) {
680b57cec5SDimitry Andric CmdArgs.push_back("-o");
690b57cec5SDimitry Andric CmdArgs.push_back(Output.getFilename());
700b57cec5SDimitry Andric }
710b57cec5SDimitry Andric
720b57cec5SDimitry Andric if (Args.hasArg(options::OPT_v))
730b57cec5SDimitry Andric CmdArgs.push_back("-v");
740b57cec5SDimitry Andric
750b57cec5SDimitry Andric // Pass -fexceptions through to the linker if it was present.
760b57cec5SDimitry Andric if (Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions,
770b57cec5SDimitry Andric false))
780b57cec5SDimitry Andric CmdArgs.push_back("-fexceptions");
790b57cec5SDimitry Andric
800b57cec5SDimitry Andric AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
810b57cec5SDimitry Andric
820b57cec5SDimitry Andric const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("xcc"));
835ffd83dbSDimitry Andric C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
84e8d8bef9SDimitry Andric Exec, CmdArgs, Inputs, Output));
850b57cec5SDimitry Andric }
860b57cec5SDimitry Andric
870b57cec5SDimitry Andric /// XCore tool chain
XCoreToolChain(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)880b57cec5SDimitry Andric XCoreToolChain::XCoreToolChain(const Driver &D, const llvm::Triple &Triple,
890b57cec5SDimitry Andric const ArgList &Args)
900b57cec5SDimitry Andric : ToolChain(D, Triple, Args) {
910b57cec5SDimitry Andric // ProgramPaths are found via 'PATH' environment variable.
920b57cec5SDimitry Andric }
930b57cec5SDimitry Andric
buildAssembler() const940b57cec5SDimitry Andric Tool *XCoreToolChain::buildAssembler() const {
950b57cec5SDimitry Andric return new tools::XCore::Assembler(*this);
960b57cec5SDimitry Andric }
970b57cec5SDimitry Andric
buildLinker() const980b57cec5SDimitry Andric Tool *XCoreToolChain::buildLinker() const {
990b57cec5SDimitry Andric return new tools::XCore::Linker(*this);
1000b57cec5SDimitry Andric }
1010b57cec5SDimitry Andric
isPICDefault() const1020b57cec5SDimitry Andric bool XCoreToolChain::isPICDefault() const { return false; }
1030b57cec5SDimitry Andric
isPIEDefault(const llvm::opt::ArgList & Args) const104349cc55cSDimitry Andric bool XCoreToolChain::isPIEDefault(const llvm::opt::ArgList &Args) const {
105349cc55cSDimitry Andric return false;
106349cc55cSDimitry Andric }
1070b57cec5SDimitry Andric
isPICDefaultForced() const1080b57cec5SDimitry Andric bool XCoreToolChain::isPICDefaultForced() const { return false; }
1090b57cec5SDimitry Andric
SupportsProfiling() const1100b57cec5SDimitry Andric bool XCoreToolChain::SupportsProfiling() const { return false; }
1110b57cec5SDimitry Andric
hasBlocksRuntime() const1120b57cec5SDimitry Andric bool XCoreToolChain::hasBlocksRuntime() const { return false; }
1130b57cec5SDimitry Andric
AddClangSystemIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const1140b57cec5SDimitry Andric void XCoreToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
1150b57cec5SDimitry Andric ArgStringList &CC1Args) const {
1160b57cec5SDimitry Andric if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc) ||
1170b57cec5SDimitry Andric DriverArgs.hasArg(options::OPT_nostdlibinc))
1180b57cec5SDimitry Andric return;
1190b57cec5SDimitry Andric if (const char *cl_include_dir = getenv("XCC_C_INCLUDE_PATH")) {
1200b57cec5SDimitry Andric SmallVector<StringRef, 4> Dirs;
1210b57cec5SDimitry Andric const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
1220b57cec5SDimitry Andric StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr));
1230b57cec5SDimitry Andric ArrayRef<StringRef> DirVec(Dirs);
1240b57cec5SDimitry Andric addSystemIncludes(DriverArgs, CC1Args, DirVec);
1250b57cec5SDimitry Andric }
1260b57cec5SDimitry Andric }
1270b57cec5SDimitry Andric
addClangTargetOptions(const ArgList & DriverArgs,ArgStringList & CC1Args,Action::OffloadKind) const1280b57cec5SDimitry Andric void XCoreToolChain::addClangTargetOptions(const ArgList &DriverArgs,
1290b57cec5SDimitry Andric ArgStringList &CC1Args,
1300b57cec5SDimitry Andric Action::OffloadKind) const {
1310b57cec5SDimitry Andric CC1Args.push_back("-nostdsysteminc");
1321fd87a68SDimitry Andric // Set `-fno-use-cxa-atexit` to default.
1331fd87a68SDimitry Andric if (!DriverArgs.hasFlag(options::OPT_fuse_cxa_atexit,
1341fd87a68SDimitry Andric options::OPT_fno_use_cxa_atexit, false))
1351fd87a68SDimitry Andric CC1Args.push_back("-fno-use-cxa-atexit");
1360b57cec5SDimitry Andric }
1370b57cec5SDimitry Andric
AddClangCXXStdlibIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const1380b57cec5SDimitry Andric void XCoreToolChain::AddClangCXXStdlibIncludeArgs(
1390b57cec5SDimitry Andric const ArgList &DriverArgs, ArgStringList &CC1Args) const {
1400b57cec5SDimitry Andric if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc) ||
1410b57cec5SDimitry Andric DriverArgs.hasArg(options::OPT_nostdlibinc) ||
1420b57cec5SDimitry Andric DriverArgs.hasArg(options::OPT_nostdincxx))
1430b57cec5SDimitry Andric return;
1440b57cec5SDimitry Andric if (const char *cl_include_dir = getenv("XCC_CPLUS_INCLUDE_PATH")) {
1450b57cec5SDimitry Andric SmallVector<StringRef, 4> Dirs;
1460b57cec5SDimitry Andric const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
1470b57cec5SDimitry Andric StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr));
1480b57cec5SDimitry Andric ArrayRef<StringRef> DirVec(Dirs);
1490b57cec5SDimitry Andric addSystemIncludes(DriverArgs, CC1Args, DirVec);
1500b57cec5SDimitry Andric }
1510b57cec5SDimitry Andric }
1520b57cec5SDimitry Andric
AddCXXStdlibLibArgs(const ArgList & Args,ArgStringList & CmdArgs) const1530b57cec5SDimitry Andric void XCoreToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
1540b57cec5SDimitry Andric ArgStringList &CmdArgs) const {
1550b57cec5SDimitry Andric // We don't output any lib args. This is handled by xcc.
1560b57cec5SDimitry Andric }
157