jlebar created this revision.
jlebar added a reviewer: echristo.
jlebar added a subscriber: cfe-commits.
jlebar added a dependency: D15910: Make isa, cast, dyn_cast, etc. work with
std::unique_ptr and std::shared_ptr..
Herald added a subscriber: klimek.
This makes constructing Action graphs which are DAGs much simpler. It
also just simplifies in general the ownership semantics of Actions.
Depends on D15910.
http://reviews.llvm.org/D15911
Files:
include/clang/Driver/Action.h
include/clang/Driver/Driver.h
include/clang/Driver/Util.h
lib/Driver/Action.cpp
lib/Driver/Compilation.cpp
lib/Driver/Driver.cpp
lib/Driver/Tools.cpp
lib/Tooling/CompilationDatabase.cpp
Index: lib/Tooling/CompilationDatabase.cpp
===================================================================
--- lib/Tooling/CompilationDatabase.cpp
+++ lib/Tooling/CompilationDatabase.cpp
@@ -141,7 +141,7 @@
for (driver::ActionList::const_iterator I = A->begin(), E = A->end();
I != E; ++I)
- runImpl(*I, CollectChildren);
+ runImpl(I->get(), CollectChildren);
}
};
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -2455,7 +2455,7 @@
return true;
for (const auto &Act : *A)
- if (ContainsCompileAction(Act))
+ if (ContainsCompileAction(Act.get()))
return true;
return false;
@@ -2472,7 +2472,7 @@
if (RelaxDefault) {
RelaxDefault = false;
for (const auto &Act : C.getActions()) {
- if (ContainsCompileAction(Act)) {
+ if (ContainsCompileAction(Act.get())) {
RelaxDefault = true;
break;
}
@@ -5922,7 +5922,7 @@
const Action *SourceAction = &JA;
while (SourceAction->getKind() != Action::InputClass) {
assert(!SourceAction->getInputs().empty() && "unexpected root action!");
- SourceAction = SourceAction->getInputs()[0];
+ SourceAction = SourceAction->getInputs()[0].get();
}
// Forward -g and handle debug info related flags, assuming we are dealing
@@ -6833,7 +6833,7 @@
const Action *SourceAction = &JA;
while (SourceAction->getKind() != Action::InputClass) {
assert(!SourceAction->getInputs().empty() && "unexpected root action!");
- SourceAction = SourceAction->getInputs()[0];
+ SourceAction = SourceAction->getInputs()[0].get();
}
// If -fno-integrated-as is used add -Q to the darwin assember driver to make
Index: lib/Driver/Driver.cpp
===================================================================
--- lib/Driver/Driver.cpp
+++ lib/Driver/Driver.cpp
@@ -934,36 +934,36 @@
// Display an action graph human-readably. Action A is the "sink" node
// and latest-occuring action. Traversal is in pre-order, visiting the
// inputs to each action before printing the action itself.
-static unsigned PrintActions1(const Compilation &C, Action *A,
- std::map<Action *, unsigned> &Ids) {
+static unsigned PrintActions1(const Compilation &C, const Action *A,
+ std::map<const Action *, unsigned> &Ids) {
if (Ids.count(A)) // A was already visited.
return Ids[A];
std::string str;
llvm::raw_string_ostream os(str);
os << Action::getClassName(A->getKind()) << ", ";
- if (InputAction *IA = dyn_cast<InputAction>(A)) {
+ if (const InputAction *IA = dyn_cast<InputAction>(A)) {
os << "\"" << IA->getInputArg().getValue() << "\"";
- } else if (BindArchAction *BIA = dyn_cast<BindArchAction>(A)) {
+ } else if (const BindArchAction *BIA = dyn_cast<BindArchAction>(A)) {
os << '"' << BIA->getArchName() << '"' << ", {"
- << PrintActions1(C, *BIA->begin(), Ids) << "}";
- } else if (CudaDeviceAction *CDA = dyn_cast<CudaDeviceAction>(A)) {
+ << PrintActions1(C, BIA->begin()->get(), Ids) << "}";
+ } else if (const CudaDeviceAction *CDA = dyn_cast<CudaDeviceAction>(A)) {
os << '"' << CDA->getGpuArchName() << '"' << ", {"
- << PrintActions1(C, *CDA->begin(), Ids) << "}";
+ << PrintActions1(C, CDA->begin()->get(), Ids) << "}";
} else {
const ActionList *AL;
- if (CudaHostAction *CHA = dyn_cast<CudaHostAction>(A)) {
- os << "{" << PrintActions1(C, *CHA->begin(), Ids) << "}"
+ if (const CudaHostAction *CHA = dyn_cast<CudaHostAction>(A)) {
+ os << "{" << PrintActions1(C, CHA->begin()->get(), Ids) << "}"
<< ", gpu binaries ";
AL = &CHA->getDeviceActions();
} else
AL = &A->getInputs();
if (AL->size()) {
const char *Prefix = "{";
- for (Action *PreRequisite : *AL) {
- os << Prefix << PrintActions1(C, PreRequisite, Ids);
+ for (const std::shared_ptr<Action> &PreRequisite : *AL) {
+ os << Prefix << PrintActions1(C, PreRequisite.get(), Ids);
Prefix = ", ";
}
os << "}";
@@ -982,9 +982,9 @@
// Print the action graphs in a compilation C.
// For example "clang -c file1.c file2.c" is composed of two subgraphs.
void Driver::PrintActions(const Compilation &C) const {
- std::map<Action *, unsigned> Ids;
- for (Action *A : C.getActions())
- PrintActions1(C, A, Ids);
+ std::map<const Action *, unsigned> Ids;
+ for (const std::shared_ptr<Action> &A : C.getActions())
+ PrintActions1(C, A.get(), Ids);
}
/// \brief Check whether the given input tree contains any compilation or
@@ -994,8 +994,8 @@
isa<AssembleJobAction>(A))
return true;
- for (const Action *Input : *A)
- if (ContainsCompileOrAssembleAction(Input))
+ for (const std::shared_ptr<Action> Input : *A)
+ if (ContainsCompileOrAssembleAction(Input.get()))
return true;
return false;
@@ -1037,7 +1037,7 @@
// Add in arch bindings for every top level action, as well as lipo and
// dsymutil steps if needed.
- for (Action* Act : SingleActions) {
+ for (const std::shared_ptr<Action> &Act : SingleActions) {
// Make sure we can lipo this kind of output. If not (and it is an actual
// output) then we disallow, since we can't create an output file with the
// right name without overwriting it. We could remove this oddity by just
@@ -1050,24 +1050,22 @@
ActionList Inputs;
for (unsigned i = 0, e = Archs.size(); i != e; ++i) {
- Inputs.push_back(
- new BindArchAction(std::unique_ptr<Action>(Act), Archs[i]));
- if (i != 0)
- Inputs.back()->setOwnsInputs(false);
+ Inputs.push_back(std::make_shared<BindArchAction>(Act, Archs[i]));
}
// Lipo if necessary, we do it this way because we need to set the arch flag
// so that -Xarch_ gets overwritten.
if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
Actions.append(Inputs.begin(), Inputs.end());
else
- Actions.push_back(new LipoJobAction(Inputs, Act->getType()));
+ Actions.push_back(
+ std::make_shared<LipoJobAction>(Inputs, Act->getType()));
// Handle debug info queries.
Arg *A = Args.getLastArg(options::OPT_g_Group);
if (A && !A->getOption().matches(options::OPT_g0) &&
!A->getOption().matches(options::OPT_gstabs) &&
- ContainsCompileOrAssembleAction(Actions.back())) {
+ ContainsCompileOrAssembleAction(Actions.back().get())) {
// Add a 'dsymutil' step if necessary, when debug info is enabled and we
// have a compile input. We need to run 'dsymutil' ourselves in such cases
@@ -1077,15 +1075,16 @@
ActionList Inputs;
Inputs.push_back(Actions.back());
Actions.pop_back();
- Actions.push_back(new DsymutilJobAction(Inputs, types::TY_dSYM));
+ Actions.push_back(
+ std::make_shared<DsymutilJobAction>(Inputs, types::TY_dSYM));
}
// Verify the debug info output.
if (Args.hasArg(options::OPT_verify_debug_info)) {
- std::unique_ptr<Action> VerifyInput(Actions.back());
+ std::shared_ptr<Action> LastAction = Actions.back();
Actions.pop_back();
- Actions.push_back(new VerifyDebugInfoJobAction(std::move(VerifyInput),
- types::TY_Nothing));
+ Actions.push_back(std::make_shared<VerifyDebugInfoJobAction>(
+ LastAction, types::TY_Nothing));
}
}
}
@@ -1283,16 +1282,16 @@
// Actions and /p Current is released. Otherwise the function creates
// and returns a new CudaHostAction which wraps /p Current and device
// side actions.
-static std::unique_ptr<Action>
+static std::shared_ptr<Action>
buildCudaActions(Compilation &C, DerivedArgList &Args, const Arg *InputArg,
- std::unique_ptr<Action> HostAction, ActionList &Actions) {
+ std::shared_ptr<Action> HostAction, ActionList &Actions) {
Arg *PartialCompilationArg = Args.getLastArg(options::OPT_cuda_host_only,
options::OPT_cuda_device_only);
// Host-only compilation case.
if (PartialCompilationArg &&
PartialCompilationArg->getOption().matches(options::OPT_cuda_host_only))
- return std::unique_ptr<Action>(
- new CudaHostAction(std::move(HostAction), {}));
+ return std::make_shared<CudaHostAction>(std::move(HostAction),
+ ActionList());
// Collect all cuda_gpu_arch parameters, removing duplicates.
SmallVector<const char *, 4> GpuArchList;
@@ -1350,26 +1349,25 @@
}
for (unsigned I = 0, E = GpuArchList.size(); I != E; ++I)
- Actions.push_back(new CudaDeviceAction(
- std::unique_ptr<Action>(CudaDeviceActions[I]), GpuArchList[I],
+ Actions.push_back(std::make_shared<CudaDeviceAction>(
+ CudaDeviceActions[I], GpuArchList[I],
/* AtTopLevel */ true));
// Kill host action in case of device-only compilation.
if (DeviceOnlyCompilation)
- HostAction.reset(nullptr);
+ return nullptr;
return HostAction;
}
// Outputs of device actions during complete CUDA compilation get created
// with AtTopLevel=false and become inputs for the host action.
ActionList DeviceActions;
for (unsigned I = 0, E = GpuArchList.size(); I != E; ++I)
- DeviceActions.push_back(new CudaDeviceAction(
- std::unique_ptr<Action>(CudaDeviceActions[I]), GpuArchList[I],
- /* AtTopLevel */ false));
+ DeviceActions.push_back(
+ std::make_shared<CudaDeviceAction>(CudaDeviceActions[I], GpuArchList[I],
+ /* AtTopLevel */ false));
// Return a new host action that incorporates original host action and all
// device actions.
- return std::unique_ptr<Action>(
- new CudaHostAction(std::move(HostAction), DeviceActions));
+ return std::make_shared<CudaHostAction>(std::move(HostAction), DeviceActions);
}
void Driver::BuildActions(Compilation &C, const ToolChain &TC,
@@ -1478,7 +1476,8 @@
}
// Build the pipeline for this file.
- std::unique_ptr<Action> Current(new InputAction(*InputArg, InputType));
+ std::shared_ptr<Action> Current =
+ std::make_shared<InputAction>(*InputArg, InputType);
for (SmallVectorImpl<phases::ID>::iterator i = PL.begin(), e = PL.end();
i != e; ++i) {
phases::ID Phase = *i;
@@ -1490,7 +1489,7 @@
// Queue linker inputs.
if (Phase == phases::Link) {
assert((i + 1) == e && "linking must be final compilation step.");
- LinkerInputs.push_back(Current.release());
+ LinkerInputs.push_back(std::move(Current));
break;
}
@@ -1516,12 +1515,13 @@
// If we ended with something, add to the output list.
if (Current)
- Actions.push_back(Current.release());
+ Actions.push_back(std::move(Current));
}
// Add a link action if necessary.
if (!LinkerInputs.empty())
- Actions.push_back(new LinkJobAction(LinkerInputs, types::TY_Image));
+ Actions.push_back(
+ std::make_shared<LinkJobAction>(LinkerInputs, types::TY_Image));
// If we are linking, claim any options which are obviously only used for
// compilation.
@@ -1538,10 +1538,10 @@
Args.ClaimAllArgs(options::OPT_cuda_host_only);
}
-std::unique_ptr<Action>
+std::shared_ptr<Action>
Driver::ConstructPhaseAction(const ToolChain &TC, const ArgList &Args,
phases::ID Phase,
- std::unique_ptr<Action> Input) const {
+ std::shared_ptr<Action> Input) const {
llvm::PrettyStackTraceString CrashInfo("Constructing phase actions");
// Build the appropriate action.
switch (Phase) {
@@ -1630,7 +1630,7 @@
// files.
if (FinalOutput) {
unsigned NumOutputs = 0;
- for (const Action *A : C.getActions())
+ for (const std::shared_ptr<Action> &A : C.getActions())
if (A->getType() != types::TY_Nothing)
++NumOutputs;
@@ -1647,7 +1647,7 @@
if (A->getOption().matches(options::OPT_arch))
ArchNames.insert(A->getValue());
- for (Action *A : C.getActions()) {
+ for (const std::shared_ptr<Action>& A : C.getActions()) {
// If we are linking an image for multiple archs then the linker wants
// -arch_multiple and -final_output <final image name>. Unfortunately, this
// doesn't fit in cleanly because we have to pass this information down.
@@ -1663,7 +1663,7 @@
}
InputInfo II;
- BuildJobsForAction(C, A, &C.getDefaultToolChain(),
+ BuildJobsForAction(C, A.get(), &C.getDefaultToolChain(),
/*BoundArch*/ nullptr,
/*AtTopLevel*/ true,
/*MultipleArchs*/ ArchNames.size() > 1,
@@ -1806,14 +1806,14 @@
if (const CudaHostAction *CHA = dyn_cast<CudaHostAction>(A)) {
InputInfo II;
// Append outputs of device jobs to the input list.
- for (const Action *DA : CHA->getDeviceActions()) {
- BuildJobsForAction(C, DA, TC, nullptr, AtTopLevel,
+ for (const std::shared_ptr<Action> &DA : CHA->getDeviceActions()) {
+ BuildJobsForAction(C, DA.get(), TC, nullptr, AtTopLevel,
/*MultipleArchs*/ false, LinkingOutput, II);
CudaDeviceInputInfos.push_back(II);
}
// Override current action with a real host compile action and continue
// processing it.
- A = *CHA->begin();
+ A = CHA->begin()->get();
}
if (const InputAction *IA = dyn_cast<InputAction>(A)) {
@@ -1841,16 +1841,16 @@
else
TC = &C.getDefaultToolChain();
- BuildJobsForAction(C, *BAA->begin(), TC, ArchName, AtTopLevel,
+ BuildJobsForAction(C, BAA->begin()->get(), TC, ArchName, AtTopLevel,
MultipleArchs, LinkingOutput, Result);
return;
}
if (const CudaDeviceAction *CDA = dyn_cast<CudaDeviceAction>(A)) {
// Initial processing of CudaDeviceAction carries host params.
// Call BuildJobsForAction() again, now with correct device parameters.
assert(CDA->getGpuArchName() && "No GPU name in device action.");
- BuildJobsForAction(C, *CDA->begin(), C.getCudaDeviceToolChain(),
+ BuildJobsForAction(C, CDA->begin()->get(), C.getCudaDeviceToolChain(),
CDA->getGpuArchName(), CDA->isAtTopLevel(),
/*MultipleArchs*/ true, LinkingOutput, Result);
return;
@@ -1869,26 +1869,26 @@
// need to build jobs for device-side inputs it may have held.
if (CollapsedCHA) {
InputInfo II;
- for (const Action *DA : CollapsedCHA->getDeviceActions()) {
- BuildJobsForAction(C, DA, TC, "", AtTopLevel,
+ for (const std::shared_ptr<Action> &DA : CollapsedCHA->getDeviceActions()) {
+ BuildJobsForAction(C, DA.get(), TC, "", AtTopLevel,
/*MultipleArchs*/ false, LinkingOutput, II);
CudaDeviceInputInfos.push_back(II);
}
}
// Only use pipes when there is exactly one input.
InputInfoList InputInfos;
- for (const Action *Input : *Inputs) {
+ for (const std::shared_ptr<Action> &Input : *Inputs) {
// Treat dsymutil and verify sub-jobs as being at the top-level too, they
// shouldn't get temporary output names.
// FIXME: Clean this up.
bool SubJobAtTopLevel = false;
if (AtTopLevel && (isa<DsymutilJobAction>(A) || isa<VerifyJobAction>(A)))
SubJobAtTopLevel = true;
InputInfo II;
- BuildJobsForAction(C, Input, TC, BoundArch, SubJobAtTopLevel, MultipleArchs,
- LinkingOutput, II);
+ BuildJobsForAction(C, Input.get(), TC, BoundArch, SubJobAtTopLevel,
+ MultipleArchs, LinkingOutput, II);
InputInfos.push_back(II);
}
Index: lib/Driver/Compilation.cpp
===================================================================
--- lib/Driver/Compilation.cpp
+++ lib/Driver/Compilation.cpp
@@ -40,11 +40,6 @@
if (it->second != TranslatedArgs)
delete it->second;
- // Free the actions, if built.
- for (ActionList::iterator it = Actions.begin(), ie = Actions.end();
- it != ie; ++it)
- delete *it;
-
// Free redirections of stdout/stderr.
if (Redirects) {
delete Redirects[1];
@@ -182,7 +177,7 @@
return true;
for (Action::const_iterator AI = A->begin(), AE = A->end(); AI != AE; ++AI)
- if (ActionFailed(*AI, FailingCommands))
+ if (ActionFailed(AI->get(), FailingCommands))
return true;
return false;
@@ -208,7 +203,7 @@
ForDiagnostics = true;
// Free actions and jobs.
- DeleteContainerPointers(Actions);
+ Actions.clear();
Jobs.clear();
// Clear temporary/results file lists.
Index: lib/Driver/Action.cpp
===================================================================
--- lib/Driver/Action.cpp
+++ lib/Driver/Action.cpp
@@ -13,12 +13,7 @@
using namespace clang::driver;
using namespace llvm::opt;
-Action::~Action() {
- if (OwnsInputs) {
- for (iterator it = begin(), ie = end(); it != ie; ++it)
- delete *it;
- }
-}
+Action::~Action() {}
const char *Action::getClassName(ActionClass AC) {
switch (AC) {
@@ -51,31 +46,28 @@
void BindArchAction::anchor() {}
-BindArchAction::BindArchAction(std::unique_ptr<Action> Input,
+BindArchAction::BindArchAction(std::shared_ptr<Action> Input,
const char *_ArchName)
: Action(BindArchClass, std::move(Input)), ArchName(_ArchName) {}
void CudaDeviceAction::anchor() {}
-CudaDeviceAction::CudaDeviceAction(std::unique_ptr<Action> Input,
+CudaDeviceAction::CudaDeviceAction(std::shared_ptr<Action> Input,
const char *ArchName, bool AtTopLevel)
: Action(CudaDeviceClass, std::move(Input)), GpuArchName(ArchName),
AtTopLevel(AtTopLevel) {}
void CudaHostAction::anchor() {}
-CudaHostAction::CudaHostAction(std::unique_ptr<Action> Input,
+CudaHostAction::CudaHostAction(std::shared_ptr<Action> Input,
const ActionList &DeviceActions)
: Action(CudaHostClass, std::move(Input)), DeviceActions(DeviceActions) {}
-CudaHostAction::~CudaHostAction() {
- for (auto &DA : DeviceActions)
- delete DA;
-}
+CudaHostAction::~CudaHostAction() {}
void JobAction::anchor() {}
-JobAction::JobAction(ActionClass Kind, std::unique_ptr<Action> Input,
+JobAction::JobAction(ActionClass Kind, std::shared_ptr<Action> Input,
types::ID Type)
: Action(Kind, std::move(Input), Type) {}
@@ -85,43 +77,43 @@
void PreprocessJobAction::anchor() {}
-PreprocessJobAction::PreprocessJobAction(std::unique_ptr<Action> Input,
+PreprocessJobAction::PreprocessJobAction(std::shared_ptr<Action> Input,
types::ID OutputType)
: JobAction(PreprocessJobClass, std::move(Input), OutputType) {}
void PrecompileJobAction::anchor() {}
-PrecompileJobAction::PrecompileJobAction(std::unique_ptr<Action> Input,
+PrecompileJobAction::PrecompileJobAction(std::shared_ptr<Action> Input,
types::ID OutputType)
: JobAction(PrecompileJobClass, std::move(Input), OutputType) {}
void AnalyzeJobAction::anchor() {}
-AnalyzeJobAction::AnalyzeJobAction(std::unique_ptr<Action> Input,
+AnalyzeJobAction::AnalyzeJobAction(std::shared_ptr<Action> Input,
types::ID OutputType)
: JobAction(AnalyzeJobClass, std::move(Input), OutputType) {}
void MigrateJobAction::anchor() {}
-MigrateJobAction::MigrateJobAction(std::unique_ptr<Action> Input,
+MigrateJobAction::MigrateJobAction(std::shared_ptr<Action> Input,
types::ID OutputType)
: JobAction(MigrateJobClass, std::move(Input), OutputType) {}
void CompileJobAction::anchor() {}
-CompileJobAction::CompileJobAction(std::unique_ptr<Action> Input,
+CompileJobAction::CompileJobAction(std::shared_ptr<Action> Input,
types::ID OutputType)
: JobAction(CompileJobClass, std::move(Input), OutputType) {}
void BackendJobAction::anchor() {}
-BackendJobAction::BackendJobAction(std::unique_ptr<Action> Input,
+BackendJobAction::BackendJobAction(std::shared_ptr<Action> Input,
types::ID OutputType)
: JobAction(BackendJobClass, std::move(Input), OutputType) {}
void AssembleJobAction::anchor() {}
-AssembleJobAction::AssembleJobAction(std::unique_ptr<Action> Input,
+AssembleJobAction::AssembleJobAction(std::shared_ptr<Action> Input,
types::ID OutputType)
: JobAction(AssembleJobClass, std::move(Input), OutputType) {}
@@ -146,20 +138,20 @@
void VerifyJobAction::anchor() {}
VerifyJobAction::VerifyJobAction(ActionClass Kind,
- std::unique_ptr<Action> Input, types::ID Type)
+ std::shared_ptr<Action> Input, types::ID Type)
: JobAction(Kind, std::move(Input), Type) {
assert((Kind == VerifyDebugInfoJobClass || Kind == VerifyPCHJobClass) &&
"ActionClass is not a valid VerifyJobAction");
}
void VerifyDebugInfoJobAction::anchor() {}
VerifyDebugInfoJobAction::VerifyDebugInfoJobAction(
- std::unique_ptr<Action> Input, types::ID Type)
+ std::shared_ptr<Action> Input, types::ID Type)
: VerifyJobAction(VerifyDebugInfoJobClass, std::move(Input), Type) {}
void VerifyPCHJobAction::anchor() {}
-VerifyPCHJobAction::VerifyPCHJobAction(std::unique_ptr<Action> Input,
+VerifyPCHJobAction::VerifyPCHJobAction(std::shared_ptr<Action> Input,
types::ID Type)
: VerifyJobAction(VerifyPCHJobClass, std::move(Input), Type) {}
Index: include/clang/Driver/Util.h
===================================================================
--- include/clang/Driver/Util.h
+++ include/clang/Driver/Util.h
@@ -24,7 +24,7 @@
typedef llvm::DenseMap<const JobAction*, const char*> ArgStringMap;
/// ActionList - Type used for lists of actions.
- typedef SmallVector<Action*, 3> ActionList;
+ typedef SmallVector<std::shared_ptr<Action>, 3> ActionList;
} // end namespace driver
} // end namespace clang
Index: include/clang/Driver/Driver.h
===================================================================
--- include/clang/Driver/Driver.h
+++ include/clang/Driver/Driver.h
@@ -375,9 +375,9 @@
/// ConstructAction - Construct the appropriate action to do for
/// \p Phase on the \p Input, taking in to account arguments
/// like -fsyntax-only or --analyze.
- std::unique_ptr<Action>
+ std::shared_ptr<Action>
ConstructPhaseAction(const ToolChain &TC, const llvm::opt::ArgList &Args,
- phases::ID Phase, std::unique_ptr<Action> Input) const;
+ phases::ID Phase, std::shared_ptr<Action> Input) const;
/// BuildJobsForAction - Construct the jobs to perform for the
/// action \p A.
Index: include/clang/Driver/Action.h
===================================================================
--- include/clang/Driver/Action.h
+++ include/clang/Driver/Action.h
@@ -32,6 +32,10 @@
/// single primary output, at least in terms of controlling the
/// compilation. Actions can produce auxiliary files, but can only
/// produce a single output to feed into subsequent actions.
+///
+/// An Action keeps a std::shared_ptr to each of its inputs (in an
+/// ActionList). Using shared_ptrs lets us manage graphs of Actions that
+/// are DAGs.
class Action {
public:
typedef ActionList::size_type size_type;
@@ -70,27 +74,20 @@
ActionList Inputs;
- unsigned OwnsInputs : 1;
-
protected:
- Action(ActionClass Kind, types::ID Type)
- : Kind(Kind), Type(Type), OwnsInputs(true) {}
- Action(ActionClass Kind, std::unique_ptr<Action> Input, types::ID Type)
- : Kind(Kind), Type(Type), Inputs(1, Input.release()), OwnsInputs(true) {
- }
- Action(ActionClass Kind, std::unique_ptr<Action> Input)
- : Kind(Kind), Type(Input->getType()), Inputs(1, Input.release()),
- OwnsInputs(true) {}
+ Action(ActionClass Kind, types::ID Type) : Action(Kind, ActionList(), Type) {}
+ Action(ActionClass Kind, std::shared_ptr<Action> Input, types::ID Type)
+ : Action(Kind, ActionList({Input}), Type) {}
+ Action(ActionClass Kind, std::shared_ptr<Action> Input)
+ : Action(Kind, ActionList({Input}), Input->getType()) {}
Action(ActionClass Kind, const ActionList &Inputs, types::ID Type)
- : Kind(Kind), Type(Type), Inputs(Inputs), OwnsInputs(true) {}
+ : Kind(Kind), Type(Type), Inputs(Inputs) {}
+
public:
virtual ~Action();
const char *getClassName() const { return Action::getClassName(getKind()); }
- bool getOwnsInputs() { return OwnsInputs; }
- void setOwnsInputs(bool Value) { OwnsInputs = Value; }
-
ActionClass getKind() const { return Kind; }
types::ID getType() const { return Type; }
@@ -126,7 +123,7 @@
const char *ArchName;
public:
- BindArchAction(std::unique_ptr<Action> Input, const char *ArchName);
+ BindArchAction(std::shared_ptr<Action> Input, const char *ArchName);
const char *getArchName() const { return ArchName; }
@@ -144,7 +141,7 @@
bool AtTopLevel;
public:
- CudaDeviceAction(std::unique_ptr<Action> Input, const char *ArchName,
+ CudaDeviceAction(std::shared_ptr<Action> Input, const char *ArchName,
bool AtTopLevel);
const char *getGpuArchName() const { return GpuArchName; }
@@ -160,7 +157,7 @@
ActionList DeviceActions;
public:
- CudaHostAction(std::unique_ptr<Action> Input,
+ CudaHostAction(std::shared_ptr<Action> Input,
const ActionList &DeviceActions);
~CudaHostAction() override;
@@ -172,7 +169,7 @@
class JobAction : public Action {
virtual void anchor();
protected:
- JobAction(ActionClass Kind, std::unique_ptr<Action> Input, types::ID Type);
+ JobAction(ActionClass Kind, std::shared_ptr<Action> Input, types::ID Type);
JobAction(ActionClass Kind, const ActionList &Inputs, types::ID Type);
public:
@@ -185,7 +182,7 @@
class PreprocessJobAction : public JobAction {
void anchor() override;
public:
- PreprocessJobAction(std::unique_ptr<Action> Input, types::ID OutputType);
+ PreprocessJobAction(std::shared_ptr<Action> Input, types::ID OutputType);
static bool classof(const Action *A) {
return A->getKind() == PreprocessJobClass;
@@ -195,7 +192,7 @@
class PrecompileJobAction : public JobAction {
void anchor() override;
public:
- PrecompileJobAction(std::unique_ptr<Action> Input, types::ID OutputType);
+ PrecompileJobAction(std::shared_ptr<Action> Input, types::ID OutputType);
static bool classof(const Action *A) {
return A->getKind() == PrecompileJobClass;
@@ -205,7 +202,7 @@
class AnalyzeJobAction : public JobAction {
void anchor() override;
public:
- AnalyzeJobAction(std::unique_ptr<Action> Input, types::ID OutputType);
+ AnalyzeJobAction(std::shared_ptr<Action> Input, types::ID OutputType);
static bool classof(const Action *A) {
return A->getKind() == AnalyzeJobClass;
@@ -215,7 +212,7 @@
class MigrateJobAction : public JobAction {
void anchor() override;
public:
- MigrateJobAction(std::unique_ptr<Action> Input, types::ID OutputType);
+ MigrateJobAction(std::shared_ptr<Action> Input, types::ID OutputType);
static bool classof(const Action *A) {
return A->getKind() == MigrateJobClass;
@@ -225,7 +222,7 @@
class CompileJobAction : public JobAction {
void anchor() override;
public:
- CompileJobAction(std::unique_ptr<Action> Input, types::ID OutputType);
+ CompileJobAction(std::shared_ptr<Action> Input, types::ID OutputType);
static bool classof(const Action *A) {
return A->getKind() == CompileJobClass;
@@ -235,7 +232,7 @@
class BackendJobAction : public JobAction {
void anchor() override;
public:
- BackendJobAction(std::unique_ptr<Action> Input, types::ID OutputType);
+ BackendJobAction(std::shared_ptr<Action> Input, types::ID OutputType);
static bool classof(const Action *A) {
return A->getKind() == BackendJobClass;
@@ -245,7 +242,7 @@
class AssembleJobAction : public JobAction {
void anchor() override;
public:
- AssembleJobAction(std::unique_ptr<Action> Input, types::ID OutputType);
+ AssembleJobAction(std::shared_ptr<Action> Input, types::ID OutputType);
static bool classof(const Action *A) {
return A->getKind() == AssembleJobClass;
@@ -285,7 +282,7 @@
class VerifyJobAction : public JobAction {
void anchor() override;
public:
- VerifyJobAction(ActionClass Kind, std::unique_ptr<Action> Input,
+ VerifyJobAction(ActionClass Kind, std::shared_ptr<Action> Input,
types::ID Type);
static bool classof(const Action *A) {
return A->getKind() == VerifyDebugInfoJobClass ||
@@ -296,16 +293,16 @@
class VerifyDebugInfoJobAction : public VerifyJobAction {
void anchor() override;
public:
- VerifyDebugInfoJobAction(std::unique_ptr<Action> Input, types::ID Type);
+ VerifyDebugInfoJobAction(std::shared_ptr<Action> Input, types::ID Type);
static bool classof(const Action *A) {
return A->getKind() == VerifyDebugInfoJobClass;
}
};
class VerifyPCHJobAction : public VerifyJobAction {
void anchor() override;
public:
- VerifyPCHJobAction(std::unique_ptr<Action> Input, types::ID Type);
+ VerifyPCHJobAction(std::shared_ptr<Action> Input, types::ID Type);
static bool classof(const Action *A) {
return A->getKind() == VerifyPCHJobClass;
}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits