aboutsummaryrefslogtreecommitdiff
path: root/lib/Driver
diff options
context:
space:
mode:
authorEd Schouten <ed@FreeBSD.org>2009-07-04 13:58:54 +0000
committerEd Schouten <ed@FreeBSD.org>2009-07-04 13:58:54 +0000
commit5362a71c02e7d448a8ce98cf00c47e353fba5d04 (patch)
tree8ddfe382e1c6d590dc240e76f7cd45cea5c78e24 /lib/Driver
parent4ebdf5c4f587daef4e0be499802eac3a7a49bf2f (diff)
Notes
Diffstat (limited to 'lib/Driver')
-rw-r--r--lib/Driver/ArgList.cpp29
-rw-r--r--lib/Driver/Compilation.cpp43
-rw-r--r--lib/Driver/Driver.cpp50
-rw-r--r--lib/Driver/HostInfo.cpp57
-rw-r--r--lib/Driver/Job.cpp6
-rw-r--r--lib/Driver/ToolChains.cpp30
-rw-r--r--lib/Driver/ToolChains.h7
-rw-r--r--lib/Driver/Tools.cpp148
-rw-r--r--lib/Driver/Tools.h34
9 files changed, 360 insertions, 44 deletions
diff --git a/lib/Driver/ArgList.cpp b/lib/Driver/ArgList.cpp
index 593694cfbbf67..54dd4bb775382 100644
--- a/lib/Driver/ArgList.cpp
+++ b/lib/Driver/ArgList.cpp
@@ -49,6 +49,35 @@ Arg *ArgList::getLastArg(options::ID Id0, options::ID Id1, bool Claim) const {
return Res;
}
+Arg *ArgList::getLastArg(options::ID Id0, options::ID Id1, options::ID Id2,
+ bool Claim) const {
+ Arg *Res = 0;
+ Arg *A0 = getLastArg(Id0, false);
+ Arg *A1 = getLastArg(Id1, false);
+ Arg *A2 = getLastArg(Id2, false);
+
+ int A0Idx = A0 ? A0->getIndex() : -1;
+ int A1Idx = A1 ? A1->getIndex() : -1;
+ int A2Idx = A2 ? A2->getIndex() : -1;
+
+ if (A0Idx > A1Idx) {
+ if (A0Idx > A2Idx)
+ Res = A0;
+ else if (A2Idx != -1)
+ Res = A2;
+ } else {
+ if (A1Idx > A2Idx)
+ Res = A1;
+ else if (A2Idx != -1)
+ Res = A2;
+ }
+
+ if (Claim && Res)
+ Res->claim();
+
+ return Res;
+}
+
bool ArgList::hasFlag(options::ID Pos, options::ID Neg, bool Default) const {
if (Arg *A = getLastArg(Pos, Neg))
return A->getOption().matches(Pos);
diff --git a/lib/Driver/Compilation.cpp b/lib/Driver/Compilation.cpp
index 1e044c6b8fdc1..7e29b67769d34 100644
--- a/lib/Driver/Compilation.cpp
+++ b/lib/Driver/Compilation.cpp
@@ -21,8 +21,8 @@
#include <errno.h>
using namespace clang::driver;
-Compilation::Compilation(Driver &D,
- ToolChain &_DefaultToolChain,
+Compilation::Compilation(const Driver &D,
+ const ToolChain &_DefaultToolChain,
InputArgList *_Args)
: TheDriver(D), DefaultToolChain(_DefaultToolChain), Args(_Args) {
}
@@ -105,7 +105,8 @@ bool Compilation::CleanupFileList(const ArgStringList &Files,
return Success;
}
-int Compilation::ExecuteCommand(const Command &C) const {
+int Compilation::ExecuteCommand(const Command &C,
+ const Command *&FailingCommand) const {
llvm::sys::Path Prog(C.getExecutable());
const char **Argv = new const char*[C.getArguments().size() + 2];
Argv[0] = C.getExecutable();
@@ -126,49 +127,31 @@ int Compilation::ExecuteCommand(const Command &C) const {
getDriver().Diag(clang::diag::err_drv_command_failure) << Error;
}
+ if (Res)
+ FailingCommand = &C;
+
delete[] Argv;
return Res;
}
-int Compilation::ExecuteJob(const Job &J) const {
+int Compilation::ExecuteJob(const Job &J,
+ const Command *&FailingCommand) const {
if (const Command *C = dyn_cast<Command>(&J)) {
- return ExecuteCommand(*C);
+ return ExecuteCommand(*C, FailingCommand);
} else if (const PipedJob *PJ = dyn_cast<PipedJob>(&J)) {
// Piped commands with a single job are easy.
if (PJ->size() == 1)
- return ExecuteCommand(**PJ->begin());
+ return ExecuteCommand(**PJ->begin(), FailingCommand);
+ FailingCommand = *PJ->begin();
getDriver().Diag(clang::diag::err_drv_unsupported_opt) << "-pipe";
return 1;
} else {
const JobList *Jobs = cast<JobList>(&J);
for (JobList::const_iterator
it = Jobs->begin(), ie = Jobs->end(); it != ie; ++it)
- if (int Res = ExecuteJob(**it))
+ if (int Res = ExecuteJob(**it, FailingCommand))
return Res;
return 0;
}
}
-
-int Compilation::Execute() const {
- // Just print if -### was present.
- if (getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
- PrintJob(llvm::errs(), Jobs, "\n", true);
- return 0;
- }
-
- // If there were errors building the compilation, quit now.
- if (getDriver().getDiags().getNumErrors())
- return 1;
-
- int Res = ExecuteJob(Jobs);
-
- // Remove temp files.
- CleanupFileList(TempFiles);
-
- // If the compilation failed, remove result files as well.
- if (Res != 0 && !getArgs().hasArg(options::OPT_save_temps))
- CleanupFileList(ResultFiles, true);
-
- return Res;
-}
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index 8c2676b8cd7dd..1b0b5615dfbcb 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -217,6 +217,54 @@ Compilation *Driver::BuildCompilation(int argc, const char **argv) {
return C;
}
+int Driver::ExecuteCompilation(const Compilation &C) const {
+ // Just print if -### was present.
+ if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
+ C.PrintJob(llvm::errs(), C.getJobs(), "\n", true);
+ return 0;
+ }
+
+ // If there were errors building the compilation, quit now.
+ if (getDiags().getNumErrors())
+ return 1;
+
+ const Command *FailingCommand = 0;
+ int Res = C.ExecuteJob(C.getJobs(), FailingCommand);
+
+ // Remove temp files.
+ C.CleanupFileList(C.getTempFiles());
+
+ // If the compilation failed, remove result files as well.
+ if (Res != 0 && !C.getArgs().hasArg(options::OPT_save_temps))
+ C.CleanupFileList(C.getResultFiles(), true);
+
+ // Print extra information about abnormal failures, if possible.
+ if (Res) {
+ // This is ad-hoc, but we don't want to be excessively noisy. If the result
+ // status was 1, assume the command failed normally. In particular, if it
+ // was the compiler then assume it gave a reasonable error code. Failures in
+ // other tools are less common, and they generally have worse diagnostics,
+ // so always print the diagnostic there.
+ const Action &Source = FailingCommand->getSource();
+ bool IsFriendlyTool = (isa<PreprocessJobAction>(Source) ||
+ isa<PrecompileJobAction>(Source) ||
+ isa<AnalyzeJobAction>(Source) ||
+ isa<CompileJobAction>(Source));
+
+ if (!IsFriendlyTool || Res != 1) {
+ // FIXME: See FIXME above regarding result code interpretation.
+ if (Res < 0)
+ Diag(clang::diag::err_drv_command_signalled)
+ << Source.getClassName() << -Res;
+ else
+ Diag(clang::diag::err_drv_command_failed)
+ << Source.getClassName() << Res;
+ }
+ }
+
+ return Res;
+}
+
void Driver::PrintOptions(const ArgList &Args) const {
unsigned i = 0;
for (ArgList::const_iterator it = Args.begin(), ie = Args.end();
@@ -1205,6 +1253,8 @@ const HostInfo *Driver::GetHostInfo(const char *TripleStr) const {
return createDarwinHostInfo(*this, Triple);
case llvm::Triple::DragonFly:
return createDragonFlyHostInfo(*this, Triple);
+ case llvm::Triple::OpenBSD:
+ return createOpenBSDHostInfo(*this, Triple);
case llvm::Triple::FreeBSD:
return createFreeBSDHostInfo(*this, Triple);
case llvm::Triple::Linux:
diff --git a/lib/Driver/HostInfo.cpp b/lib/Driver/HostInfo.cpp
index 831e11b98e42d..602a977135055 100644
--- a/lib/Driver/HostInfo.cpp
+++ b/lib/Driver/HostInfo.cpp
@@ -234,6 +234,57 @@ ToolChain *UnknownHostInfo::getToolChain(const ArgList &Args,
return TC;
}
+// OpenBSD Host Info
+
+/// OpenBSDHostInfo - OpenBSD host information implementation.
+class OpenBSDHostInfo : public HostInfo {
+ /// Cache of tool chains we have created.
+ mutable llvm::StringMap<ToolChain*> ToolChains;
+
+public:
+ OpenBSDHostInfo(const Driver &D, const llvm::Triple& Triple)
+ : HostInfo(D, Triple) {}
+ ~OpenBSDHostInfo();
+
+ virtual bool useDriverDriver() const;
+
+ virtual types::ID lookupTypeForExtension(const char *Ext) const {
+ return types::lookupTypeForExtension(Ext);
+ }
+
+ virtual ToolChain *getToolChain(const ArgList &Args,
+ const char *ArchName) const;
+};
+
+OpenBSDHostInfo::~OpenBSDHostInfo() {
+ for (llvm::StringMap<ToolChain*>::iterator
+ it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
+ delete it->second;
+}
+
+bool OpenBSDHostInfo::useDriverDriver() const {
+ return false;
+}
+
+ToolChain *OpenBSDHostInfo::getToolChain(const ArgList &Args,
+ const char *ArchName) const {
+ assert(!ArchName &&
+ "Unexpected arch name on platform without driver driver support.");
+
+ std::string Arch = getArchName();
+ ArchName = Arch.c_str();
+
+ ToolChain *&TC = ToolChains[ArchName];
+ if (!TC) {
+ llvm::Triple TCTriple(getTriple());
+ TCTriple.setArchName(ArchName);
+
+ TC = new toolchains::OpenBSD(*this, TCTriple);
+ }
+
+ return TC;
+}
+
// FreeBSD Host Info
/// FreeBSDHostInfo - FreeBSD host information implementation.
@@ -417,6 +468,12 @@ clang::driver::createDarwinHostInfo(const Driver &D,
}
const HostInfo *
+clang::driver::createOpenBSDHostInfo(const Driver &D,
+ const llvm::Triple& Triple) {
+ return new OpenBSDHostInfo(D, Triple);
+}
+
+const HostInfo *
clang::driver::createFreeBSDHostInfo(const Driver &D,
const llvm::Triple& Triple) {
return new FreeBSDHostInfo(D, Triple);
diff --git a/lib/Driver/Job.cpp b/lib/Driver/Job.cpp
index 222cf15db60f5..1b0ea18453d06 100644
--- a/lib/Driver/Job.cpp
+++ b/lib/Driver/Job.cpp
@@ -14,8 +14,10 @@ using namespace clang::driver;
Job::~Job() {}
-Command::Command(const char *_Executable, const ArgStringList &_Arguments)
- : Job(CommandClass), Executable(_Executable), Arguments(_Arguments) {
+Command::Command(const Action &_Source, const char *_Executable,
+ const ArgStringList &_Arguments)
+ : Job(CommandClass), Source(_Source), Executable(_Executable),
+ Arguments(_Arguments) {
}
PipedJob::PipedJob() : Job(PipedJobClass) {}
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index 436d343dd0211..f663ed49536e2 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -384,6 +384,36 @@ DerivedArgList *Generic_GCC::TranslateArgs(InputArgList &Args) const {
return new DerivedArgList(Args, true);
}
+/// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly.
+
+OpenBSD::OpenBSD(const HostInfo &Host, const llvm::Triple& Triple)
+ : Generic_GCC(Host, Triple) {
+ getFilePaths().push_back(getHost().getDriver().Dir + "/../lib");
+ getFilePaths().push_back("/usr/lib");
+}
+
+Tool &OpenBSD::SelectTool(const Compilation &C, const JobAction &JA) const {
+ Action::ActionClass Key;
+ if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getArchName()))
+ Key = Action::AnalyzeJobClass;
+ else
+ Key = JA.getKind();
+
+ Tool *&T = Tools[Key];
+ if (!T) {
+ switch (Key) {
+ case Action::AssembleJobClass:
+ T = new tools::openbsd::Assemble(*this); break;
+ case Action::LinkJobClass:
+ T = new tools::openbsd::Link(*this); break;
+ default:
+ T = &Generic_GCC::SelectTool(C, JA);
+ }
+ }
+
+ return *T;
+}
+
/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
FreeBSD::FreeBSD(const HostInfo &Host, const llvm::Triple& Triple, bool Lib32)
diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h
index 3ecd1715da969..c921d52864f09 100644
--- a/lib/Driver/ToolChains.h
+++ b/lib/Driver/ToolChains.h
@@ -107,6 +107,13 @@ public:
virtual const char *GetDefaultRelocationModel() const { return "pic"; }
};
+class VISIBILITY_HIDDEN OpenBSD : public Generic_GCC {
+public:
+ OpenBSD(const HostInfo &Host, const llvm::Triple& Triple);
+
+ virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
+};
+
class VISIBILITY_HIDDEN FreeBSD : public Generic_GCC {
public:
FreeBSD(const HostInfo &Host, const llvm::Triple& Triple, bool Lib32);
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index bfc247a015ff3..d198a54cf7dd6 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -498,6 +498,18 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddLastArg(CmdArgs, options::OPT_fvisibility_EQ);
Args.AddLastArg(CmdArgs, options::OPT_fwritable_strings);
+ // Forward stack protector flags.
+ if (Arg *A = Args.getLastArg(options::OPT_fno_stack_protector,
+ options::OPT_fstack_protector_all,
+ options::OPT_fstack_protector)) {
+ if (A->getOption().matches(options::OPT_fno_stack_protector))
+ CmdArgs.push_back("--stack-protector=0");
+ else if (A->getOption().matches(options::OPT_fstack_protector))
+ CmdArgs.push_back("--stack-protector=1");
+ else
+ CmdArgs.push_back("--stack-protector=2");
+ }
+
// Forward -f options with positive and negative forms; we translate
// these by hand.
@@ -616,7 +628,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, "clang-cc").c_str());
- Dest.addCommand(new Command(Exec, CmdArgs));
+ Dest.addCommand(new Command(JA, Exec, CmdArgs));
// Explicitly warn that these options are unsupported, even though
// we are allowing compilation to continue.
@@ -747,7 +759,7 @@ void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA,
getToolChain().getHost().getDriver().CCCGenericGCCName.c_str();
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, GCCName).c_str());
- Dest.addCommand(new Command(Exec, CmdArgs));
+ Dest.addCommand(new Command(JA, Exec, CmdArgs));
}
void gcc::Preprocess::RenderExtraToolArgs(ArgStringList &CmdArgs) const {
@@ -1123,7 +1135,7 @@ void darwin::Preprocess::ConstructJob(Compilation &C, const JobAction &JA,
const char *CC1Name = getCC1Name(Inputs[0].getType());
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, CC1Name).c_str());
- Dest.addCommand(new Command(Exec, CmdArgs));
+ Dest.addCommand(new Command(JA, Exec, CmdArgs));
}
void darwin::Compile::ConstructJob(Compilation &C, const JobAction &JA,
@@ -1211,7 +1223,7 @@ void darwin::Compile::ConstructJob(Compilation &C, const JobAction &JA,
const char *CC1Name = getCC1Name(Inputs[0].getType());
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, CC1Name).c_str());
- Dest.addCommand(new Command(Exec, CmdArgs));
+ Dest.addCommand(new Command(JA, Exec, CmdArgs));
}
void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
@@ -1264,7 +1276,7 @@ void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, "as").c_str());
- Dest.addCommand(new Command(Exec, CmdArgs));
+ Dest.addCommand(new Command(JA, Exec, CmdArgs));
}
/// Helper routine for seeing if we should use dsymutil; this is a
@@ -1688,7 +1700,7 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, "ld").c_str());
- Dest.addCommand(new Command(Exec, CmdArgs));
+ Dest.addCommand(new Command(JA, Exec, CmdArgs));
// Find the first non-empty base input (we want to ignore linker
// inputs).
@@ -1718,7 +1730,7 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
Args.MakeArgString(getToolChain().GetProgramPath(C, "dsymutil").c_str());
ArgStringList CmdArgs;
CmdArgs.push_back(Output.getFilename());
- C.getJobs().addCommand(new Command(Exec, CmdArgs));
+ C.getJobs().addCommand(new Command(JA, Exec, CmdArgs));
}
}
}
@@ -1744,9 +1756,121 @@ void darwin::Lipo::ConstructJob(Compilation &C, const JobAction &JA,
}
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, "lipo").c_str());
- Dest.addCommand(new Command(Exec, CmdArgs));
+ Dest.addCommand(new Command(JA, Exec, CmdArgs));
+}
+
+void openbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
+ Job &Dest, const InputInfo &Output,
+ const InputInfoList &Inputs,
+ const ArgList &Args,
+ const char *LinkingOutput) const
+{
+ ArgStringList CmdArgs;
+
+ Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
+ options::OPT_Xassembler);
+
+ CmdArgs.push_back("-o");
+ if (Output.isPipe())
+ CmdArgs.push_back("-");
+ else
+ CmdArgs.push_back(Output.getFilename());
+
+ for (InputInfoList::const_iterator
+ it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
+ const InputInfo &II = *it;
+ if (II.isPipe())
+ CmdArgs.push_back("-");
+ else
+ CmdArgs.push_back(II.getFilename());
+ }
+
+ const char *Exec =
+ Args.MakeArgString(getToolChain().GetProgramPath(C, "as").c_str());
+ Dest.addCommand(new Command(JA, Exec, CmdArgs));
}
+void openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
+ Job &Dest, const InputInfo &Output,
+ const InputInfoList &Inputs,
+ const ArgList &Args,
+ const char *LinkingOutput) const {
+ const Driver &D = getToolChain().getHost().getDriver();
+ ArgStringList CmdArgs;
+
+ if (Args.hasArg(options::OPT_static)) {
+ CmdArgs.push_back("-Bstatic");
+ } else {
+ CmdArgs.push_back("--eh-frame-hdr");
+ if (Args.hasArg(options::OPT_shared)) {
+ CmdArgs.push_back("-Bshareable");
+ } else {
+ CmdArgs.push_back("-dynamic-linker");
+ CmdArgs.push_back("/usr/libexec/ld.so");
+ }
+ }
+
+ if (Output.isPipe()) {
+ CmdArgs.push_back("-o");
+ CmdArgs.push_back("-");
+ } else 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)) {
+ if (!Args.hasArg(options::OPT_shared)) {
+ CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crt0.o").c_str()));
+ CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbegin.o").c_str()));
+ } else {
+ CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbeginS.o").c_str()));
+ }
+ }
+
+ Args.AddAllArgs(CmdArgs, options::OPT_L);
+ Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
+ Args.AddAllArgs(CmdArgs, options::OPT_e);
+
+ for (InputInfoList::const_iterator
+ it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
+ const InputInfo &II = *it;
+
+ // Don't try to pass LLVM inputs to a generic gcc.
+ if (II.getType() == types::TY_LLVMBC)
+ D.Diag(clang::diag::err_drv_no_linker_llvm_support)
+ << getToolChain().getTripleString().c_str();
+
+ if (II.isPipe())
+ CmdArgs.push_back("-");
+ else if (II.isFilename())
+ CmdArgs.push_back(II.getFilename());
+ else
+ II.getInputArg().renderAsInput(Args, CmdArgs);
+ }
+
+ if (!Args.hasArg(options::OPT_nostdlib) &&
+ !Args.hasArg(options::OPT_nodefaultlibs)) {
+
+ if (Args.hasArg(options::OPT_pthread))
+ CmdArgs.push_back("-pthread");
+ CmdArgs.push_back("-lc");
+ }
+
+ if (!Args.hasArg(options::OPT_nostdlib) &&
+ !Args.hasArg(options::OPT_nostartfiles)) {
+ if (!Args.hasArg(options::OPT_shared))
+ CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtend.o").c_str()));
+ else
+ CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtendS.o").c_str()));
+ }
+
+ const char *Exec =
+ Args.MakeArgString(getToolChain().GetProgramPath(C, "ld").c_str());
+ Dest.addCommand(new Command(JA, Exec, CmdArgs));
+}
void freebsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
Job &Dest, const InputInfo &Output,
@@ -1781,7 +1905,7 @@ void freebsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, "as").c_str());
- Dest.addCommand(new Command(Exec, CmdArgs));
+ Dest.addCommand(new Command(JA, Exec, CmdArgs));
}
void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
@@ -1892,7 +2016,7 @@ void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, "ld").c_str());
- Dest.addCommand(new Command(Exec, CmdArgs));
+ Dest.addCommand(new Command(JA, Exec, CmdArgs));
}
/// DragonFly Tools
@@ -1931,7 +2055,7 @@ void dragonfly::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, "as").c_str());
- Dest.addCommand(new Command(Exec, CmdArgs));
+ Dest.addCommand(new Command(JA, Exec, CmdArgs));
}
void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA,
@@ -2055,5 +2179,5 @@ void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA,
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, "ld").c_str());
- Dest.addCommand(new Command(Exec, CmdArgs));
+ Dest.addCommand(new Command(JA, Exec, CmdArgs));
}
diff --git a/lib/Driver/Tools.h b/lib/Driver/Tools.h
index db108db2b4d7e..ab73496009078 100644
--- a/lib/Driver/Tools.h
+++ b/lib/Driver/Tools.h
@@ -241,6 +241,40 @@ namespace darwin {
};
}
+ /// openbsd -- Directly call GNU Binutils assembler and linker
+namespace openbsd {
+ class VISIBILITY_HIDDEN Assemble : public Tool {
+ public:
+ Assemble(const ToolChain &TC) : Tool("openbsd::Assemble", TC) {}
+
+ virtual bool acceptsPipedInput() const { return true; }
+ virtual bool canPipeOutput() const { return true; }
+ virtual bool hasIntegratedCPP() const { return false; }
+
+ virtual void ConstructJob(Compilation &C, const JobAction &JA,
+ Job &Dest,
+ const InputInfo &Output,
+ const InputInfoList &Inputs,
+ const ArgList &TCArgs,
+ const char *LinkingOutput) const;
+ };
+ class VISIBILITY_HIDDEN Link : public Tool {
+ public:
+ Link(const ToolChain &TC) : Tool("openbsd::Link", TC) {}
+
+ virtual bool acceptsPipedInput() const { return true; }
+ virtual bool canPipeOutput() const { return true; }
+ virtual bool hasIntegratedCPP() const { return false; }
+
+ virtual void ConstructJob(Compilation &C, const JobAction &JA,
+ Job &Dest,
+ const InputInfo &Output,
+ const InputInfoList &Inputs,
+ const ArgList &TCArgs,
+ const char *LinkingOutput) const;
+ };
+}
+
/// freebsd -- Directly call GNU Binutils assembler and linker
namespace freebsd {
class VISIBILITY_HIDDEN Assemble : public Tool {