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:
Daniel Dunbar 2009-03-18 02:55:38 +00:00
parent 8df898917f
commit f0eddb8510
6 changed files with 83 additions and 60 deletions

View File

@ -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

View File

@ -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

View File

@ -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) {

View File

@ -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) {

View File

@ -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);
} }

View File

@ -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,