specified at Command creation, rather than as part of the Tool.
This resolves the hack I just added to allow Darwin toolchain to vary
its level of support based on `-mlinker-version=`.
The change preserves the _current_ settings for response-file support.
Some tools look likely to be declaring that they don't support
response files in error, however I kept them as-is in order for this
change to be a simple refactoring.
Differential Revision: https://reviews.llvm.org/D82782
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator.h"
#include "llvm/Option/Option.h"
+#include "llvm/Support/Program.h"
#include <memory>
#include <string>
#include <utility>
: Filename(Filename), VFSPath(VFSPath) {}
};
+// Encodes the kind of response file supported for a command invocation.
+// Response files are necessary if the command line gets too large, requiring
+// the arguments to be transferred to a file.
+struct ResponseFileSupport {
+ enum ResponseFileKind {
+ // Provides full support for response files, which means we can transfer
+ // all tool input arguments to a file.
+ RF_Full,
+ // Input file names can live in a file, but flags can't. This is a special
+ // case for old versions of Apple's ld64.
+ RF_FileList,
+ // Does not support response files: all arguments must be passed via
+ // command line.
+ RF_None
+ };
+ /// The level of support for response files.
+ ResponseFileKind ResponseKind;
+
+ /// The encoding to use when writing response files on Windows. Ignored on
+ /// other host OSes.
+ ///
+ /// Windows use cases: - GCC and Binutils on mingw only accept ANSI response
+ /// files encoded with the system current code page.
+ /// - MSVC's CL.exe and LINK.exe accept UTF16 on Windows.
+ /// - Clang accepts both UTF8 and UTF16.
+ ///
+ /// FIXME: When GNU tools learn how to parse UTF16 on Windows, we should
+ /// always use UTF16 for Windows, which is the Windows official encoding for
+ /// international characters.
+ llvm::sys::WindowsEncodingMethod ResponseEncoding;
+
+ /// What prefix to use for the command-line argument when passing a response
+ /// file.
+ const char *ResponseFlag;
+
+ /// Returns a ResponseFileSupport indicating that response files are not
+ /// supported.
+ static constexpr ResponseFileSupport None() {
+ return {RF_None, llvm::sys::WEM_UTF8, nullptr};
+ }
+
+ /// Returns a ResponseFileSupport indicating that response files are
+ /// supported, using the @file syntax. On windows, the file is written in the
+ /// UTF8 encoding. On other OSes, no re-encoding occurs.
+ static constexpr ResponseFileSupport AtFileUTF8() {
+ return {RF_Full, llvm::sys::WEM_UTF8, "@"};
+ }
+
+ /// Returns a ResponseFileSupport indicating that response files are
+ /// supported, using the @file syntax. On windows, the file is written in the
+ /// current ANSI code-page encoding. On other OSes, no re-encoding occurs.
+ static constexpr ResponseFileSupport AtFileCurCP() {
+ return {RF_Full, llvm::sys::WEM_CurrentCodePage, "@"};
+ }
+
+ /// Returns a ResponseFileSupport indicating that response files are
+ /// supported, using the @file syntax. On windows, the file is written in the
+ /// UTF-16 encoding. On other OSes, no re-encoding occurs.
+ static constexpr ResponseFileSupport AtFileUTF16() {
+ return {RF_Full, llvm::sys::WEM_UTF16, "@"};
+ }
+};
+
/// Command - An executable path/name and argument vector to
/// execute.
class Command {
/// Tool - The tool which caused the creation of this job.
const Tool &Creator;
+ /// Whether and how to generate response files if the arguments are too long.
+ ResponseFileSupport ResponseSupport;
+
/// The executable to run.
const char *Executable;
/// Whether the command will be executed in this process or not.
bool InProcess = false;
- Command(const Action &Source, const Tool &Creator, const char *Executable,
+ Command(const Action &Source, const Tool &Creator,
+ ResponseFileSupport ResponseSupport, const char *Executable,
const llvm::opt::ArgStringList &Arguments,
ArrayRef<InputInfo> Inputs);
// FIXME: This really shouldn't be copyable, but is currently copied in some
/// getCreator - Return the Tool which caused the creation of this job.
const Tool &getCreator() const { return Creator; }
+ /// Returns the kind of response file supported by the current invocation.
+ const ResponseFileSupport &getResponseFileSupport() {
+ return ResponseSupport;
+ }
+
/// Set to pass arguments via a response file when launching the command
void setResponseFile(const char *FileName);
- /// Set an input file list, necessary if we need to use a response file but
- /// the tool being called only supports input files lists.
+ /// Set an input file list, necessary if you specified an RF_FileList response
+ /// file support.
void setInputFileList(llvm::opt::ArgStringList List) {
InputFileList = std::move(List);
}
/// Use the CC1 tool callback when available, to avoid creating a new process
class CC1Command : public Command {
public:
- CC1Command(const Action &Source, const Tool &Creator, const char *Executable,
+ CC1Command(const Action &Source, const Tool &Creator,
+ ResponseFileSupport ResponseSupport, const char *Executable,
const llvm::opt::ArgStringList &Arguments,
ArrayRef<InputInfo> Inputs);
class FallbackCommand : public Command {
public:
FallbackCommand(const Action &Source_, const Tool &Creator_,
- const char *Executable_,
+ ResponseFileSupport ResponseSupport, const char *Executable_,
const llvm::opt::ArgStringList &Arguments_,
ArrayRef<InputInfo> Inputs,
std::unique_ptr<Command> Fallback_);
class ForceSuccessCommand : public Command {
public:
ForceSuccessCommand(const Action &Source_, const Tool &Creator_,
+ ResponseFileSupport ResponseSupport,
const char *Executable_,
const llvm::opt::ArgStringList &Arguments_,
ArrayRef<InputInfo> Inputs);
#define LLVM_CLANG_DRIVER_TOOL_H
#include "clang/Basic/LLVM.h"
-#include "llvm/Support/Program.h"
namespace llvm {
namespace opt {
/// Tool - Information on a specific compilation tool.
class Tool {
-public:
- // Documents the level of support for response files in this tool.
- // Response files are necessary if the command line gets too large,
- // requiring the arguments to be transferred to a file.
- enum ResponseFileSupport {
- // Provides full support for response files, which means we can transfer
- // all tool input arguments to a file. E.g.: clang, gcc, binutils and MSVC
- // tools.
- RF_Full,
- // Input file names can live in a file, but flags can't. E.g.: ld64 (Mac
- // OS X linker).
- RF_FileList,
- // Does not support response files: all arguments must be passed via
- // command line.
- RF_None
- };
-
-private:
/// The tool name (for debugging).
const char *Name;
/// The tool chain this tool is a part of.
const ToolChain &TheToolChain;
- /// The level of support for response files seen in this tool
- const ResponseFileSupport ResponseSupport;
-
- /// The encoding to use when writing response files for this tool on Windows
- const llvm::sys::WindowsEncodingMethod ResponseEncoding;
-
- /// The flag used to pass a response file via command line to this tool
- const char *const ResponseFlag;
-
public:
- Tool(const char *Name, const char *ShortName, const ToolChain &TC,
- ResponseFileSupport ResponseSupport = RF_None,
- llvm::sys::WindowsEncodingMethod ResponseEncoding = llvm::sys::WEM_UTF8,
- const char *ResponseFlag = "@");
+ Tool(const char *Name, const char *ShortName, const ToolChain &TC);
public:
virtual ~Tool();
virtual bool hasIntegratedCPP() const = 0;
virtual bool isLinkJob() const { return false; }
virtual bool isDsymutilJob() const { return false; }
- /// Returns the level of support for response files of this tool,
- /// whether it accepts arguments to be passed via a file on disk.
- ResponseFileSupport getResponseFilesSupport() const {
- return ResponseSupport;
- }
- /// Returns which encoding the response file should use. This is only
- /// relevant on Windows platforms where there are different encodings being
- /// accepted for different tools. On UNIX, UTF8 is universal.
- ///
- /// Windows use cases: - GCC and Binutils on mingw only accept ANSI response
- /// files encoded with the system current code page.
- /// - MSVC's CL.exe and LINK.exe accept UTF16 on Windows.
- /// - Clang accepts both UTF8 and UTF16.
- ///
- /// FIXME: When GNU tools learn how to parse UTF16 on Windows, we should
- /// always use UTF16 for Windows, which is the Windows official encoding for
- /// international characters.
- llvm::sys::WindowsEncodingMethod getResponseFileEncoding() const {
- return ResponseEncoding;
- }
- /// Returns which prefix to use when passing the name of a response
- /// file as a parameter to this tool.
- const char *getResponseFileFlag() const { return ResponseFlag; }
/// Does this tool have "good" standardized diagnostics, or should the
/// driver add an additional "command failed" diagnostic on failures.
// Accessors
- /// Temporary for Darwin::Linker
- const llvm::opt::ArgList &getArgs_DO_NOT_USE() const { return Args; }
-
const Driver &getDriver() const { return D; }
llvm::vfs::FileSystem &getVFS() const;
const llvm::Triple &getTriple() const { return Triple; }
// capacity if the tool does not support response files, there is a chance/
// that things will just work without a response file, so we silently just
// skip it.
- if (Cmd.getCreator().getResponseFilesSupport() == Tool::RF_None ||
+ if (Cmd.getResponseFileSupport().ResponseKind ==
+ ResponseFileSupport::RF_None ||
llvm::sys::commandLineFitsWithinSystemLimits(Cmd.getExecutable(),
Cmd.getArguments()))
return;
using namespace driver;
Command::Command(const Action &Source, const Tool &Creator,
- const char *Executable,
+ ResponseFileSupport ResponseSupport, const char *Executable,
const llvm::opt::ArgStringList &Arguments,
ArrayRef<InputInfo> Inputs)
- : Source(Source), Creator(Creator), Executable(Executable),
- Arguments(Arguments) {
+ : Source(Source), Creator(Creator), ResponseSupport(ResponseSupport),
+ Executable(Executable), Arguments(Arguments) {
for (const auto &II : Inputs)
if (II.isFilename())
InputFilenames.push_back(II.getFilename());
void Command::writeResponseFile(raw_ostream &OS) const {
// In a file list, we only write the set of inputs to the response file
- if (Creator.getResponseFilesSupport() == Tool::RF_FileList) {
+ if (ResponseSupport.ResponseKind == ResponseFileSupport::RF_FileList) {
for (const auto *Arg : InputFileList) {
OS << Arg << '\n';
}
// When not a file list, all arguments are sent to the response file.
// This leaves us to set the argv to a single parameter, requesting the tool
// to read the response file.
- if (Creator.getResponseFilesSupport() != Tool::RF_FileList) {
+ if (ResponseSupport.ResponseKind != ResponseFileSupport::RF_FileList) {
Out.push_back(Executable);
Out.push_back(ResponseFileFlag.c_str());
return;
Out.push_back(Arg);
} else if (FirstInput) {
FirstInput = false;
- Out.push_back(Creator.getResponseFileFlag());
+ Out.push_back(ResponseSupport.ResponseFlag);
Out.push_back(ResponseFile);
}
}
writeResponseFile(OS);
// Avoiding duplicated newline terminator, since FileLists are
// newline-separated.
- if (Creator.getResponseFilesSupport() != Tool::RF_FileList)
+ if (ResponseSupport.ResponseKind != ResponseFileSupport::RF_FileList)
OS << "\n";
OS << " (end of response file)";
}
void Command::setResponseFile(const char *FileName) {
ResponseFile = FileName;
- ResponseFileFlag = Creator.getResponseFileFlag();
+ ResponseFileFlag = ResponseSupport.ResponseFlag;
ResponseFileFlag += FileName;
}
// Save the response file in the appropriate encoding
if (std::error_code EC = writeFileWithEncoding(
- ResponseFile, RespContents, Creator.getResponseFileEncoding())) {
+ ResponseFile, RespContents, ResponseSupport.ResponseEncoding)) {
if (ErrMsg)
*ErrMsg = EC.message();
if (ExecutionFailed)
}
CC1Command::CC1Command(const Action &Source, const Tool &Creator,
+ ResponseFileSupport ResponseSupport,
const char *Executable,
const llvm::opt::ArgStringList &Arguments,
ArrayRef<InputInfo> Inputs)
- : Command(Source, Creator, Executable, Arguments, Inputs) {
+ : Command(Source, Creator, ResponseSupport, Executable, Arguments, Inputs) {
InProcess = true;
}
}
FallbackCommand::FallbackCommand(const Action &Source_, const Tool &Creator_,
+ ResponseFileSupport ResponseSupport,
const char *Executable_,
const llvm::opt::ArgStringList &Arguments_,
ArrayRef<InputInfo> Inputs,
std::unique_ptr<Command> Fallback_)
- : Command(Source_, Creator_, Executable_, Arguments_, Inputs),
+ : Command(Source_, Creator_, ResponseSupport, Executable_, Arguments_,
+ Inputs),
Fallback(std::move(Fallback_)) {}
void FallbackCommand::Print(raw_ostream &OS, const char *Terminator,
}
ForceSuccessCommand::ForceSuccessCommand(
- const Action &Source_, const Tool &Creator_, const char *Executable_,
+ const Action &Source_, const Tool &Creator_,
+ ResponseFileSupport ResponseSupport, const char *Executable_,
const llvm::opt::ArgStringList &Arguments_, ArrayRef<InputInfo> Inputs)
- : Command(Source_, Creator_, Executable_, Arguments_, Inputs) {}
+ : Command(Source_, Creator_, ResponseSupport, Executable_, Arguments_,
+ Inputs) {}
void ForceSuccessCommand::Print(raw_ostream &OS, const char *Terminator,
bool Quote, CrashReportInfo *CrashInfo) const {
using namespace clang::driver;
-Tool::Tool(const char *_Name, const char *_ShortName, const ToolChain &TC,
- ResponseFileSupport _ResponseSupport,
- llvm::sys::WindowsEncodingMethod _ResponseEncoding,
- const char *_ResponseFlag)
- : Name(_Name), ShortName(_ShortName), TheToolChain(TC),
- ResponseSupport(_ResponseSupport), ResponseEncoding(_ResponseEncoding),
- ResponseFlag(_ResponseFlag) {}
+Tool::Tool(const char *_Name, const char *_ShortName, const ToolChain &TC)
+ : Name(_Name), ShortName(_ShortName), TheToolChain(TC) {}
Tool::~Tool() {
}
CmdArgs.push_back(II.getFilename());
const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
+ Exec, CmdArgs, Inputs));
}
void aix::Linker::ConstructJob(Compilation &C, const JobAction &JA,
}
const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
+ Exec, CmdArgs, Inputs));
}
/// AIX - AIX tool chain which can call as(1) and ld(1) directly.
CmdArgs.push_back("-shared");
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());
- C.addCommand(std::make_unique<Command>(JA, *this, Args.MakeArgString(Linker),
- CmdArgs, Inputs));
+ C.addCommand(
+ std::make_unique<Command>(JA, *this, ResponseFileSupport::AtFileCurCP(),
+ Args.MakeArgString(Linker), CmdArgs, Inputs));
}
void amdgpu::getAMDGPUTargetFeatures(const Driver &D,
namespace tools {
namespace amdgpu {
-class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
+class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
public:
- Linker(const ToolChain &TC) : GnuTool("amdgpu::Linker", "ld.lld", TC) {}
+ Linker(const ToolChain &TC) : Tool("amdgpu::Linker", "ld.lld", TC) {}
bool isLinkJob() const override { return true; }
bool hasIntegratedCPP() const override { return false; }
void ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(Args.MakeArgString(std::string("-m") + *FamilyName));
}
- C.addCommand(std::make_unique<Command>(JA, *this, Args.MakeArgString(Linker),
- CmdArgs, Inputs));
+ C.addCommand(
+ std::make_unique<Command>(JA, *this, ResponseFileSupport::AtFileCurCP(),
+ Args.MakeArgString(Linker), CmdArgs, Inputs));
}
llvm::Optional<std::string> AVRToolChain::findAVRLibcInstallation() const {
namespace tools {
namespace AVR {
-class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
+class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
public:
Linker(const llvm::Triple &Triple, const ToolChain &TC, bool LinkStdlib)
- : GnuTool("AVR::Linker", "avr-ld", TC), Triple(Triple),
+ : Tool("AVR::Linker", "avr-ld", TC), Triple(Triple),
LinkStdlib(LinkStdlib) {}
bool hasIntegratedCPP() const override { return false; }
CmdArgs.push_back(II.getFilename());
const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(
+ JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs));
}
void ananas::Linker::ConstructJob(Compilation &C, const JobAction &JA,
}
const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(
+ JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs));
}
// Ananas - Ananas tool chain which can call as(1) and ld(1) directly.
/// ananas -- Directly call GNU Binutils assembler and linker
namespace ananas {
-class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool {
+class LLVM_LIBRARY_VISIBILITY Assembler : public Tool {
public:
- Assembler(const ToolChain &TC)
- : GnuTool("ananas::Assembler", "assembler", TC) {}
+ Assembler(const ToolChain &TC) : Tool("ananas::Assembler", "assembler", TC) {}
bool hasIntegratedCPP() const override { return false; }
const char *LinkingOutput) const override;
};
-class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
+class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
public:
- Linker(const ToolChain &TC) : GnuTool("ananas::Linker", "linker", TC) {}
+ Linker(const ToolChain &TC) : Tool("ananas::Linker", "linker", TC) {}
bool hasIntegratedCPP() const override { return false; }
bool isLinkJob() const override { return true; }
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());
- C.addCommand(std::make_unique<Command>(JA, *this,
- Args.MakeArgString(TC.GetLinkerPath()),
- CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
+ Args.MakeArgString(TC.GetLinkerPath()),
+ CmdArgs, Inputs));
}
II.getInputArg().renderAsInput(Args, CmdArgs);
}
- C.addCommand(std::make_unique<Command>(JA, *this, D.getClangProgramPath(),
- CmdArgs, Inputs));
+ C.addCommand(
+ std::make_unique<Command>(JA, *this, ResponseFileSupport::AtFileUTF8(),
+ D.getClangProgramPath(), CmdArgs, Inputs));
return;
}
auto CLCommand =
getCLFallback()->GetCommand(C, JA, Output, Inputs, Args, LinkingOutput);
C.addCommand(std::make_unique<FallbackCommand>(
- JA, *this, Exec, CmdArgs, Inputs, std::move(CLCommand)));
+ JA, *this, ResponseFileSupport::AtFileUTF8(), Exec, CmdArgs, Inputs,
+ std::move(CLCommand)));
} else if (Args.hasArg(options::OPT__SLASH_fallback) &&
isa<PrecompileJobAction>(JA)) {
// In /fallback builds, run the main compilation even if the pch generation
// fails, so that the main compilation's fallback to cl.exe runs.
- C.addCommand(std::make_unique<ForceSuccessCommand>(JA, *this, Exec,
- CmdArgs, Inputs));
+ C.addCommand(std::make_unique<ForceSuccessCommand>(
+ JA, *this, ResponseFileSupport::AtFileUTF8(), Exec, CmdArgs, Inputs));
} else if (D.CC1Main && !D.CCGenDiagnostics) {
// Invoke the CC1 directly in this process
- C.addCommand(
- std::make_unique<CC1Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<CC1Command>(
+ JA, *this, ResponseFileSupport::AtFileUTF8(), Exec, CmdArgs, Inputs));
} else {
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(
+ JA, *this, ResponseFileSupport::AtFileUTF8(), Exec, CmdArgs, Inputs));
}
// Make the compile command echo its inputs for /showFilenames.
// CAUTION! The first constructor argument ("clang") is not arbitrary,
// as it is for other tools. Some operations on a Tool actually test
// whether that tool is Clang based on the Tool's Name as a string.
- : Tool("clang", "clang frontend", TC, RF_Full) {}
+ : Tool("clang", "clang frontend", TC) {}
Clang::~Clang() {}
CmdArgs.push_back(Input.getFilename());
const char *Exec = getToolChain().getDriver().getClangProgramPath();
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(
+ JA, *this, ResponseFileSupport::AtFileUTF8(), Exec, CmdArgs, Inputs));
}
// Begin OffloadBundler
// All the inputs are encoded as commands.
C.addCommand(std::make_unique<Command>(
- JA, *this,
+ JA, *this, ResponseFileSupport::None(),
TCArgs.MakeArgString(getToolChain().GetProgramPath(getShortName())),
CmdArgs, None));
}
// All the inputs are encoded as commands.
C.addCommand(std::make_unique<Command>(
- JA, *this,
+ JA, *this, ResponseFileSupport::None(),
TCArgs.MakeArgString(getToolChain().GetProgramPath(getShortName())),
CmdArgs, None));
}
}
C.addCommand(std::make_unique<Command>(
- JA, *this,
+ JA, *this, ResponseFileSupport::None(),
Args.MakeArgString(getToolChain().GetProgramPath(getShortName())),
CmdArgs, Inputs));
}
class LLVM_LIBRARY_VISIBILITY ClangAs : public Tool {
public:
ClangAs(const ToolChain &TC)
- : Tool("clang::as", "clang integrated assembler", TC, RF_Full) {}
+ : Tool("clang::as", "clang integrated assembler", TC) {}
void AddMIPSTargetArgs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const;
void AddX86TargetArgs(const llvm::opt::ArgList &Args,
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o")));
const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(
+ JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs));
}
// CloudABI - CloudABI tool chain which can call ld(1) directly.
/// cloudabi -- Directly call GNU Binutils linker
namespace cloudabi {
-class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
+class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
public:
- Linker(const ToolChain &TC) : GnuTool("cloudabi::Linker", "linker", TC) {}
+ Linker(const ToolChain &TC) : Tool("cloudabi::Linker", "linker", TC) {}
bool hasIntegratedCPP() const override { return false; }
bool isLinkJob() const override { return true; }
InputInfo II(types::TY_Object, Output.getFilename(), Output.getFilename());
// First extract the dwo sections.
- C.addCommand(std::make_unique<Command>(JA, T, Exec, ExtractArgs, II));
+ C.addCommand(std::make_unique<Command>(
+ JA, T, ResponseFileSupport::AtFileCurCP(), Exec, ExtractArgs, II));
// Then remove them from the original .o file.
- C.addCommand(std::make_unique<Command>(JA, T, Exec, StripArgs, II));
+ C.addCommand(std::make_unique<Command>(
+ JA, T, ResponseFileSupport::AtFileCurCP(), Exec, StripArgs, II));
}
// Claim options we don't want to warn if they are unused. We do this for
const std::string Assembler = TC.GetProgramPath("as");
Exec = Args.MakeArgString(Assembler);
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
+ Exec, CmdArgs, Inputs));
}
void tools::CrossWindows::Linker::ConstructJob(
Exec = Args.MakeArgString(TC.GetLinkerPath());
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(
+ JA, *this, ResponseFileSupport::AtFileUTF8(), Exec, CmdArgs, Inputs));
}
CrossWindowsToolChain::CrossWindowsToolChain(const Driver &D,
class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
public:
- Linker(const ToolChain &TC)
- : Tool("CrossWindows::Linker", "ld", TC, RF_Full) {}
+ Linker(const ToolChain &TC) : Tool("CrossWindows::Linker", "ld", TC) {}
bool hasIntegratedCPP() const override { return false; }
bool isLinkJob() const override { return true; }
Exec = A->getValue();
else
Exec = Args.MakeArgString(TC.GetProgramPath("ptxas"));
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(
+ JA, *this,
+ ResponseFileSupport{ResponseFileSupport::RF_Full, llvm::sys::WEM_UTF8,
+ "--options-file"},
+ Exec, CmdArgs, Inputs));
}
static bool shouldIncludePTX(const ArgList &Args, const char *gpu_arch) {
CmdArgs.push_back(Args.MakeArgString(A));
const char *Exec = Args.MakeArgString(TC.GetProgramPath("fatbinary"));
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(
+ JA, *this,
+ ResponseFileSupport{ResponseFileSupport::RF_Full, llvm::sys::WEM_UTF8,
+ "--options-file"},
+ Exec, CmdArgs, Inputs));
}
void NVPTX::OpenMPLinker::ConstructJob(Compilation &C, const JobAction &JA,
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath("nvlink"));
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(
+ JA, *this,
+ ResponseFileSupport{ResponseFileSupport::RF_Full, llvm::sys::WEM_UTF8,
+ "--options-file"},
+ Exec, CmdArgs, Inputs));
}
/// CUDA toolchain. Our assembler is ptxas, and our "linker" is fatbinary,
// Run ptxas, the NVPTX assembler.
class LLVM_LIBRARY_VISIBILITY Assembler : public Tool {
public:
- Assembler(const ToolChain &TC)
- : Tool("NVPTX::Assembler", "ptxas", TC, RF_Full, llvm::sys::WEM_UTF8,
- "--options-file") {}
+ Assembler(const ToolChain &TC) : Tool("NVPTX::Assembler", "ptxas", TC) {}
bool hasIntegratedCPP() const override { return false; }
// assembly into a single output file.
class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
public:
- Linker(const ToolChain &TC)
- : Tool("NVPTX::Linker", "fatbinary", TC, RF_Full, llvm::sys::WEM_UTF8,
- "--options-file") {}
+ Linker(const ToolChain &TC) : Tool("NVPTX::Linker", "fatbinary", TC) {}
bool hasIntegratedCPP() const override { return false; }
class LLVM_LIBRARY_VISIBILITY OpenMPLinker : public Tool {
public:
OpenMPLinker(const ToolChain &TC)
- : Tool("NVPTX::OpenMPLinker", "nvlink", TC, RF_Full, llvm::sys::WEM_UTF8,
- "--options-file") {}
+ : Tool("NVPTX::OpenMPLinker", "nvlink", TC) {}
bool hasIntegratedCPP() const override { return false; }
// asm_final spec is empty.
const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
+ Exec, CmdArgs, Inputs));
}
void darwin::MachOTool::anchor() {}
void darwin::Linker::AddLinkArgs(Compilation &C, const ArgList &Args,
ArgStringList &CmdArgs,
- const InputInfoList &Inputs) const {
+ const InputInfoList &Inputs,
+ unsigned Version[5]) const {
const Driver &D = getToolChain().getDriver();
const toolchains::MachO &MachOTC = getMachOToolChain();
- unsigned Version[5] = {0, 0, 0, 0, 0};
- if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) {
- if (!Driver::GetReleaseVersion(A->getValue(), Version))
- D.Diag(diag::err_drv_invalid_version_number) << A->getAsString(Args);
- }
-
// Newer linkers support -demangle. Pass it if supported and not disabled by
// the user.
if (Version[0] >= 100 && !Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath("touch"));
CmdArgs.push_back(Output.getFilename());
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, None));
+ C.addCommand(std::make_unique<Command>(
+ JA, *this, ResponseFileSupport::None(), Exec, CmdArgs, None));
return;
}
+ unsigned Version[5] = {0, 0, 0, 0, 0};
+ if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) {
+ if (!Driver::GetReleaseVersion(A->getValue(), Version))
+ getToolChain().getDriver().Diag(diag::err_drv_invalid_version_number)
+ << A->getAsString(Args);
+ }
+
// I'm not sure why this particular decomposition exists in gcc, but
// we follow suite for ease of comparison.
- AddLinkArgs(C, Args, CmdArgs, Inputs);
+ AddLinkArgs(C, Args, CmdArgs, Inputs, Version);
if (willEmitRemarks(Args) &&
checkRemarksOptions(getToolChain().getDriver(), Args,
}
}
+ ResponseFileSupport ResponseSupport = ResponseFileSupport::AtFileUTF8();
+ if (Version[0] < 607) {
+ // For older versions of the linker, use the legacy filelist method instead.
+ ResponseSupport = {ResponseFileSupport::RF_FileList, llvm::sys::WEM_UTF8,
+ "-filelist"};
+ }
+
const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
- std::unique_ptr<Command> Cmd =
- std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs);
+ std::unique_ptr<Command> Cmd = std::make_unique<Command>(
+ JA, *this, ResponseSupport, Exec, CmdArgs, Inputs);
Cmd->setInputFileList(std::move(InputFileList));
C.addCommand(std::move(Cmd));
}
}
const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("lipo"));
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
+ Exec, CmdArgs, Inputs));
}
void darwin::Dsymutil::ConstructJob(Compilation &C, const JobAction &JA,
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath("dsymutil"));
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
+ Exec, CmdArgs, Inputs));
}
void darwin::VerifyDebug::ConstructJob(Compilation &C, const JobAction &JA,
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath("dwarfdump"));
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
+ Exec, CmdArgs, Inputs));
}
MachO::MachO(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
}
}
-Tool *MachO::buildLinker() const {
- // Determine whether to use an @responsefile or the old -filelist mechanism.
- bool UseAtFile = false;
- unsigned Version[5] = {0, 0, 0, 0, 0};
- if (Arg *A =
- getArgs_DO_NOT_USE().getLastArg(options::OPT_mlinker_version_EQ)) {
- // We don't need to diagnose a parse error here, it'll be caught in
- // ConstructJob.
- if (Driver::GetReleaseVersion(A->getValue(), Version)) {
- if (Version[0] >= 607)
- UseAtFile = true;
- }
- }
-
- return new tools::darwin::Linker(*this, UseAtFile);
-}
+Tool *MachO::buildLinker() const { return new tools::darwin::Linker(*this); }
Tool *MachO::buildAssembler() const {
return new tools::darwin::Assembler(*this);
}
public:
- MachOTool(
- const char *Name, const char *ShortName, const ToolChain &TC,
- ResponseFileSupport ResponseSupport = RF_None,
- llvm::sys::WindowsEncodingMethod ResponseEncoding = llvm::sys::WEM_UTF8,
- const char *ResponseFlag = "@")
- : Tool(Name, ShortName, TC, ResponseSupport, ResponseEncoding,
- ResponseFlag) {}
+ MachOTool(const char *Name, const char *ShortName, const ToolChain &TC)
+ : Tool(Name, ShortName, TC) {}
};
class LLVM_LIBRARY_VISIBILITY Assembler : public MachOTool {
bool NeedsTempPath(const InputInfoList &Inputs) const;
void AddLinkArgs(Compilation &C, const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs,
- const InputInfoList &Inputs) const;
+ const InputInfoList &Inputs, unsigned Version[5]) const;
public:
- Linker(const ToolChain &TC, bool UseAtFile)
- : MachOTool("darwin::Linker", "linker", TC,
- UseAtFile ? RF_Full : RF_FileList, llvm::sys::WEM_UTF8,
- UseAtFile ? "@" : "-filelist") {}
+ Linker(const ToolChain &TC) : MachOTool("darwin::Linker", "linker", TC) {}
bool hasIntegratedCPP() const override { return false; }
bool isLinkJob() const override { return true; }
CmdArgs.push_back(II.getFilename());
const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(
+ JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs));
}
void dragonfly::Linker::ConstructJob(Compilation &C, const JobAction &JA,
getToolChain().addProfileRTLibs(Args, CmdArgs);
const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(
+ JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs));
}
/// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly.
namespace tools {
/// dragonfly -- Directly call GNU Binutils assembler and linker
namespace dragonfly {
-class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool {
+class LLVM_LIBRARY_VISIBILITY Assembler : public Tool {
public:
Assembler(const ToolChain &TC)
- : GnuTool("dragonfly::Assembler", "assembler", TC) {}
+ : Tool("dragonfly::Assembler", "assembler", TC) {}
bool hasIntegratedCPP() const override { return false; }
const char *LinkingOutput) const override;
};
-class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
+class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
public:
- Linker(const ToolChain &TC) : GnuTool("dragonfly::Linker", "linker", TC) {}
+ Linker(const ToolChain &TC) : Tool("dragonfly::Linker", "linker", TC) {}
bool hasIntegratedCPP() const override { return false; }
bool isLinkJob() const override { return true; }
const auto& D = C.getDriver();
const char* Exec = Args.MakeArgString(D.GetProgramPath("flang", TC));
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(
+ JA, *this, ResponseFileSupport::AtFileUTF8(), Exec, CmdArgs, Inputs));
}
-Flang::Flang(const ToolChain &TC)
- : Tool("flang", "flang frontend", TC, RF_Full) {}
+Flang::Flang(const ToolChain &TC) : Tool("flang", "flang frontend", TC) {}
Flang::~Flang() {}
CmdArgs.push_back(II.getFilename());
const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(
+ JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs));
}
void freebsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
ToolChain.addProfileRTLibs(Args, CmdArgs);
const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(
+ JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs));
}
/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
/// freebsd -- Directly call GNU Binutils assembler and linker
namespace freebsd {
-class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool {
+class LLVM_LIBRARY_VISIBILITY Assembler : public Tool {
public:
Assembler(const ToolChain &TC)
- : GnuTool("freebsd::Assembler", "assembler", TC) {}
+ : Tool("freebsd::Assembler", "assembler", TC) {}
bool hasIntegratedCPP() const override { return false; }
const char *LinkingOutput) const override;
};
-class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
+class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
public:
- Linker(const ToolChain &TC) : GnuTool("freebsd::Linker", "linker", TC) {}
+ Linker(const ToolChain &TC) : Tool("freebsd::Linker", "linker", TC) {}
bool hasIntegratedCPP() const override { return false; }
bool isLinkJob() const override { return true; }
CmdArgs.push_back("-lc");
}
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
+ Exec, CmdArgs, Inputs));
}
/// Fuchsia - Fuchsia tool chain which can call as(1) and ld(1) directly.
using tools::addMultilibFlag;
using tools::addPathIfExists;
-void tools::GnuTool::anchor() {}
-
static bool forwardToGCC(const Option &O) {
// Don't forward inputs from the original command line. They are added from
// InputInfoList.
GCCName = "gcc";
const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath(GCCName));
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(
+ JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs));
}
void tools::gcc::Preprocessor::RenderExtraToolArgs(
}
const char *Exec = Args.MakeArgString(getToolChain().GetStaticLibToolPath());
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(
+ JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs));
}
void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddAllArgs(CmdArgs, options::OPT_T);
const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(
+ JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs));
}
void tools::gnutools::Assembler::ConstructJob(Compilation &C,
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(DefaultAssembler));
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(
+ JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs));
// Handle the debug info splitting at object creation time if we're
// creating an object.
namespace tools {
-/// Base class for all GNU tools that provide the same behavior when
-/// it comes to response files support
-class LLVM_LIBRARY_VISIBILITY GnuTool : public Tool {
- virtual void anchor();
-
-public:
- GnuTool(const char *Name, const char *ShortName, const ToolChain &TC)
- : Tool(Name, ShortName, TC, RF_Full, llvm::sys::WEM_CurrentCodePage) {}
-};
-
/// Directly call GNU Binutils' assembler and linker.
namespace gnutools {
-class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool {
+class LLVM_LIBRARY_VISIBILITY Assembler : public Tool {
public:
- Assembler(const ToolChain &TC) : GnuTool("GNU::Assembler", "assembler", TC) {}
+ Assembler(const ToolChain &TC) : Tool("GNU::Assembler", "assembler", TC) {}
bool hasIntegratedCPP() const override { return false; }
const char *LinkingOutput) const override;
};
-class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
+class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
public:
- Linker(const ToolChain &TC) : GnuTool("GNU::Linker", "linker", TC) {}
+ Linker(const ToolChain &TC) : Tool("GNU::Linker", "linker", TC) {}
bool hasIntegratedCPP() const override { return false; }
bool isLinkJob() const override { return true; }
const char *LinkingOutput) const override;
};
-class LLVM_LIBRARY_VISIBILITY StaticLibTool : public GnuTool {
+class LLVM_LIBRARY_VISIBILITY StaticLibTool : public Tool {
public:
StaticLibTool(const ToolChain &TC)
- : GnuTool("GNU::StaticLibTool", "static-lib-linker", TC) {}
+ : Tool("GNU::StaticLibTool", "static-lib-linker", TC) {}
bool hasIntegratedCPP() const override { return false; }
bool isLinkJob() const override { return true; }
/// gcc - Generic GCC tool implementations.
namespace gcc {
-class LLVM_LIBRARY_VISIBILITY Common : public GnuTool {
+class LLVM_LIBRARY_VISIBILITY Common : public Tool {
public:
Common(const char *Name, const char *ShortName, const ToolChain &TC)
- : GnuTool(Name, ShortName, TC) {}
+ : Tool(Name, ShortName, TC) {}
// A gcc tool has an "integrated" assembler that it will call to produce an
// object. Let it use that assembler so that we don't have to deal with
for (auto Input : Inputs)
LldArgs.push_back(Input.getFilename());
const char *Lld = Args.MakeArgString(getToolChain().GetProgramPath("lld"));
- C.addCommand(std::make_unique<Command>(JA, *this, Lld, LldArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
+ Lld, LldArgs, Inputs));
}
// Construct a clang-offload-bundler command to bundle code objects for
const char *Bundler = Args.MakeArgString(
T.getToolChain().GetProgramPath("clang-offload-bundler"));
- C.addCommand(std::make_unique<Command>(JA, T, Bundler, BundlerArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(JA, T, ResponseFileSupport::None(),
+ Bundler, BundlerArgs, Inputs));
}
/// Add Generated HIP Object File which has device images embedded into the
"-o", Output.getFilename(),
McinFile, "--filetype=obj"};
const char *Mc = Args.MakeArgString(TC.GetProgramPath("llvm-mc"));
- C.addCommand(std::make_unique<Command>(JA, *this, Mc, McArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
+ Mc, McArgs, Inputs));
}
// For amdgcn the inputs of the linker job are device bitcode and output is
}
auto *Exec = Args.MakeArgString(HTC.GetProgramPath(AsName));
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(
+ JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs));
}
void hexagon::Linker::RenderExtraToolArgs(const JobAction &JA,
LinkingOutput);
const char *Exec = Args.MakeArgString(HTC.GetLinkerPath());
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(
+ JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs));
}
// Hexagon tools end.
// For Hexagon, we do not need to instantiate tools for PreProcess, PreCompile
// and Compile.
// We simply use "clang -cc1" for those actions.
-class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool {
+class LLVM_LIBRARY_VISIBILITY Assembler : public Tool {
public:
Assembler(const ToolChain &TC)
- : GnuTool("hexagon::Assembler", "hexagon-as", TC) {}
+ : Tool("hexagon::Assembler", "hexagon-as", TC) {}
bool hasIntegratedCPP() const override { return false; }
const char *LinkingOutput) const override;
};
-class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
+class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
public:
- Linker(const ToolChain &TC) : GnuTool("hexagon::Linker", "hexagon-ld", TC) {}
+ Linker(const ToolChain &TC) : Tool("hexagon::Linker", "hexagon-ld", TC) {}
bool hasIntegratedCPP() const override { return false; }
bool isLinkJob() const override { return true; }
CmdArgs.push_back(Args.MakeArgString(InputFilename.c_str()));
}
- C.addCommand(std::make_unique<Command>(JA, *this, Args.MakeArgString(Merger),
- CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
+ Args.MakeArgString(Merger), CmdArgs,
+ Inputs));
}
} // namespace ifstool
} // namespace tools
}
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());
- C.addCommand(std::make_unique<Command>(JA, *this, Args.MakeArgString(Linker),
- CmdArgs, Inputs));
+ C.addCommand(
+ std::make_unique<Command>(JA, *this, ResponseFileSupport::AtFileCurCP(),
+ Args.MakeArgString(Linker), CmdArgs, Inputs));
}
namespace tools {
namespace msp430 {
-class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
+class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
public:
- Linker(const ToolChain &TC)
- : GnuTool("MSP430::Linker", "msp430-elf-ld", TC) {}
+ Linker(const ToolChain &TC) : Tool("MSP430::Linker", "msp430-elf-ld", TC) {}
bool hasIntegratedCPP() const override { return false; }
bool isLinkJob() const override { return true; }
void ConstructJob(Compilation &C, const JobAction &JA,
linkPath = TC.GetProgramPath(Linker.str().c_str());
}
- auto LinkCmd = std::make_unique<Command>(
- JA, *this, Args.MakeArgString(linkPath), CmdArgs, Inputs);
+ auto LinkCmd =
+ std::make_unique<Command>(JA, *this, ResponseFileSupport::AtFileUTF16(),
+ Args.MakeArgString(linkPath), CmdArgs, Inputs);
if (!Environment.empty())
LinkCmd->setEnvironment(Environment);
C.addCommand(std::move(LinkCmd));
CmdArgs.push_back(Fo);
std::string Exec = FindVisualStudioExecutable(getToolChain(), "cl.exe");
- return std::make_unique<Command>(JA, *this, Args.MakeArgString(Exec),
- CmdArgs, Inputs);
+ return std::make_unique<Command>(JA, *this,
+ ResponseFileSupport::AtFileUTF16(),
+ Args.MakeArgString(Exec), CmdArgs, Inputs);
}
MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple &Triple,
namespace visualstudio {
class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
public:
- Linker(const ToolChain &TC)
- : Tool("visualstudio::Linker", "linker", TC, RF_Full,
- llvm::sys::WEM_UTF16) {}
+ Linker(const ToolChain &TC) : Tool("visualstudio::Linker", "linker", TC) {}
bool hasIntegratedCPP() const override { return false; }
bool isLinkJob() const override { return true; }
class LLVM_LIBRARY_VISIBILITY Compiler : public Tool {
public:
Compiler(const ToolChain &TC)
- : Tool("visualstudio::Compiler", "compiler", TC, RF_Full,
- llvm::sys::WEM_UTF16) {}
+ : Tool("visualstudio::Compiler", "compiler", TC) {}
bool hasIntegratedAssembler() const override { return true; }
bool hasIntegratedCPP() const override { return true; }
CmdArgs.push_back(II.getFilename());
const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
+ Exec, CmdArgs, Inputs));
if (Args.hasArg(options::OPT_gsplit_dwarf))
SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output,
}
}
const char *Exec = Args.MakeArgString(TC.GetLinkerPath());
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(
+ JA, *this, ResponseFileSupport::AtFileUTF8(), Exec, CmdArgs, Inputs));
}
// Simplified from Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple.
#include "Gnu.h"
#include "clang/Driver/Tool.h"
#include "clang/Driver/ToolChain.h"
+#include "llvm/Support/ErrorOr.h"
namespace clang {
namespace driver {
class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
public:
- Linker(const ToolChain &TC)
- : Tool("MinGW::Linker", "linker", TC, Tool::RF_Full) {}
+ Linker(const ToolChain &TC) : Tool("MinGW::Linker", "linker", TC) {}
bool hasIntegratedCPP() const override { return false; }
bool isLinkJob() const override { return true; }
CmdArgs.push_back(II.getFilename());
const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(
+ JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs));
}
void tools::minix::Linker::ConstructJob(Compilation &C, const JobAction &JA,
}
const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(
+ JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs));
}
/// Minix - Minix tool chain which can call as(1) and ld(1) directly.
namespace tools {
/// minix -- Directly call GNU Binutils assembler and linker
namespace minix {
-class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool {
+class LLVM_LIBRARY_VISIBILITY Assembler : public Tool {
public:
- Assembler(const ToolChain &TC)
- : GnuTool("minix::Assembler", "assembler", TC) {}
+ Assembler(const ToolChain &TC) : Tool("minix::Assembler", "assembler", TC) {}
bool hasIntegratedCPP() const override { return false; }
const char *LinkingOutput) const override;
};
-class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
+class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
public:
- Linker(const ToolChain &TC) : GnuTool("minix::Linker", "linker", TC) {}
+ Linker(const ToolChain &TC) : Tool("minix::Linker", "linker", TC) {}
bool hasIntegratedCPP() const override { return false; }
bool isLinkJob() const override { return true; }
std::string Exec =
Args.MakeArgString(getToolChain().GetProgramPath("moviCompile"));
- C.addCommand(std::make_unique<Command>(JA, *this, Args.MakeArgString(Exec),
- CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
+ Args.MakeArgString(Exec), CmdArgs,
+ Inputs));
}
void tools::SHAVE::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
std::string Exec =
Args.MakeArgString(getToolChain().GetProgramPath("moviAsm"));
- C.addCommand(std::make_unique<Command>(JA, *this, Args.MakeArgString(Exec),
- CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
+ Args.MakeArgString(Exec), CmdArgs,
+ Inputs));
}
void tools::Myriad::Linker::ConstructJob(Compilation &C, const JobAction &JA,
std::string Exec =
Args.MakeArgString(TC.GetProgramPath("sparc-myriad-rtems-ld"));
- C.addCommand(std::make_unique<Command>(JA, *this, Args.MakeArgString(Exec),
- CmdArgs, Inputs));
+ C.addCommand(
+ std::make_unique<Command>(JA, *this, ResponseFileSupport::AtFileCurCP(),
+ Args.MakeArgString(Exec), CmdArgs, Inputs));
}
MyriadToolChain::MyriadToolChain(const Driver &D, const llvm::Triple &Triple,
/// whereas the linker, which accepts code for a mixture of Sparc and SHAVE,
/// is in the Myriad namespace.
namespace Myriad {
-class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
+class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
public:
- Linker(const ToolChain &TC) : GnuTool("shave::Linker", "ld", TC) {}
+ Linker(const ToolChain &TC) : Tool("shave::Linker", "ld", TC) {}
bool hasIntegratedCPP() const override { return false; }
bool isLinkJob() const override { return true; }
void ConstructJob(Compilation &C, const JobAction &JA,
}
const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(
+ JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs));
}
/// NaCl Toolchain
const char *LinkingOutput) const override;
};
-class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
+class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
public:
- Linker(const ToolChain &TC) : GnuTool("NaCl::Linker", "linker", TC) {}
+ Linker(const ToolChain &TC) : Tool("NaCl::Linker", "linker", TC) {}
bool hasIntegratedCPP() const override { return false; }
bool isLinkJob() const override { return true; }
CmdArgs.push_back(II.getFilename());
const char *Exec = Args.MakeArgString((getToolChain().GetProgramPath("as")));
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(
+ JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs));
}
void netbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
ToolChain.addProfileRTLibs(Args, CmdArgs);
const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(
+ JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs));
}
/// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly.
/// netbsd -- Directly call GNU Binutils assembler and linker
namespace netbsd {
-class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool {
+class LLVM_LIBRARY_VISIBILITY Assembler : public Tool {
public:
- Assembler(const ToolChain &TC)
- : GnuTool("netbsd::Assembler", "assembler", TC) {}
+ Assembler(const ToolChain &TC) : Tool("netbsd::Assembler", "assembler", TC) {}
bool hasIntegratedCPP() const override { return false; }
const char *LinkingOutput) const override;
};
-class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
+class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
public:
- Linker(const ToolChain &TC) : GnuTool("netbsd::Linker", "linker", TC) {}
+ Linker(const ToolChain &TC) : Tool("netbsd::Linker", "linker", TC) {}
bool hasIntegratedCPP() const override { return false; }
bool isLinkJob() const override { return true; }
CmdArgs.push_back(II.getFilename());
const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(
+ JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs));
}
void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
}
const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(
+ JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs));
}
SanitizerMask OpenBSD::getSupportedSanitizers() const {
/// openbsd -- Directly call GNU Binutils assembler and linker
namespace openbsd {
-class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool {
+class LLVM_LIBRARY_VISIBILITY Assembler : public Tool {
public:
Assembler(const ToolChain &TC)
- : GnuTool("openbsd::Assembler", "assembler", TC) {}
+ : Tool("openbsd::Assembler", "assembler", TC) {}
bool hasIntegratedCPP() const override { return false; }
const char *LinkingOutput) const override;
};
-class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
+class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
public:
- Linker(const ToolChain &TC) : GnuTool("openbsd::Linker", "linker", TC) {}
+ Linker(const ToolChain &TC) : Tool("openbsd::Linker", "linker", TC) {}
bool hasIntegratedCPP() const override { return false; }
bool isLinkJob() const override { return true; }
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath("orbis-as"));
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(
+ JA, *this, ResponseFileSupport::AtFileUTF8(), Exec, CmdArgs, Inputs));
}
static void AddPS4SanitizerArgs(const ToolChain &TC, ArgStringList &CmdArgs) {
const char *Exec =
Args.MakeArgString(ToolChain.GetProgramPath("orbis-ld"));
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(
+ JA, *this, ResponseFileSupport::AtFileUTF8(), Exec, CmdArgs, Inputs));
}
toolchains::PS4CPU::PS4CPU(const Driver &D, const llvm::Triple &Triple,
class LLVM_LIBRARY_VISIBILITY Assemble : public Tool {
public:
- Assemble(const ToolChain &TC)
- : Tool("PS4cpu::Assemble", "assembler", TC, RF_Full) {}
+ Assemble(const ToolChain &TC) : Tool("PS4cpu::Assemble", "assembler", TC) {}
bool hasIntegratedCPP() const override { return false; }
class LLVM_LIBRARY_VISIBILITY Link : public Tool {
public:
- Link(const ToolChain &TC) : Tool("PS4cpu::Link", "linker", TC, RF_Full) {}
+ Link(const ToolChain &TC) : Tool("PS4cpu::Link", "linker", TC) {}
bool hasIntegratedCPP() const override { return false; }
bool isLinkJob() const override { return true; }
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());
- C.addCommand(std::make_unique<Command>(JA, *this, Args.MakeArgString(Linker),
- CmdArgs, Inputs));
+ C.addCommand(
+ std::make_unique<Command>(JA, *this, ResponseFileSupport::AtFileCurCP(),
+ Args.MakeArgString(Linker), CmdArgs, Inputs));
}
// RISCV tools end.
namespace tools {
namespace RISCV {
-class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
+class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
public:
- Linker(const ToolChain &TC) : GnuTool("RISCV::Linker", "ld", TC) {}
+ Linker(const ToolChain &TC) : Tool("RISCV::Linker", "ld", TC) {}
bool hasIntegratedCPP() const override { return false; }
bool isLinkJob() const override { return true; }
void ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(II.getFilename());
const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
+ Exec, CmdArgs, Inputs));
}
void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA,
getToolChain().addProfileRTLibs(Args, CmdArgs);
const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
+ Exec, CmdArgs, Inputs));
}
static StringRef getSolarisLibSuffix(const llvm::Triple &Triple) {
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());
- C.addCommand(std::make_unique<Command>(JA, *this, Linker, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(
+ JA, *this, ResponseFileSupport::AtFileCurCP(), Linker, CmdArgs, Inputs));
// When optimizing, if wasm-opt is available, run it.
if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
CmdArgs.push_back(Args.MakeArgString(llvm::Twine("-O") + OOpt));
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());
- C.addCommand(std::make_unique<Command>(JA, *this, WasmOpt, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(
+ JA, *this, ResponseFileSupport::AtFileCurCP(), WasmOpt, CmdArgs,
+ Inputs));
}
}
}
namespace tools {
namespace wasm {
-class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
+class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
public:
- explicit Linker(const ToolChain &TC)
- : GnuTool("wasm::Linker", "linker", TC) {}
+ explicit Linker(const ToolChain &TC) : Tool("wasm::Linker", "linker", TC) {}
bool isLinkJob() const override { return true; }
bool hasIntegratedCPP() const override { return false; }
std::string getLinkerPath(const llvm::opt::ArgList &Args) const;
CmdArgs.push_back(II.getFilename());
const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("xcc"));
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
+ Exec, CmdArgs, Inputs));
}
void tools::XCore::Linker::ConstructJob(Compilation &C, const JobAction &JA,
AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("xcc"));
- C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
+ Exec, CmdArgs, Inputs));
}
/// XCore tool chain