Move ownership of Action objects into Compilation.

Summary:
This makes constructing Action graphs which are DAGs much simpler.  It
also just simplifies in general the ownership semantics of Actions.

Depends on D15910.

Reviewers: echristo

Subscribers: klimek, cfe-commits

Differential Revision: http://reviews.llvm.org/D15911

llvm-svn: 257407
This commit is contained in:
Justin Lebar 2016-01-11 23:07:27 +00:00
parent f55e418247
commit 41094615fb
6 changed files with 123 additions and 157 deletions

View File

@ -32,6 +32,9 @@ namespace driver {
/// 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.
///
/// Actions are usually owned by a Compilation, which creates new
/// actions via MakeAction().
class Action {
public:
typedef ActionList::size_type size_type;
@ -70,27 +73,20 @@ private:
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, Action *Input, types::ID Type)
: Action(Kind, ActionList({Input}), Type) {}
Action(ActionClass Kind, 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 +122,7 @@ class BindArchAction : public Action {
const char *ArchName;
public:
BindArchAction(std::unique_ptr<Action> Input, const char *ArchName);
BindArchAction(Action *Input, const char *ArchName);
const char *getArchName() const { return ArchName; }
@ -144,8 +140,7 @@ class CudaDeviceAction : public Action {
bool AtTopLevel;
public:
CudaDeviceAction(std::unique_ptr<Action> Input, const char *ArchName,
bool AtTopLevel);
CudaDeviceAction(Action *Input, const char *ArchName, bool AtTopLevel);
const char *getGpuArchName() const { return GpuArchName; }
bool isAtTopLevel() const { return AtTopLevel; }
@ -160,9 +155,7 @@ class CudaHostAction : public Action {
ActionList DeviceActions;
public:
CudaHostAction(std::unique_ptr<Action> Input,
const ActionList &DeviceActions);
~CudaHostAction() override;
CudaHostAction(Action *Input, const ActionList &DeviceActions);
const ActionList &getDeviceActions() const { return DeviceActions; }
@ -172,7 +165,7 @@ public:
class JobAction : public Action {
virtual void anchor();
protected:
JobAction(ActionClass Kind, std::unique_ptr<Action> Input, types::ID Type);
JobAction(ActionClass Kind, Action *Input, types::ID Type);
JobAction(ActionClass Kind, const ActionList &Inputs, types::ID Type);
public:
@ -185,7 +178,7 @@ public:
class PreprocessJobAction : public JobAction {
void anchor() override;
public:
PreprocessJobAction(std::unique_ptr<Action> Input, types::ID OutputType);
PreprocessJobAction(Action *Input, types::ID OutputType);
static bool classof(const Action *A) {
return A->getKind() == PreprocessJobClass;
@ -195,7 +188,7 @@ public:
class PrecompileJobAction : public JobAction {
void anchor() override;
public:
PrecompileJobAction(std::unique_ptr<Action> Input, types::ID OutputType);
PrecompileJobAction(Action *Input, types::ID OutputType);
static bool classof(const Action *A) {
return A->getKind() == PrecompileJobClass;
@ -205,7 +198,7 @@ public:
class AnalyzeJobAction : public JobAction {
void anchor() override;
public:
AnalyzeJobAction(std::unique_ptr<Action> Input, types::ID OutputType);
AnalyzeJobAction(Action *Input, types::ID OutputType);
static bool classof(const Action *A) {
return A->getKind() == AnalyzeJobClass;
@ -215,7 +208,7 @@ public:
class MigrateJobAction : public JobAction {
void anchor() override;
public:
MigrateJobAction(std::unique_ptr<Action> Input, types::ID OutputType);
MigrateJobAction(Action *Input, types::ID OutputType);
static bool classof(const Action *A) {
return A->getKind() == MigrateJobClass;
@ -225,7 +218,7 @@ public:
class CompileJobAction : public JobAction {
void anchor() override;
public:
CompileJobAction(std::unique_ptr<Action> Input, types::ID OutputType);
CompileJobAction(Action *Input, types::ID OutputType);
static bool classof(const Action *A) {
return A->getKind() == CompileJobClass;
@ -235,7 +228,7 @@ public:
class BackendJobAction : public JobAction {
void anchor() override;
public:
BackendJobAction(std::unique_ptr<Action> Input, types::ID OutputType);
BackendJobAction(Action *Input, types::ID OutputType);
static bool classof(const Action *A) {
return A->getKind() == BackendJobClass;
@ -245,7 +238,7 @@ public:
class AssembleJobAction : public JobAction {
void anchor() override;
public:
AssembleJobAction(std::unique_ptr<Action> Input, types::ID OutputType);
AssembleJobAction(Action *Input, types::ID OutputType);
static bool classof(const Action *A) {
return A->getKind() == AssembleJobClass;
@ -285,8 +278,7 @@ public:
class VerifyJobAction : public JobAction {
void anchor() override;
public:
VerifyJobAction(ActionClass Kind, std::unique_ptr<Action> Input,
types::ID Type);
VerifyJobAction(ActionClass Kind, Action *Input, types::ID Type);
static bool classof(const Action *A) {
return A->getKind() == VerifyDebugInfoJobClass ||
A->getKind() == VerifyPCHJobClass;
@ -296,7 +288,7 @@ public:
class VerifyDebugInfoJobAction : public VerifyJobAction {
void anchor() override;
public:
VerifyDebugInfoJobAction(std::unique_ptr<Action> Input, types::ID Type);
VerifyDebugInfoJobAction(Action *Input, types::ID Type);
static bool classof(const Action *A) {
return A->getKind() == VerifyDebugInfoJobClass;
}
@ -305,7 +297,7 @@ public:
class VerifyPCHJobAction : public VerifyJobAction {
void anchor() override;
public:
VerifyPCHJobAction(std::unique_ptr<Action> Input, types::ID Type);
VerifyPCHJobAction(Action *Input, types::ID Type);
static bool classof(const Action *A) {
return A->getKind() == VerifyPCHJobClass;
}

View File

@ -48,7 +48,12 @@ class Compilation {
/// own argument translation.
llvm::opt::DerivedArgList *TranslatedArgs;
/// The list of actions.
/// The list of actions we've created via MakeAction. This is not accessible
/// to consumers; it's here just to manage ownership.
std::vector<std::unique_ptr<Action>> AllActions;
/// The list of actions. This is maintained and modified by consumers, via
/// getActions().
ActionList Actions;
/// The root list of jobs.
@ -105,6 +110,15 @@ public:
ActionList &getActions() { return Actions; }
const ActionList &getActions() const { return Actions; }
/// Creates a new Action owned by this Compilation.
///
/// The new Action is *not* added to the list returned by getActions().
template <typename T, typename... Args> T *MakeAction(Args &&... Arg) {
T *RawPtr = new T(std::forward<Args>(Arg)...);
AllActions.push_back(std::unique_ptr<Action>(RawPtr));
return RawPtr;
}
JobList &getJobs() { return Jobs; }
const JobList &getJobs() const { return Jobs; }

View File

@ -375,9 +375,9 @@ public:
/// 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>
ConstructPhaseAction(const ToolChain &TC, const llvm::opt::ArgList &Args,
phases::ID Phase, std::unique_ptr<Action> Input) const;
Action *ConstructPhaseAction(Compilation &C, const ToolChain &TC,
const llvm::opt::ArgList &Args, phases::ID Phase,
Action *Input) const;
/// BuildJobsForAction - Construct the jobs to perform for the
/// action \p A.

View File

@ -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,33 +46,25 @@ InputAction::InputAction(const Arg &_Input, types::ID _Type)
void BindArchAction::anchor() {}
BindArchAction::BindArchAction(std::unique_ptr<Action> Input,
const char *_ArchName)
: Action(BindArchClass, std::move(Input)), ArchName(_ArchName) {}
BindArchAction::BindArchAction(Action *Input, const char *_ArchName)
: Action(BindArchClass, Input), ArchName(_ArchName) {}
void CudaDeviceAction::anchor() {}
CudaDeviceAction::CudaDeviceAction(std::unique_ptr<Action> Input,
const char *ArchName, bool AtTopLevel)
: Action(CudaDeviceClass, std::move(Input)), GpuArchName(ArchName),
CudaDeviceAction::CudaDeviceAction(Action *Input, const char *ArchName,
bool AtTopLevel)
: Action(CudaDeviceClass, Input), GpuArchName(ArchName),
AtTopLevel(AtTopLevel) {}
void CudaHostAction::anchor() {}
CudaHostAction::CudaHostAction(std::unique_ptr<Action> Input,
const ActionList &DeviceActions)
: Action(CudaHostClass, std::move(Input)), DeviceActions(DeviceActions) {}
CudaHostAction::~CudaHostAction() {
for (auto &DA : DeviceActions)
delete DA;
}
CudaHostAction::CudaHostAction(Action *Input, const ActionList &DeviceActions)
: Action(CudaHostClass, Input), DeviceActions(DeviceActions) {}
void JobAction::anchor() {}
JobAction::JobAction(ActionClass Kind, std::unique_ptr<Action> Input,
types::ID Type)
: Action(Kind, std::move(Input), Type) {}
JobAction::JobAction(ActionClass Kind, Action *Input, types::ID Type)
: Action(Kind, Input, Type) {}
JobAction::JobAction(ActionClass Kind, const ActionList &Inputs, types::ID Type)
: Action(Kind, Inputs, Type) {
@ -85,45 +72,38 @@ JobAction::JobAction(ActionClass Kind, const ActionList &Inputs, types::ID Type)
void PreprocessJobAction::anchor() {}
PreprocessJobAction::PreprocessJobAction(std::unique_ptr<Action> Input,
types::ID OutputType)
: JobAction(PreprocessJobClass, std::move(Input), OutputType) {}
PreprocessJobAction::PreprocessJobAction(Action *Input, types::ID OutputType)
: JobAction(PreprocessJobClass, Input, OutputType) {}
void PrecompileJobAction::anchor() {}
PrecompileJobAction::PrecompileJobAction(std::unique_ptr<Action> Input,
types::ID OutputType)
: JobAction(PrecompileJobClass, std::move(Input), OutputType) {}
PrecompileJobAction::PrecompileJobAction(Action *Input, types::ID OutputType)
: JobAction(PrecompileJobClass, Input, OutputType) {}
void AnalyzeJobAction::anchor() {}
AnalyzeJobAction::AnalyzeJobAction(std::unique_ptr<Action> Input,
types::ID OutputType)
: JobAction(AnalyzeJobClass, std::move(Input), OutputType) {}
AnalyzeJobAction::AnalyzeJobAction(Action *Input, types::ID OutputType)
: JobAction(AnalyzeJobClass, Input, OutputType) {}
void MigrateJobAction::anchor() {}
MigrateJobAction::MigrateJobAction(std::unique_ptr<Action> Input,
types::ID OutputType)
: JobAction(MigrateJobClass, std::move(Input), OutputType) {}
MigrateJobAction::MigrateJobAction(Action *Input, types::ID OutputType)
: JobAction(MigrateJobClass, Input, OutputType) {}
void CompileJobAction::anchor() {}
CompileJobAction::CompileJobAction(std::unique_ptr<Action> Input,
types::ID OutputType)
: JobAction(CompileJobClass, std::move(Input), OutputType) {}
CompileJobAction::CompileJobAction(Action *Input, types::ID OutputType)
: JobAction(CompileJobClass, Input, OutputType) {}
void BackendJobAction::anchor() {}
BackendJobAction::BackendJobAction(std::unique_ptr<Action> Input,
types::ID OutputType)
: JobAction(BackendJobClass, std::move(Input), OutputType) {}
BackendJobAction::BackendJobAction(Action *Input, types::ID OutputType)
: JobAction(BackendJobClass, Input, OutputType) {}
void AssembleJobAction::anchor() {}
AssembleJobAction::AssembleJobAction(std::unique_ptr<Action> Input,
types::ID OutputType)
: JobAction(AssembleJobClass, std::move(Input), OutputType) {}
AssembleJobAction::AssembleJobAction(Action *Input, types::ID OutputType)
: JobAction(AssembleJobClass, Input, OutputType) {}
void LinkJobAction::anchor() {}
@ -145,21 +125,20 @@ DsymutilJobAction::DsymutilJobAction(ActionList &Inputs, types::ID Type)
void VerifyJobAction::anchor() {}
VerifyJobAction::VerifyJobAction(ActionClass Kind,
std::unique_ptr<Action> Input, types::ID Type)
: JobAction(Kind, std::move(Input), Type) {
VerifyJobAction::VerifyJobAction(ActionClass Kind, Action *Input,
types::ID Type)
: JobAction(Kind, 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)
: VerifyJobAction(VerifyDebugInfoJobClass, std::move(Input), Type) {}
VerifyDebugInfoJobAction::VerifyDebugInfoJobAction(Action *Input,
types::ID Type)
: VerifyJobAction(VerifyDebugInfoJobClass, Input, Type) {}
void VerifyPCHJobAction::anchor() {}
VerifyPCHJobAction::VerifyPCHJobAction(std::unique_ptr<Action> Input,
types::ID Type)
: VerifyJobAction(VerifyPCHJobClass, std::move(Input), Type) {}
VerifyPCHJobAction::VerifyPCHJobAction(Action *Input, types::ID Type)
: VerifyJobAction(VerifyPCHJobClass, Input, Type) {}

View File

@ -40,11 +40,6 @@ Compilation::~Compilation() {
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];
@ -208,7 +203,8 @@ void Compilation::initCompilationForDiagnostics() {
ForDiagnostics = true;
// Free actions and jobs.
DeleteContainerPointers(Actions);
Actions.clear();
AllActions.clear();
Jobs.clear();
// Clear temporary/results file lists.

View File

@ -1049,19 +1049,15 @@ void Driver::BuildUniversalActions(Compilation &C, const ToolChain &TC,
<< types::getTypeName(Act->getType());
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);
}
for (unsigned i = 0, e = Archs.size(); i != e; ++i)
Inputs.push_back(C.MakeAction<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(C.MakeAction<LipoJobAction>(Inputs, Act->getType()));
// Handle debug info queries.
Arg *A = Args.getLastArg(options::OPT_g_Group);
@ -1077,15 +1073,16 @@ void Driver::BuildUniversalActions(Compilation &C, const ToolChain &TC,
ActionList Inputs;
Inputs.push_back(Actions.back());
Actions.pop_back();
Actions.push_back(new DsymutilJobAction(Inputs, types::TY_dSYM));
Actions.push_back(
C.MakeAction<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());
Action* LastAction = Actions.back();
Actions.pop_back();
Actions.push_back(new VerifyDebugInfoJobAction(std::move(VerifyInput),
types::TY_Nothing));
Actions.push_back(C.MakeAction<VerifyDebugInfoJobAction>(
LastAction, types::TY_Nothing));
}
}
}
@ -1283,16 +1280,15 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args,
// 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>
buildCudaActions(Compilation &C, DerivedArgList &Args, const Arg *InputArg,
std::unique_ptr<Action> HostAction, ActionList &Actions) {
static Action *buildCudaActions(Compilation &C, DerivedArgList &Args,
const Arg *InputArg, 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 C.MakeAction<CudaHostAction>(HostAction, ActionList());
// Collect all cuda_gpu_arch parameters, removing duplicates.
SmallVector<const char *, 4> GpuArchList;
@ -1347,12 +1343,12 @@ buildCudaActions(Compilation &C, DerivedArgList &Args, const Arg *InputArg,
}
for (unsigned I = 0, E = GpuArchList.size(); I != E; ++I)
Actions.push_back(new CudaDeviceAction(
std::unique_ptr<Action>(CudaDeviceActions[I]), GpuArchList[I],
/* AtTopLevel */ true));
Actions.push_back(C.MakeAction<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;
}
@ -1360,13 +1356,12 @@ buildCudaActions(Compilation &C, DerivedArgList &Args, const Arg *InputArg,
// 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(
C.MakeAction<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 C.MakeAction<CudaHostAction>(HostAction, DeviceActions);
}
void Driver::BuildActions(Compilation &C, const ToolChain &TC,
@ -1474,7 +1469,7 @@ void Driver::BuildActions(Compilation &C, const ToolChain &TC,
: FinalPhase;
// Build the pipeline for this file.
std::unique_ptr<Action> Current(new InputAction(*InputArg, InputType));
Action *Current = C.MakeAction<InputAction>(*InputArg, InputType);
for (SmallVectorImpl<phases::ID>::iterator i = PL.begin(), e = PL.end();
i != e; ++i) {
phases::ID Phase = *i;
@ -1486,7 +1481,8 @@ void Driver::BuildActions(Compilation &C, const ToolChain &TC,
// 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(Current);
Current = nullptr;
break;
}
@ -1497,11 +1493,10 @@ void Driver::BuildActions(Compilation &C, const ToolChain &TC,
continue;
// Otherwise construct the appropriate action.
Current = ConstructPhaseAction(TC, Args, Phase, std::move(Current));
Current = ConstructPhaseAction(C, TC, Args, Phase, Current);
if (InputType == types::TY_CUDA && Phase == CudaInjectionPhase) {
Current =
buildCudaActions(C, Args, InputArg, std::move(Current), Actions);
Current = buildCudaActions(C, Args, InputArg, Current, Actions);
if (!Current)
break;
}
@ -1512,12 +1507,13 @@ void Driver::BuildActions(Compilation &C, const ToolChain &TC,
// If we ended with something, add to the output list.
if (Current)
Actions.push_back(Current.release());
Actions.push_back(Current);
}
// Add a link action if necessary.
if (!LinkerInputs.empty())
Actions.push_back(new LinkJobAction(LinkerInputs, types::TY_Image));
Actions.push_back(
C.MakeAction<LinkJobAction>(LinkerInputs, types::TY_Image));
// If we are linking, claim any options which are obviously only used for
// compilation.
@ -1534,10 +1530,9 @@ void Driver::BuildActions(Compilation &C, const ToolChain &TC,
Args.ClaimAllArgs(options::OPT_cuda_host_only);
}
std::unique_ptr<Action>
Driver::ConstructPhaseAction(const ToolChain &TC, const ArgList &Args,
phases::ID Phase,
std::unique_ptr<Action> Input) const {
Action *Driver::ConstructPhaseAction(Compilation &C, const ToolChain &TC,
const ArgList &Args, phases::ID Phase,
Action *Input) const {
llvm::PrettyStackTraceString CrashInfo("Constructing phase actions");
// Build the appropriate action.
switch (Phase) {
@ -1557,7 +1552,7 @@ Driver::ConstructPhaseAction(const ToolChain &TC, const ArgList &Args,
assert(OutputTy != types::TY_INVALID &&
"Cannot preprocess this input type!");
}
return llvm::make_unique<PreprocessJobAction>(std::move(Input), OutputTy);
return C.MakeAction<PreprocessJobAction>(Input, OutputTy);
}
case phases::Precompile: {
types::ID OutputTy = types::TY_PCH;
@ -1565,53 +1560,43 @@ Driver::ConstructPhaseAction(const ToolChain &TC, const ArgList &Args,
// Syntax checks should not emit a PCH file
OutputTy = types::TY_Nothing;
}
return llvm::make_unique<PrecompileJobAction>(std::move(Input), OutputTy);
return C.MakeAction<PrecompileJobAction>(Input, OutputTy);
}
case phases::Compile: {
if (Args.hasArg(options::OPT_fsyntax_only))
return llvm::make_unique<CompileJobAction>(std::move(Input),
types::TY_Nothing);
return C.MakeAction<CompileJobAction>(Input, types::TY_Nothing);
if (Args.hasArg(options::OPT_rewrite_objc))
return llvm::make_unique<CompileJobAction>(std::move(Input),
types::TY_RewrittenObjC);
return C.MakeAction<CompileJobAction>(Input, types::TY_RewrittenObjC);
if (Args.hasArg(options::OPT_rewrite_legacy_objc))
return llvm::make_unique<CompileJobAction>(std::move(Input),
types::TY_RewrittenLegacyObjC);
return C.MakeAction<CompileJobAction>(Input,
types::TY_RewrittenLegacyObjC);
if (Args.hasArg(options::OPT__analyze, options::OPT__analyze_auto))
return llvm::make_unique<AnalyzeJobAction>(std::move(Input),
types::TY_Plist);
return C.MakeAction<AnalyzeJobAction>(Input, types::TY_Plist);
if (Args.hasArg(options::OPT__migrate))
return llvm::make_unique<MigrateJobAction>(std::move(Input),
types::TY_Remap);
return C.MakeAction<MigrateJobAction>(Input, types::TY_Remap);
if (Args.hasArg(options::OPT_emit_ast))
return llvm::make_unique<CompileJobAction>(std::move(Input),
types::TY_AST);
return C.MakeAction<CompileJobAction>(Input, types::TY_AST);
if (Args.hasArg(options::OPT_module_file_info))
return llvm::make_unique<CompileJobAction>(std::move(Input),
types::TY_ModuleFile);
return C.MakeAction<CompileJobAction>(Input, types::TY_ModuleFile);
if (Args.hasArg(options::OPT_verify_pch))
return llvm::make_unique<VerifyPCHJobAction>(std::move(Input),
types::TY_Nothing);
return llvm::make_unique<CompileJobAction>(std::move(Input),
types::TY_LLVM_BC);
return C.MakeAction<VerifyPCHJobAction>(Input, types::TY_Nothing);
return C.MakeAction<CompileJobAction>(Input, types::TY_LLVM_BC);
}
case phases::Backend: {
if (isUsingLTO()) {
types::ID Output =
Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
return llvm::make_unique<BackendJobAction>(std::move(Input), Output);
return C.MakeAction<BackendJobAction>(Input, Output);
}
if (Args.hasArg(options::OPT_emit_llvm)) {
types::ID Output =
Args.hasArg(options::OPT_S) ? types::TY_LLVM_IR : types::TY_LLVM_BC;
return llvm::make_unique<BackendJobAction>(std::move(Input), Output);
return C.MakeAction<BackendJobAction>(Input, Output);
}
return llvm::make_unique<BackendJobAction>(std::move(Input),
types::TY_PP_Asm);
return C.MakeAction<BackendJobAction>(Input, types::TY_PP_Asm);
}
case phases::Assemble:
return llvm::make_unique<AssembleJobAction>(std::move(Input),
types::TY_Object);
return C.MakeAction<AssembleJobAction>(Input, types::TY_Object);
}
llvm_unreachable("invalid phase in ConstructPhaseAction");