From: Daniel Dunbar Date: Wed, 18 Mar 2009 02:55:38 +0000 (+0000) Subject: Driver: Move actions into Compilation, and construct the compilation X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=21549237f14505cfc2a18a06416372a36229d0ce;p=clang 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67158 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Driver/Compilation.h b/include/clang/Driver/Compilation.h index 4581386769..91e6dc6f44 100644 --- a/include/clang/Driver/Compilation.h +++ b/include/clang/Driver/Compilation.h @@ -30,6 +30,9 @@ class Compilation { /// The original (untranslated) input argument list. ArgList *Args; + /// The list of actions. + ActionList Actions; + /// The root list of jobs. JobList Jobs; @@ -46,7 +49,13 @@ public: Compilation(ToolChain &DefaultToolChain, ArgList *Args); ~Compilation(); + const ToolChain &getDefaultToolChain() const { return DefaultToolChain; } + const ArgList &getArgs() const { return *Args; } + + ActionList &getActions() { return Actions; } + const ActionList &getActions() const { return Actions; } + JobList &getJobs() { return Jobs; } /// getArgsForToolChain - Return the argument list, possibly diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h index 02ee6116ad..807b108a3d 100644 --- a/include/clang/Driver/Driver.h +++ b/include/clang/Driver/Driver.h @@ -138,20 +138,24 @@ public: /// /// \param Args - The input arguments. /// \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 /// for the given arguments, which may require a universal build. /// /// \param Args - The input arguments. /// \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 /// arguments to form the list of jobs to run. /// /// \arg C - The compilation that is being built. - void BuildJobs(Compilation &C, const ActionList &Actions) const; + void BuildJobs(Compilation &C) const; /// @} /// @name Helper Methods @@ -168,27 +172,25 @@ public: /// GetFilePath - Lookup \arg Name in the list of file search paths. /// - /// \arg TC - Use the provided tool chain for additional information - /// on directories to search, or the DefaultToolChain if not - /// provided. + /// \arg TC - The tool chain for additional information on + /// directories to search. // 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 /// paths. /// - /// \arg TC - Use the provided tool chain for additional information - /// on directories to search, or the DefaultToolChain if not - /// provided. + /// \arg TC - The provided tool chain for additional information on + /// directories to search. // 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 /// treated before building actions or binding tools. /// /// \return Whether any compilation should be built for this /// invocation. - bool HandleImmediateArgs(const ArgList &Args); + bool HandleImmediateArgs(const Compilation &C); /// ConstructAction - Construct the appropriate action to do for /// \arg Phase on the \arg Input, taking in to account arguments diff --git a/lib/Driver/Action.cpp b/lib/Driver/Action.cpp index aafb589f42..71bf22ffa1 100644 --- a/lib/Driver/Action.cpp +++ b/lib/Driver/Action.cpp @@ -12,7 +12,11 @@ #include 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) { switch (AC) { diff --git a/lib/Driver/Compilation.cpp b/lib/Driver/Compilation.cpp index 949bbe7d6b..b35bf2402d 100644 --- a/lib/Driver/Compilation.cpp +++ b/lib/Driver/Compilation.cpp @@ -9,6 +9,7 @@ #include "clang/Driver/Compilation.h" +#include "clang/Driver/Action.h" #include "clang/Driver/ArgList.h" #include "clang/Driver/ToolChain.h" @@ -29,6 +30,11 @@ Compilation::~Compilation() { if (A != 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) { diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index 2538ed8384..f60271c02e 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -166,31 +166,33 @@ Compilation *Driver::BuildCompilation(int argc, const char **argv) { // is part of the compilation (it is arg dependent). DefaultToolChain = Host->getToolChain(*Args); + // The compilation takes ownership of Args. + Compilation *C = new Compilation(*DefaultToolChain, Args); + // FIXME: This behavior shouldn't be here. if (CCCPrintOptions) { - PrintOptions(*Args); - return 0; + PrintOptions(C->getArgs()); + return C; } - if (!HandleImmediateArgs(*Args)) - return 0; + if (!HandleImmediateArgs(*C)) + return C; // Construct the list of abstract actions to perform for this - // compilation. - ActionList Actions; + // 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(*Args, Actions); + BuildUniversalActions(C->getArgs(), C->getActions()); else - BuildActions(*Args, Actions); + BuildActions(C->getArgs(), C->getActions()); if (CCCPrintActions) { - PrintActions(*Args, Actions); - return 0; + PrintActions(C->getArgs(), C->getActions()); + return C; } - // The compilation takes ownership of Args. - Compilation *C = new Compilation(*DefaultToolChain, Args); - BuildJobs(*C, Actions); + BuildJobs(*C); return C; } @@ -220,30 +222,33 @@ void Driver::PrintVersion() const { 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 // place, but we don't expect inconsistencies w.r.t. that to matter // in practice. - if (Args.hasArg(options::OPT_v) || - Args.hasArg(options::OPT__HASH_HASH_HASH)) { + if (C.getArgs().hasArg(options::OPT_v) || + C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) { PrintVersion(); SuppressMissingInputWarning = true; } + const ToolChain &TC = C.getDefaultToolChain(); // FIXME: The following handlers should use a callback mechanism, we // don't know what the client would like to do. - if (Arg *A = Args.getLastArg(options::OPT_print_file_name_EQ)) { - llvm::outs() << GetFilePath(A->getValue(Args)).toString() << "\n"; + if (Arg *A = C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) { + llvm::outs() << GetFilePath(A->getValue(C.getArgs()), TC).toString() + << "\n"; return false; } - if (Arg *A = Args.getLastArg(options::OPT_print_prog_name_EQ)) { - llvm::outs() << GetProgramPath(A->getValue(Args)).toString() << "\n"; + if (Arg *A = C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) { + llvm::outs() << GetProgramPath(A->getValue(C.getArgs()), TC).toString() + << "\n"; return false; } - if (Args.hasArg(options::OPT_print_libgcc_file_name)) { - llvm::outs() << GetProgramPath("libgcc.a").toString() << "\n"; + if (C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) { + llvm::outs() << GetProgramPath("libgcc.a", TC).toString() << "\n"; return false; } @@ -292,7 +297,8 @@ void Driver::PrintActions(const ArgList &Args, 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"); // Collect the list of architectures. Duplicates are allowed, but // 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"); // 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; } -void Driver::BuildJobs(Compilation &C, const ActionList &Actions) const { +void Driver::BuildJobs(Compilation &C) const { llvm::PrettyStackTraceString CrashInfo("Building compilation jobs"); bool SaveTemps = C.getArgs().hasArg(options::OPT_save_temps); bool UsePipes = C.getArgs().hasArg(options::OPT_pipe); @@ -604,8 +610,8 @@ void Driver::BuildJobs(Compilation &C, const ActionList &Actions) const { // output files. if (FinalOutput) { unsigned NumOutputs = 0; - for (ActionList::const_iterator it = Actions.begin(), ie = Actions.end(); - it != ie; ++it) + for (ActionList::const_iterator it = C.getActions().begin(), + ie = C.getActions().end(); it != ie; ++it) if ((*it)->getType() != types::TY_Nothing) ++NumOutputs; @@ -615,8 +621,8 @@ void Driver::BuildJobs(Compilation &C, const ActionList &Actions) const { } } - for (ActionList::const_iterator it = Actions.begin(), ie = Actions.end(); - it != ie; ++it) { + for (ActionList::const_iterator it = C.getActions().begin(), + ie = C.getActions().end(); it != ie; ++it) { Action *A = *it; // 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, - const ToolChain *TC) const { + const ToolChain &TC) const { // FIXME: Implement. - if (!TC) TC = DefaultToolChain; - return llvm::sys::Path(Name); } llvm::sys::Path Driver::GetProgramPath(const char *Name, - const ToolChain *TC) const { + const ToolChain &TC) const { // FIXME: Implement. - if (!TC) TC = DefaultToolChain; - return llvm::sys::Path(Name); } diff --git a/lib/Driver/ToolChain.cpp b/lib/Driver/ToolChain.cpp index 11dc9aad8f..87b169e7e9 100644 --- a/lib/Driver/ToolChain.cpp +++ b/lib/Driver/ToolChain.cpp @@ -25,13 +25,13 @@ ToolChain::~ToolChain() { llvm::sys::Path ToolChain::GetFilePath(const Compilation &C, const char *Name) const { - return Host.getDriver().GetFilePath(Name, this); + return Host.getDriver().GetFilePath(Name, *this); } llvm::sys::Path ToolChain::GetProgramPath(const Compilation &C, const char *Name) const { - return Host.getDriver().GetProgramPath(Name, this); + return Host.getDriver().GetProgramPath(Name, *this); } bool ToolChain::ShouldUseClangCompiler(const Compilation &C,