10b57cec5SDimitry Andric //===--- MSP430.cpp - MSP430 Helpers for Tools ------------------*- 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 "MSP430.h"
100b57cec5SDimitry Andric #include "CommonArgs.h"
110b57cec5SDimitry Andric #include "Gnu.h"
120b57cec5SDimitry Andric #include "clang/Driver/Compilation.h"
13fe6060f1SDimitry Andric #include "clang/Driver/InputInfo.h"
140b57cec5SDimitry Andric #include "clang/Driver/Multilib.h"
150b57cec5SDimitry Andric #include "clang/Driver/Options.h"
160b57cec5SDimitry Andric #include "llvm/Option/ArgList.h"
170b57cec5SDimitry Andric #include "llvm/Support/FileSystem.h"
180b57cec5SDimitry Andric #include "llvm/Support/Path.h"
190b57cec5SDimitry Andric
200b57cec5SDimitry Andric using namespace clang::driver;
210b57cec5SDimitry Andric using namespace clang::driver::toolchains;
220b57cec5SDimitry Andric using namespace clang::driver::tools;
230b57cec5SDimitry Andric using namespace clang;
240b57cec5SDimitry Andric using namespace llvm::opt;
250b57cec5SDimitry Andric
isSupportedMCU(const StringRef MCU)260b57cec5SDimitry Andric static bool isSupportedMCU(const StringRef MCU) {
270b57cec5SDimitry Andric return llvm::StringSwitch<bool>(MCU)
280b57cec5SDimitry Andric #define MSP430_MCU(NAME) .Case(NAME, true)
290b57cec5SDimitry Andric #include "clang/Basic/MSP430Target.def"
300b57cec5SDimitry Andric .Default(false);
310b57cec5SDimitry Andric }
320b57cec5SDimitry Andric
getSupportedHWMult(const Arg * MCU)330b57cec5SDimitry Andric static StringRef getSupportedHWMult(const Arg *MCU) {
340b57cec5SDimitry Andric if (!MCU)
350b57cec5SDimitry Andric return "none";
360b57cec5SDimitry Andric
370b57cec5SDimitry Andric return llvm::StringSwitch<StringRef>(MCU->getValue())
380b57cec5SDimitry Andric #define MSP430_MCU_FEAT(NAME, HWMULT) .Case(NAME, HWMULT)
390b57cec5SDimitry Andric #include "clang/Basic/MSP430Target.def"
400b57cec5SDimitry Andric .Default("none");
410b57cec5SDimitry Andric }
420b57cec5SDimitry Andric
getHWMultLib(const ArgList & Args)430b57cec5SDimitry Andric static StringRef getHWMultLib(const ArgList &Args) {
440b57cec5SDimitry Andric StringRef HWMult = Args.getLastArgValue(options::OPT_mhwmult_EQ, "auto");
450b57cec5SDimitry Andric if (HWMult == "auto") {
460b57cec5SDimitry Andric HWMult = getSupportedHWMult(Args.getLastArg(options::OPT_mmcu_EQ));
470b57cec5SDimitry Andric }
480b57cec5SDimitry Andric
490b57cec5SDimitry Andric return llvm::StringSwitch<StringRef>(HWMult)
500b57cec5SDimitry Andric .Case("16bit", "-lmul_16")
510b57cec5SDimitry Andric .Case("32bit", "-lmul_32")
520b57cec5SDimitry Andric .Case("f5series", "-lmul_f5")
530b57cec5SDimitry Andric .Default("-lmul_none");
540b57cec5SDimitry Andric }
550b57cec5SDimitry Andric
getMSP430TargetFeatures(const Driver & D,const ArgList & Args,std::vector<StringRef> & Features)560b57cec5SDimitry Andric void msp430::getMSP430TargetFeatures(const Driver &D, const ArgList &Args,
570b57cec5SDimitry Andric std::vector<StringRef> &Features) {
580b57cec5SDimitry Andric const Arg *MCU = Args.getLastArg(options::OPT_mmcu_EQ);
590b57cec5SDimitry Andric if (MCU && !isSupportedMCU(MCU->getValue())) {
600b57cec5SDimitry Andric D.Diag(diag::err_drv_clang_unsupported) << MCU->getValue();
610b57cec5SDimitry Andric return;
620b57cec5SDimitry Andric }
630b57cec5SDimitry Andric
640b57cec5SDimitry Andric const Arg *HWMultArg = Args.getLastArg(options::OPT_mhwmult_EQ);
650b57cec5SDimitry Andric if (!MCU && !HWMultArg)
660b57cec5SDimitry Andric return;
670b57cec5SDimitry Andric
680b57cec5SDimitry Andric StringRef HWMult = HWMultArg ? HWMultArg->getValue() : "auto";
690b57cec5SDimitry Andric StringRef SupportedHWMult = getSupportedHWMult(MCU);
700b57cec5SDimitry Andric
710b57cec5SDimitry Andric if (HWMult == "auto") {
720b57cec5SDimitry Andric // 'auto' - deduce hw multiplier support based on mcu name provided.
730b57cec5SDimitry Andric // If no mcu name is provided, assume no hw multiplier is supported.
740b57cec5SDimitry Andric if (!MCU)
750b57cec5SDimitry Andric D.Diag(clang::diag::warn_drv_msp430_hwmult_no_device);
760b57cec5SDimitry Andric HWMult = SupportedHWMult;
770b57cec5SDimitry Andric }
780b57cec5SDimitry Andric
790b57cec5SDimitry Andric if (HWMult == "none") {
800b57cec5SDimitry Andric // 'none' - disable hw multiplier.
810b57cec5SDimitry Andric Features.push_back("-hwmult16");
820b57cec5SDimitry Andric Features.push_back("-hwmult32");
830b57cec5SDimitry Andric Features.push_back("-hwmultf5");
840b57cec5SDimitry Andric return;
850b57cec5SDimitry Andric }
860b57cec5SDimitry Andric
870b57cec5SDimitry Andric if (MCU && SupportedHWMult == "none")
880b57cec5SDimitry Andric D.Diag(clang::diag::warn_drv_msp430_hwmult_unsupported) << HWMult;
890b57cec5SDimitry Andric if (MCU && HWMult != SupportedHWMult)
900b57cec5SDimitry Andric D.Diag(clang::diag::warn_drv_msp430_hwmult_mismatch)
910b57cec5SDimitry Andric << SupportedHWMult << HWMult;
920b57cec5SDimitry Andric
930b57cec5SDimitry Andric if (HWMult == "16bit") {
940b57cec5SDimitry Andric // '16bit' - for 16-bit only hw multiplier.
950b57cec5SDimitry Andric Features.push_back("+hwmult16");
960b57cec5SDimitry Andric } else if (HWMult == "32bit") {
970b57cec5SDimitry Andric // '32bit' - for 16/32-bit hw multiplier.
980b57cec5SDimitry Andric Features.push_back("+hwmult32");
990b57cec5SDimitry Andric } else if (HWMult == "f5series") {
1000b57cec5SDimitry Andric // 'f5series' - for 16/32-bit hw multiplier supported by F5 series mcus.
1010b57cec5SDimitry Andric Features.push_back("+hwmultf5");
1020b57cec5SDimitry Andric } else {
1030b57cec5SDimitry Andric D.Diag(clang::diag::err_drv_unsupported_option_argument)
104bdd1243dSDimitry Andric << HWMultArg->getSpelling() << HWMult;
1050b57cec5SDimitry Andric }
1060b57cec5SDimitry Andric }
1070b57cec5SDimitry Andric
1080b57cec5SDimitry Andric /// MSP430 Toolchain
MSP430ToolChain(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)1090b57cec5SDimitry Andric MSP430ToolChain::MSP430ToolChain(const Driver &D, const llvm::Triple &Triple,
1100b57cec5SDimitry Andric const ArgList &Args)
1110b57cec5SDimitry Andric : Generic_ELF(D, Triple, Args) {
1120b57cec5SDimitry Andric
1130b57cec5SDimitry Andric StringRef MultilibSuf = "";
1140b57cec5SDimitry Andric
1150b57cec5SDimitry Andric GCCInstallation.init(Triple, Args);
1160b57cec5SDimitry Andric if (GCCInstallation.isValid()) {
1170b57cec5SDimitry Andric MultilibSuf = GCCInstallation.getMultilib().gccSuffix();
1180b57cec5SDimitry Andric
1190b57cec5SDimitry Andric SmallString<128> GCCBinPath;
1200b57cec5SDimitry Andric llvm::sys::path::append(GCCBinPath,
1210b57cec5SDimitry Andric GCCInstallation.getParentLibPath(), "..", "bin");
1220b57cec5SDimitry Andric addPathIfExists(D, GCCBinPath, getProgramPaths());
1230b57cec5SDimitry Andric
1240b57cec5SDimitry Andric SmallString<128> GCCRtPath;
1250b57cec5SDimitry Andric llvm::sys::path::append(GCCRtPath,
1260b57cec5SDimitry Andric GCCInstallation.getInstallPath(), MultilibSuf);
1270b57cec5SDimitry Andric addPathIfExists(D, GCCRtPath, getFilePaths());
1280b57cec5SDimitry Andric }
1290b57cec5SDimitry Andric
1300b57cec5SDimitry Andric SmallString<128> SysRootDir(computeSysRoot());
131e8d8bef9SDimitry Andric llvm::sys::path::append(SysRootDir, "msp430-elf", "lib", MultilibSuf);
1320b57cec5SDimitry Andric addPathIfExists(D, SysRootDir, getFilePaths());
1330b57cec5SDimitry Andric }
1340b57cec5SDimitry Andric
computeSysRoot() const1350b57cec5SDimitry Andric std::string MSP430ToolChain::computeSysRoot() const {
1360b57cec5SDimitry Andric if (!getDriver().SysRoot.empty())
1370b57cec5SDimitry Andric return getDriver().SysRoot;
1380b57cec5SDimitry Andric
1390b57cec5SDimitry Andric SmallString<128> Dir;
1400b57cec5SDimitry Andric if (GCCInstallation.isValid())
141e8d8bef9SDimitry Andric llvm::sys::path::append(Dir, GCCInstallation.getParentLibPath(), "..");
1420b57cec5SDimitry Andric else
143e8d8bef9SDimitry Andric llvm::sys::path::append(Dir, getDriver().Dir, "..");
1440b57cec5SDimitry Andric
1457a6dacacSDimitry Andric return std::string(Dir);
1460b57cec5SDimitry Andric }
1470b57cec5SDimitry Andric
AddClangSystemIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const1480b57cec5SDimitry Andric void MSP430ToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
1490b57cec5SDimitry Andric ArgStringList &CC1Args) const {
1500b57cec5SDimitry Andric if (DriverArgs.hasArg(options::OPT_nostdinc) ||
1510b57cec5SDimitry Andric DriverArgs.hasArg(options::OPT_nostdlibinc))
1520b57cec5SDimitry Andric return;
1530b57cec5SDimitry Andric
1540b57cec5SDimitry Andric SmallString<128> Dir(computeSysRoot());
155e8d8bef9SDimitry Andric llvm::sys::path::append(Dir, "msp430-elf", "include");
1560b57cec5SDimitry Andric addSystemInclude(DriverArgs, CC1Args, Dir.str());
1570b57cec5SDimitry Andric }
1580b57cec5SDimitry Andric
addClangTargetOptions(const ArgList & DriverArgs,ArgStringList & CC1Args,Action::OffloadKind) const1590b57cec5SDimitry Andric void MSP430ToolChain::addClangTargetOptions(const ArgList &DriverArgs,
1600b57cec5SDimitry Andric ArgStringList &CC1Args,
1610b57cec5SDimitry Andric Action::OffloadKind) const {
1620b57cec5SDimitry Andric CC1Args.push_back("-nostdsysteminc");
1630b57cec5SDimitry Andric
1640b57cec5SDimitry Andric const auto *MCUArg = DriverArgs.getLastArg(options::OPT_mmcu_EQ);
1650b57cec5SDimitry Andric if (!MCUArg)
1660b57cec5SDimitry Andric return;
1670b57cec5SDimitry Andric
1680b57cec5SDimitry Andric const StringRef MCU = MCUArg->getValue();
1695f757f3fSDimitry Andric if (MCU.starts_with("msp430i")) {
1700b57cec5SDimitry Andric // 'i' should be in lower case as it's defined in TI MSP430-GCC headers
1710b57cec5SDimitry Andric CC1Args.push_back(DriverArgs.MakeArgString(
1720b57cec5SDimitry Andric "-D__MSP430i" + MCU.drop_front(7).upper() + "__"));
1730b57cec5SDimitry Andric } else {
1740b57cec5SDimitry Andric CC1Args.push_back(DriverArgs.MakeArgString("-D__" + MCU.upper() + "__"));
1750b57cec5SDimitry Andric }
1760b57cec5SDimitry Andric }
1770b57cec5SDimitry Andric
buildLinker() const1780b57cec5SDimitry Andric Tool *MSP430ToolChain::buildLinker() const {
1790b57cec5SDimitry Andric return new tools::msp430::Linker(*this);
1800b57cec5SDimitry Andric }
1810b57cec5SDimitry Andric
AddStartFiles(bool UseExceptions,const ArgList & Args,ArgStringList & CmdArgs) const182e8d8bef9SDimitry Andric void msp430::Linker::AddStartFiles(bool UseExceptions, const ArgList &Args,
183e8d8bef9SDimitry Andric ArgStringList &CmdArgs) const {
184e8d8bef9SDimitry Andric const ToolChain &ToolChain = getToolChain();
185e8d8bef9SDimitry Andric
186e8d8bef9SDimitry Andric CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o")));
187e8d8bef9SDimitry Andric const char *crtbegin = UseExceptions ? "crtbegin.o" : "crtbegin_no_eh.o";
188e8d8bef9SDimitry Andric CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));
189e8d8bef9SDimitry Andric }
190e8d8bef9SDimitry Andric
AddDefaultLibs(const llvm::opt::ArgList & Args,llvm::opt::ArgStringList & CmdArgs) const191e8d8bef9SDimitry Andric void msp430::Linker::AddDefaultLibs(const llvm::opt::ArgList &Args,
192e8d8bef9SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const {
193e8d8bef9SDimitry Andric const ToolChain &ToolChain = getToolChain();
194e8d8bef9SDimitry Andric const Driver &D = ToolChain.getDriver();
195e8d8bef9SDimitry Andric
196e8d8bef9SDimitry Andric CmdArgs.push_back("--start-group");
197e8d8bef9SDimitry Andric CmdArgs.push_back(Args.MakeArgString(getHWMultLib(Args)));
198e8d8bef9SDimitry Andric CmdArgs.push_back("-lc");
199e8d8bef9SDimitry Andric AddRunTimeLibs(ToolChain, D, CmdArgs, Args);
200e8d8bef9SDimitry Andric CmdArgs.push_back("-lcrt");
201e8d8bef9SDimitry Andric
202e8d8bef9SDimitry Andric if (Args.hasArg(options::OPT_msim)) {
203e8d8bef9SDimitry Andric CmdArgs.push_back("-lsim");
204e8d8bef9SDimitry Andric
205e8d8bef9SDimitry Andric // msp430-sim.ld relies on __crt0_call_exit being implicitly .refsym-ed
206e8d8bef9SDimitry Andric // in main() by msp430-gcc.
207e8d8bef9SDimitry Andric // This workaround should work seamlessly unless the compilation unit that
208e8d8bef9SDimitry Andric // contains main() is compiled by clang and then passed to
209e8d8bef9SDimitry Andric // gcc compiler driver for linkage.
210e8d8bef9SDimitry Andric CmdArgs.push_back("--undefined=__crt0_call_exit");
211e8d8bef9SDimitry Andric } else
212e8d8bef9SDimitry Andric CmdArgs.push_back("-lnosys");
213e8d8bef9SDimitry Andric
214e8d8bef9SDimitry Andric CmdArgs.push_back("--end-group");
215e8d8bef9SDimitry Andric AddRunTimeLibs(ToolChain, D, CmdArgs, Args);
216e8d8bef9SDimitry Andric }
217e8d8bef9SDimitry Andric
AddEndFiles(bool UseExceptions,const ArgList & Args,ArgStringList & CmdArgs) const218e8d8bef9SDimitry Andric void msp430::Linker::AddEndFiles(bool UseExceptions, const ArgList &Args,
219e8d8bef9SDimitry Andric ArgStringList &CmdArgs) const {
220e8d8bef9SDimitry Andric const ToolChain &ToolChain = getToolChain();
221e8d8bef9SDimitry Andric const Driver &D = ToolChain.getDriver();
222e8d8bef9SDimitry Andric
223e8d8bef9SDimitry Andric const char *crtend = UseExceptions ? "crtend.o" : "crtend_no_eh.o";
224e8d8bef9SDimitry Andric CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtend)));
225e8d8bef9SDimitry Andric AddRunTimeLibs(ToolChain, D, CmdArgs, Args);
226e8d8bef9SDimitry Andric }
227e8d8bef9SDimitry Andric
AddSspArgs(const ArgList & Args,ArgStringList & CmdArgs)228e8d8bef9SDimitry Andric static void AddSspArgs(const ArgList &Args, ArgStringList &CmdArgs) {
229e8d8bef9SDimitry Andric Arg *SspFlag = Args.getLastArg(
230e8d8bef9SDimitry Andric options::OPT_fno_stack_protector, options::OPT_fstack_protector,
231e8d8bef9SDimitry Andric options::OPT_fstack_protector_all, options::OPT_fstack_protector_strong);
232e8d8bef9SDimitry Andric
233e8d8bef9SDimitry Andric if (SspFlag &&
234e8d8bef9SDimitry Andric !SspFlag->getOption().matches(options::OPT_fno_stack_protector)) {
235e8d8bef9SDimitry Andric CmdArgs.push_back("-lssp_nonshared");
236e8d8bef9SDimitry Andric CmdArgs.push_back("-lssp");
237e8d8bef9SDimitry Andric }
238e8d8bef9SDimitry Andric }
239e8d8bef9SDimitry Andric
AddImplicitLinkerScript(const std::string SysRoot,const ArgList & Args,ArgStringList & CmdArgs)240e8d8bef9SDimitry Andric static void AddImplicitLinkerScript(const std::string SysRoot,
241e8d8bef9SDimitry Andric const ArgList &Args,
242e8d8bef9SDimitry Andric ArgStringList &CmdArgs) {
243e8d8bef9SDimitry Andric if (Args.hasArg(options::OPT_T))
244e8d8bef9SDimitry Andric return;
245e8d8bef9SDimitry Andric
246e8d8bef9SDimitry Andric if (Args.hasArg(options::OPT_msim)) {
247e8d8bef9SDimitry Andric CmdArgs.push_back("-Tmsp430-sim.ld");
248e8d8bef9SDimitry Andric return;
249e8d8bef9SDimitry Andric }
250e8d8bef9SDimitry Andric
251e8d8bef9SDimitry Andric const Arg *MCUArg = Args.getLastArg(options::OPT_mmcu_EQ);
252e8d8bef9SDimitry Andric if (!MCUArg)
253e8d8bef9SDimitry Andric return;
254e8d8bef9SDimitry Andric
255e8d8bef9SDimitry Andric SmallString<128> MCULinkerScriptPath(SysRoot);
256e8d8bef9SDimitry Andric llvm::sys::path::append(MCULinkerScriptPath, "include");
257e8d8bef9SDimitry Andric // -L because <mcu>.ld INCLUDEs <mcu>_symbols.ld
258e8d8bef9SDimitry Andric CmdArgs.push_back(Args.MakeArgString("-L" + MCULinkerScriptPath));
259e8d8bef9SDimitry Andric CmdArgs.push_back(
260e8d8bef9SDimitry Andric Args.MakeArgString("-T" + StringRef(MCUArg->getValue()) + ".ld"));
261e8d8bef9SDimitry Andric }
262e8d8bef9SDimitry Andric
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const2630b57cec5SDimitry Andric void msp430::Linker::ConstructJob(Compilation &C, const JobAction &JA,
2640b57cec5SDimitry Andric const InputInfo &Output,
2650b57cec5SDimitry Andric const InputInfoList &Inputs,
2660b57cec5SDimitry Andric const ArgList &Args,
2670b57cec5SDimitry Andric const char *LinkingOutput) const {
2680b57cec5SDimitry Andric const ToolChain &ToolChain = getToolChain();
2690b57cec5SDimitry Andric const Driver &D = ToolChain.getDriver();
2700b57cec5SDimitry Andric std::string Linker = ToolChain.GetProgramPath(getShortName());
2710b57cec5SDimitry Andric ArgStringList CmdArgs;
272e8d8bef9SDimitry Andric bool UseExceptions = Args.hasFlag(options::OPT_fexceptions,
273e8d8bef9SDimitry Andric options::OPT_fno_exceptions, false);
274e8d8bef9SDimitry Andric bool UseStartAndEndFiles = !Args.hasArg(options::OPT_nostdlib, options::OPT_r,
275e8d8bef9SDimitry Andric options::OPT_nostartfiles);
2760b57cec5SDimitry Andric
277e8d8bef9SDimitry Andric if (Args.hasArg(options::OPT_mrelax))
278e8d8bef9SDimitry Andric CmdArgs.push_back("--relax");
279e8d8bef9SDimitry Andric if (!Args.hasArg(options::OPT_r, options::OPT_g_Group))
280e8d8bef9SDimitry Andric CmdArgs.push_back("--gc-sections");
281e8d8bef9SDimitry Andric
2825f757f3fSDimitry Andric Args.addAllArgs(CmdArgs, {
283e8d8bef9SDimitry Andric options::OPT_n,
284e8d8bef9SDimitry Andric options::OPT_s,
285e8d8bef9SDimitry Andric options::OPT_t,
286e8d8bef9SDimitry Andric options::OPT_u,
287e8d8bef9SDimitry Andric });
288e8d8bef9SDimitry Andric
289e8d8bef9SDimitry Andric if (UseStartAndEndFiles)
290e8d8bef9SDimitry Andric AddStartFiles(UseExceptions, Args, CmdArgs);
2910b57cec5SDimitry Andric
2920b57cec5SDimitry Andric Args.AddAllArgs(CmdArgs, options::OPT_L);
2930b57cec5SDimitry Andric ToolChain.AddFilePathLibArgs(Args, CmdArgs);
2940b57cec5SDimitry Andric AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
2950b57cec5SDimitry Andric
296e8d8bef9SDimitry Andric if (!Args.hasArg(options::OPT_nostdlib, options::OPT_r,
297e8d8bef9SDimitry Andric options::OPT_nodefaultlibs)) {
298e8d8bef9SDimitry Andric AddSspArgs(Args, CmdArgs);
299e8d8bef9SDimitry Andric AddRunTimeLibs(ToolChain, D, CmdArgs, Args);
300e8d8bef9SDimitry Andric if (!Args.hasArg(options::OPT_nolibc)) {
301e8d8bef9SDimitry Andric AddDefaultLibs(Args, CmdArgs);
302e8d8bef9SDimitry Andric AddImplicitLinkerScript(D.SysRoot, Args, CmdArgs);
3030b57cec5SDimitry Andric }
304e8d8bef9SDimitry Andric }
3050b57cec5SDimitry Andric
306e8d8bef9SDimitry Andric if (UseStartAndEndFiles)
307e8d8bef9SDimitry Andric AddEndFiles(UseExceptions, Args, CmdArgs);
308e8d8bef9SDimitry Andric
3090b57cec5SDimitry Andric CmdArgs.push_back("-o");
3100b57cec5SDimitry Andric CmdArgs.push_back(Output.getFilename());
311e8d8bef9SDimitry Andric
312e8d8bef9SDimitry Andric Args.AddAllArgs(CmdArgs, options::OPT_T);
313e8d8bef9SDimitry Andric
314e8d8bef9SDimitry Andric C.addCommand(std::make_unique<Command>(
315e8d8bef9SDimitry Andric JA, *this, ResponseFileSupport::AtFileCurCP(), Args.MakeArgString(Linker),
316e8d8bef9SDimitry Andric CmdArgs, Inputs, Output));
3170b57cec5SDimitry Andric }
318