Driver: Move actions into Compilation, and construct the compilation
earlier. - This gives us a simple ownership model, and allows clients access to more information should they ever want it. - We now free Actions correctly. llvm-svn: 67158
This commit is contained in:
parent
8df898917f
commit
f0eddb8510
|
@ -30,6 +30,9 @@ class Compilation {
|
||||||
/// The original (untranslated) input argument list.
|
/// The original (untranslated) input argument list.
|
||||||
ArgList *Args;
|
ArgList *Args;
|
||||||
|
|
||||||
|
/// The list of actions.
|
||||||
|
ActionList Actions;
|
||||||
|
|
||||||
/// The root list of jobs.
|
/// The root list of jobs.
|
||||||
JobList Jobs;
|
JobList Jobs;
|
||||||
|
|
||||||
|
@ -46,7 +49,13 @@ public:
|
||||||
Compilation(ToolChain &DefaultToolChain, ArgList *Args);
|
Compilation(ToolChain &DefaultToolChain, ArgList *Args);
|
||||||
~Compilation();
|
~Compilation();
|
||||||
|
|
||||||
|
const ToolChain &getDefaultToolChain() const { return DefaultToolChain; }
|
||||||
|
|
||||||
const ArgList &getArgs() const { return *Args; }
|
const ArgList &getArgs() const { return *Args; }
|
||||||
|
|
||||||
|
ActionList &getActions() { return Actions; }
|
||||||
|
const ActionList &getActions() const { return Actions; }
|
||||||
|
|
||||||
JobList &getJobs() { return Jobs; }
|
JobList &getJobs() { return Jobs; }
|
||||||
|
|
||||||
/// getArgsForToolChain - Return the argument list, possibly
|
/// getArgsForToolChain - Return the argument list, possibly
|
||||||
|
|
|
@ -138,20 +138,24 @@ public:
|
||||||
///
|
///
|
||||||
/// \param Args - The input arguments.
|
/// \param Args - The input arguments.
|
||||||
/// \param Actions - The list to store the resulting actions onto.
|
/// \param Actions - The list to store the resulting actions onto.
|
||||||
void BuildActions(ArgList &Args, ActionList &Actions) const;
|
void BuildActions(const ArgList &Args, ActionList &Actions) const;
|
||||||
|
|
||||||
/// BuildUniversalActions - Construct the list of actions to perform
|
/// BuildUniversalActions - Construct the list of actions to perform
|
||||||
/// for the given arguments, which may require a universal build.
|
/// for the given arguments, which may require a universal build.
|
||||||
///
|
///
|
||||||
/// \param Args - The input arguments.
|
/// \param Args - The input arguments.
|
||||||
/// \param Actions - The list to store the resulting actions onto.
|
/// \param Actions - The list to store the resulting actions onto.
|
||||||
void BuildUniversalActions(ArgList &Args, ActionList &Actions) const;
|
/// \param DefaultArchName - The default arch name (required to know
|
||||||
|
/// what architecture to bind if no -arch options are present).
|
||||||
|
|
||||||
|
void BuildUniversalActions(const ArgList &Args, ActionList &Actions,
|
||||||
|
const char *DefaultArchName) const;
|
||||||
|
|
||||||
/// BuildJobs - Bind actions to concrete tools and translate
|
/// BuildJobs - Bind actions to concrete tools and translate
|
||||||
/// arguments to form the list of jobs to run.
|
/// arguments to form the list of jobs to run.
|
||||||
///
|
///
|
||||||
/// \arg C - The compilation that is being built.
|
/// \arg C - The compilation that is being built.
|
||||||
void BuildJobs(Compilation &C, const ActionList &Actions) const;
|
void BuildJobs(Compilation &C) const;
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
/// @name Helper Methods
|
/// @name Helper Methods
|
||||||
|
@ -168,27 +172,25 @@ public:
|
||||||
|
|
||||||
/// GetFilePath - Lookup \arg Name in the list of file search paths.
|
/// GetFilePath - Lookup \arg Name in the list of file search paths.
|
||||||
///
|
///
|
||||||
/// \arg TC - Use the provided tool chain for additional information
|
/// \arg TC - The tool chain for additional information on
|
||||||
/// on directories to search, or the DefaultToolChain if not
|
/// directories to search.
|
||||||
/// provided.
|
|
||||||
// FIXME: This should be in CompilationInfo.
|
// FIXME: This should be in CompilationInfo.
|
||||||
llvm::sys::Path GetFilePath(const char *Name, const ToolChain *TC=0) const;
|
llvm::sys::Path GetFilePath(const char *Name, const ToolChain &TC) const;
|
||||||
|
|
||||||
/// GetProgramPath - Lookup \arg Name in the list of program search
|
/// GetProgramPath - Lookup \arg Name in the list of program search
|
||||||
/// paths.
|
/// paths.
|
||||||
///
|
///
|
||||||
/// \arg TC - Use the provided tool chain for additional information
|
/// \arg TC - The provided tool chain for additional information on
|
||||||
/// on directories to search, or the DefaultToolChain if not
|
/// directories to search.
|
||||||
/// provided.
|
|
||||||
// FIXME: This should be in CompilationInfo.
|
// FIXME: This should be in CompilationInfo.
|
||||||
llvm::sys::Path GetProgramPath(const char *Name, const ToolChain *TC=0) const;
|
llvm::sys::Path GetProgramPath(const char *Name, const ToolChain &TC) const;
|
||||||
|
|
||||||
/// HandleImmediateArgs - Handle any arguments which should be
|
/// HandleImmediateArgs - Handle any arguments which should be
|
||||||
/// treated before building actions or binding tools.
|
/// treated before building actions or binding tools.
|
||||||
///
|
///
|
||||||
/// \return Whether any compilation should be built for this
|
/// \return Whether any compilation should be built for this
|
||||||
/// invocation.
|
/// invocation.
|
||||||
bool HandleImmediateArgs(const ArgList &Args);
|
bool HandleImmediateArgs(const Compilation &C);
|
||||||
|
|
||||||
/// ConstructAction - Construct the appropriate action to do for
|
/// ConstructAction - Construct the appropriate action to do for
|
||||||
/// \arg Phase on the \arg Input, taking in to account arguments
|
/// \arg Phase on the \arg Input, taking in to account arguments
|
||||||
|
|
|
@ -12,7 +12,11 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
using namespace clang::driver;
|
using namespace clang::driver;
|
||||||
|
|
||||||
Action::~Action() {}
|
Action::~Action() {
|
||||||
|
// Free the inputs.
|
||||||
|
for (iterator it = begin(), ie = end(); it != ie; ++it)
|
||||||
|
delete *it;
|
||||||
|
}
|
||||||
|
|
||||||
const char *Action::getClassName(ActionClass AC) {
|
const char *Action::getClassName(ActionClass AC) {
|
||||||
switch (AC) {
|
switch (AC) {
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include "clang/Driver/Compilation.h"
|
#include "clang/Driver/Compilation.h"
|
||||||
|
|
||||||
|
#include "clang/Driver/Action.h"
|
||||||
#include "clang/Driver/ArgList.h"
|
#include "clang/Driver/ArgList.h"
|
||||||
#include "clang/Driver/ToolChain.h"
|
#include "clang/Driver/ToolChain.h"
|
||||||
|
|
||||||
|
@ -29,6 +30,11 @@ Compilation::~Compilation() {
|
||||||
if (A != Args)
|
if (A != Args)
|
||||||
delete Args;
|
delete Args;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Free the actions, if built.
|
||||||
|
for (ActionList::iterator it = Actions.begin(), ie = Actions.end();
|
||||||
|
it != ie; ++it)
|
||||||
|
delete *it;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ArgList &Compilation::getArgsForToolChain(const ToolChain *TC) {
|
const ArgList &Compilation::getArgsForToolChain(const ToolChain *TC) {
|
||||||
|
|
|
@ -166,31 +166,33 @@ Compilation *Driver::BuildCompilation(int argc, const char **argv) {
|
||||||
// is part of the compilation (it is arg dependent).
|
// is part of the compilation (it is arg dependent).
|
||||||
DefaultToolChain = Host->getToolChain(*Args);
|
DefaultToolChain = Host->getToolChain(*Args);
|
||||||
|
|
||||||
// FIXME: This behavior shouldn't be here.
|
|
||||||
if (CCCPrintOptions) {
|
|
||||||
PrintOptions(*Args);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!HandleImmediateArgs(*Args))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// Construct the list of abstract actions to perform for this
|
|
||||||
// compilation.
|
|
||||||
ActionList Actions;
|
|
||||||
if (Host->useDriverDriver())
|
|
||||||
BuildUniversalActions(*Args, Actions);
|
|
||||||
else
|
|
||||||
BuildActions(*Args, Actions);
|
|
||||||
|
|
||||||
if (CCCPrintActions) {
|
|
||||||
PrintActions(*Args, Actions);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The compilation takes ownership of Args.
|
// The compilation takes ownership of Args.
|
||||||
Compilation *C = new Compilation(*DefaultToolChain, Args);
|
Compilation *C = new Compilation(*DefaultToolChain, Args);
|
||||||
BuildJobs(*C, Actions);
|
|
||||||
|
// FIXME: This behavior shouldn't be here.
|
||||||
|
if (CCCPrintOptions) {
|
||||||
|
PrintOptions(C->getArgs());
|
||||||
|
return C;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!HandleImmediateArgs(*C))
|
||||||
|
return C;
|
||||||
|
|
||||||
|
// Construct the list of abstract actions to perform for this
|
||||||
|
// compilation. We avoid passing a Compilation here simply to
|
||||||
|
// enforce the abstraction that pipelining is not host or toolchain
|
||||||
|
// dependent (other than the driver driver test).
|
||||||
|
if (Host->useDriverDriver())
|
||||||
|
BuildUniversalActions(C->getArgs(), C->getActions());
|
||||||
|
else
|
||||||
|
BuildActions(C->getArgs(), C->getActions());
|
||||||
|
|
||||||
|
if (CCCPrintActions) {
|
||||||
|
PrintActions(C->getArgs(), C->getActions());
|
||||||
|
return C;
|
||||||
|
}
|
||||||
|
|
||||||
|
BuildJobs(*C);
|
||||||
|
|
||||||
return C;
|
return C;
|
||||||
}
|
}
|
||||||
|
@ -220,30 +222,33 @@ void Driver::PrintVersion() const {
|
||||||
llvm::outs() << "ccc version 1.0" << "\n";
|
llvm::outs() << "ccc version 1.0" << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Driver::HandleImmediateArgs(const ArgList &Args) {
|
bool Driver::HandleImmediateArgs(const Compilation &C) {
|
||||||
// The order these options are handled in in gcc is all over the
|
// The order these options are handled in in gcc is all over the
|
||||||
// place, but we don't expect inconsistencies w.r.t. that to matter
|
// place, but we don't expect inconsistencies w.r.t. that to matter
|
||||||
// in practice.
|
// in practice.
|
||||||
if (Args.hasArg(options::OPT_v) ||
|
if (C.getArgs().hasArg(options::OPT_v) ||
|
||||||
Args.hasArg(options::OPT__HASH_HASH_HASH)) {
|
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
|
||||||
PrintVersion();
|
PrintVersion();
|
||||||
SuppressMissingInputWarning = true;
|
SuppressMissingInputWarning = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ToolChain &TC = C.getDefaultToolChain();
|
||||||
// FIXME: The following handlers should use a callback mechanism, we
|
// FIXME: The following handlers should use a callback mechanism, we
|
||||||
// don't know what the client would like to do.
|
// don't know what the client would like to do.
|
||||||
if (Arg *A = Args.getLastArg(options::OPT_print_file_name_EQ)) {
|
if (Arg *A = C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
|
||||||
llvm::outs() << GetFilePath(A->getValue(Args)).toString() << "\n";
|
llvm::outs() << GetFilePath(A->getValue(C.getArgs()), TC).toString()
|
||||||
|
<< "\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Arg *A = Args.getLastArg(options::OPT_print_prog_name_EQ)) {
|
if (Arg *A = C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
|
||||||
llvm::outs() << GetProgramPath(A->getValue(Args)).toString() << "\n";
|
llvm::outs() << GetProgramPath(A->getValue(C.getArgs()), TC).toString()
|
||||||
|
<< "\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Args.hasArg(options::OPT_print_libgcc_file_name)) {
|
if (C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
|
||||||
llvm::outs() << GetProgramPath("libgcc.a").toString() << "\n";
|
llvm::outs() << GetProgramPath("libgcc.a", TC).toString() << "\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,7 +297,8 @@ void Driver::PrintActions(const ArgList &Args,
|
||||||
PrintActions1(Args, *it, Ids);
|
PrintActions1(Args, *it, Ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Driver::BuildUniversalActions(ArgList &Args, ActionList &Actions) const {
|
void Driver::BuildUniversalActions(const ArgList &Args,
|
||||||
|
ActionList &Actions) const {
|
||||||
llvm::PrettyStackTraceString CrashInfo("Building actions for universal build");
|
llvm::PrettyStackTraceString CrashInfo("Building actions for universal build");
|
||||||
// Collect the list of architectures. Duplicates are allowed, but
|
// Collect the list of architectures. Duplicates are allowed, but
|
||||||
// should only be handled once (in the order seen).
|
// should only be handled once (in the order seen).
|
||||||
|
@ -367,7 +373,7 @@ void Driver::BuildUniversalActions(ArgList &Args, ActionList &Actions) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Driver::BuildActions(ArgList &Args, ActionList &Actions) const {
|
void Driver::BuildActions(const ArgList &Args, ActionList &Actions) const {
|
||||||
llvm::PrettyStackTraceString CrashInfo("Building compilation actions");
|
llvm::PrettyStackTraceString CrashInfo("Building compilation actions");
|
||||||
// Start by constructing the list of inputs and their types.
|
// Start by constructing the list of inputs and their types.
|
||||||
|
|
||||||
|
@ -587,7 +593,7 @@ Action *Driver::ConstructPhaseAction(const ArgList &Args, phases::ID Phase,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Driver::BuildJobs(Compilation &C, const ActionList &Actions) const {
|
void Driver::BuildJobs(Compilation &C) const {
|
||||||
llvm::PrettyStackTraceString CrashInfo("Building compilation jobs");
|
llvm::PrettyStackTraceString CrashInfo("Building compilation jobs");
|
||||||
bool SaveTemps = C.getArgs().hasArg(options::OPT_save_temps);
|
bool SaveTemps = C.getArgs().hasArg(options::OPT_save_temps);
|
||||||
bool UsePipes = C.getArgs().hasArg(options::OPT_pipe);
|
bool UsePipes = C.getArgs().hasArg(options::OPT_pipe);
|
||||||
|
@ -604,8 +610,8 @@ void Driver::BuildJobs(Compilation &C, const ActionList &Actions) const {
|
||||||
// output files.
|
// output files.
|
||||||
if (FinalOutput) {
|
if (FinalOutput) {
|
||||||
unsigned NumOutputs = 0;
|
unsigned NumOutputs = 0;
|
||||||
for (ActionList::const_iterator it = Actions.begin(), ie = Actions.end();
|
for (ActionList::const_iterator it = C.getActions().begin(),
|
||||||
it != ie; ++it)
|
ie = C.getActions().end(); it != ie; ++it)
|
||||||
if ((*it)->getType() != types::TY_Nothing)
|
if ((*it)->getType() != types::TY_Nothing)
|
||||||
++NumOutputs;
|
++NumOutputs;
|
||||||
|
|
||||||
|
@ -615,8 +621,8 @@ void Driver::BuildJobs(Compilation &C, const ActionList &Actions) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ActionList::const_iterator it = Actions.begin(), ie = Actions.end();
|
for (ActionList::const_iterator it = C.getActions().begin(),
|
||||||
it != ie; ++it) {
|
ie = C.getActions().end(); it != ie; ++it) {
|
||||||
Action *A = *it;
|
Action *A = *it;
|
||||||
|
|
||||||
// If we are linking an image for multiple archs then the linker
|
// If we are linking an image for multiple archs then the linker
|
||||||
|
@ -821,18 +827,14 @@ const char *Driver::GetNamedOutputPath(Compilation &C,
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::sys::Path Driver::GetFilePath(const char *Name,
|
llvm::sys::Path Driver::GetFilePath(const char *Name,
|
||||||
const ToolChain *TC) const {
|
const ToolChain &TC) const {
|
||||||
// FIXME: Implement.
|
// FIXME: Implement.
|
||||||
if (!TC) TC = DefaultToolChain;
|
|
||||||
|
|
||||||
return llvm::sys::Path(Name);
|
return llvm::sys::Path(Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::sys::Path Driver::GetProgramPath(const char *Name,
|
llvm::sys::Path Driver::GetProgramPath(const char *Name,
|
||||||
const ToolChain *TC) const {
|
const ToolChain &TC) const {
|
||||||
// FIXME: Implement.
|
// FIXME: Implement.
|
||||||
if (!TC) TC = DefaultToolChain;
|
|
||||||
|
|
||||||
return llvm::sys::Path(Name);
|
return llvm::sys::Path(Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,13 +25,13 @@ ToolChain::~ToolChain() {
|
||||||
|
|
||||||
llvm::sys::Path ToolChain::GetFilePath(const Compilation &C,
|
llvm::sys::Path ToolChain::GetFilePath(const Compilation &C,
|
||||||
const char *Name) const {
|
const char *Name) const {
|
||||||
return Host.getDriver().GetFilePath(Name, this);
|
return Host.getDriver().GetFilePath(Name, *this);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::sys::Path ToolChain::GetProgramPath(const Compilation &C,
|
llvm::sys::Path ToolChain::GetProgramPath(const Compilation &C,
|
||||||
const char *Name) const {
|
const char *Name) const {
|
||||||
return Host.getDriver().GetProgramPath(Name, this);
|
return Host.getDriver().GetProgramPath(Name, *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ToolChain::ShouldUseClangCompiler(const Compilation &C,
|
bool ToolChain::ShouldUseClangCompiler(const Compilation &C,
|
||||||
|
|
Loading…
Reference in New Issue