mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[driver] Slightly refactored Driver’s handling of OutputMode.
Instead of having buildActions() call the private Driver::getOutputMode() function, establish an OutputMode using a new Driver::buildOutputMode() function. This change will allow the OutputMode to be more easily shared across functions without needing to generate it each time (though, at the moment, only buildActions() uses the OutputMode). Swift SVN r12494
This commit is contained in:
@@ -78,6 +78,20 @@ public:
|
|||||||
typedef std::pair<types::ID, const llvm::opt::Arg *> InputPair;
|
typedef std::pair<types::ID, const llvm::opt::Arg *> InputPair;
|
||||||
typedef SmallVector<InputPair, 16> InputList;
|
typedef SmallVector<InputPair, 16> InputList;
|
||||||
|
|
||||||
|
/// \brief A class encapsulating information about the outputs the driver
|
||||||
|
/// is expected to generate.
|
||||||
|
class OutputMode {
|
||||||
|
public:
|
||||||
|
/// The output type which should be used for compile actions.
|
||||||
|
types::ID CompilerOutputType = types::ID::TY_INVALID;
|
||||||
|
|
||||||
|
/// Whether or not the output of compile actions should be linked together.
|
||||||
|
bool ShouldLink = false;
|
||||||
|
|
||||||
|
/// Whether or not the driver should generate a module.
|
||||||
|
bool ShouldGenerateModule = false;
|
||||||
|
};
|
||||||
|
|
||||||
Driver(StringRef DriverExecutable,
|
Driver(StringRef DriverExecutable,
|
||||||
DiagnosticEngine &Diags);
|
DiagnosticEngine &Diags);
|
||||||
~Driver();
|
~Driver();
|
||||||
@@ -114,15 +128,25 @@ public:
|
|||||||
void buildInputs(const ToolChain &TC, const llvm::opt::DerivedArgList &Args,
|
void buildInputs(const ToolChain &TC, const llvm::opt::DerivedArgList &Args,
|
||||||
InputList &Inputs) const;
|
InputList &Inputs) const;
|
||||||
|
|
||||||
|
/// Construct the OutputMode for the driver from the given arguments.
|
||||||
|
///
|
||||||
|
/// \param Args The input arguments.
|
||||||
|
/// \param[out] OM The OutputMode in which to store the resulting output
|
||||||
|
/// information.
|
||||||
|
void buildOutputMode(const llvm::opt::DerivedArgList &Args, OutputMode &OM)
|
||||||
|
const;
|
||||||
|
|
||||||
/// Construct the list of Actions to perform for the given arguments,
|
/// Construct the list of Actions to perform for the given arguments,
|
||||||
/// which are only done for a single architecture.
|
/// which are only done for a single architecture.
|
||||||
///
|
///
|
||||||
/// \param TC the default host tool chain.
|
/// \param TC the default host tool chain.
|
||||||
/// \param Args The input arguments.
|
/// \param Args The input arguments.
|
||||||
/// \param Inputs The inputs for which Actions should be generated.
|
/// \param Inputs The inputs for which Actions should be generated.
|
||||||
|
/// \param OM The OutputMode for which Actions should be generated.
|
||||||
/// \param[out] Actions The list in which to store the resulting Actions.
|
/// \param[out] Actions The list in which to store the resulting Actions.
|
||||||
void buildActions(const ToolChain &TC, const llvm::opt::DerivedArgList &Args,
|
void buildActions(const ToolChain &TC, const llvm::opt::DerivedArgList &Args,
|
||||||
const InputList &Inputs, ActionList &Actions) const;
|
const InputList &Inputs, const OutputMode &OM,
|
||||||
|
ActionList &Actions) const;
|
||||||
|
|
||||||
/// Add top-level Jobs to Compilation \p C for the given \p Actions.
|
/// Add top-level Jobs to Compilation \p C for the given \p Actions.
|
||||||
void buildJobs(Compilation &C, const ActionList &Actions) const;
|
void buildJobs(Compilation &C, const ActionList &Actions) const;
|
||||||
@@ -174,25 +198,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
const ToolChain &getToolChain(const llvm::opt::ArgList &Args,
|
const ToolChain &getToolChain(const llvm::opt::ArgList &Args,
|
||||||
StringRef DarwinArchName = "") const;
|
StringRef DarwinArchName = "") const;
|
||||||
|
|
||||||
class OutputMode {
|
|
||||||
public:
|
|
||||||
/// The output type which should be used for compile actions.
|
|
||||||
types::ID CompilerOutputType;
|
|
||||||
|
|
||||||
/// Whether or not the output of compile actions should be linked together.
|
|
||||||
bool ShouldLink;
|
|
||||||
|
|
||||||
/// Whether or not the driver should generate a module.
|
|
||||||
bool ShouldGenerateModule;
|
|
||||||
|
|
||||||
OutputMode(types::ID CompilerOutputType, bool ShouldLink,
|
|
||||||
bool ShouldGenerateModule)
|
|
||||||
: CompilerOutputType(CompilerOutputType), ShouldLink(ShouldLink),
|
|
||||||
ShouldGenerateModule(ShouldGenerateModule) {}
|
|
||||||
};
|
|
||||||
OutputMode getOutputMode(const llvm::opt::ArgList &Args) const;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace driver
|
} // end namespace driver
|
||||||
|
|||||||
@@ -90,8 +90,16 @@ std::unique_ptr<Compilation> Driver::buildCompilation(
|
|||||||
InputList Inputs;
|
InputList Inputs;
|
||||||
buildInputs(TC, *TranslatedArgList, Inputs);
|
buildInputs(TC, *TranslatedArgList, Inputs);
|
||||||
|
|
||||||
|
// Determine the OutputMode for the driver.
|
||||||
|
OutputMode OM;
|
||||||
|
buildOutputMode(*TranslatedArgList, OM);
|
||||||
|
|
||||||
|
assert(OM.CompilerOutputType != types::ID::TY_INVALID &&
|
||||||
|
"buildOutputMode() must set a valid output type!");
|
||||||
|
|
||||||
|
// Construct the graph of Actions.
|
||||||
ActionList Actions;
|
ActionList Actions;
|
||||||
buildActions(TC, *TranslatedArgList, Inputs, Actions);
|
buildActions(TC, *TranslatedArgList, Inputs, OM, Actions);
|
||||||
|
|
||||||
if (DriverPrintActions) {
|
if (DriverPrintActions) {
|
||||||
printActions(Actions);
|
printActions(Actions);
|
||||||
@@ -251,12 +259,61 @@ void Driver::buildInputs(const ToolChain &TC,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Driver::buildOutputMode(const DerivedArgList &Args,
|
||||||
|
OutputMode &OM) const {
|
||||||
|
OM.ShouldLink = false;
|
||||||
|
OM.ShouldGenerateModule = Args.hasArg(options::OPT_emit_module,
|
||||||
|
options::OPT_module_output_path);
|
||||||
|
types::ID CompileOutputType = types::TY_INVALID;
|
||||||
|
|
||||||
|
const Arg *const OutputModeArg = Args.getLastArg(options::OPT_modes_Group);
|
||||||
|
if (!OutputModeArg) {
|
||||||
|
if (Args.hasArg(options::OPT_emit_module, options::OPT_module_output_path))
|
||||||
|
CompileOutputType = types::TY_SwiftModuleFile;
|
||||||
|
else {
|
||||||
|
OM.ShouldLink = true;
|
||||||
|
CompileOutputType = types::TY_Object;
|
||||||
|
}
|
||||||
|
} else if (OutputModeArg->getOption().matches(options::OPT_emit_executable)) {
|
||||||
|
OM.ShouldLink = true;
|
||||||
|
CompileOutputType = types::TY_Object;
|
||||||
|
} else if (OutputModeArg->getOption().matches(options::OPT_c)) {
|
||||||
|
// The user has requested an object file.
|
||||||
|
CompileOutputType = types::TY_Object;
|
||||||
|
} else if (OutputModeArg->getOption().matches(options::OPT_S)) {
|
||||||
|
// The user has requested an assembly file.
|
||||||
|
CompileOutputType = types::TY_Assembly;
|
||||||
|
} else if (OutputModeArg->getOption().matches(options::OPT_emit_sil)) {
|
||||||
|
// The user has requested a SIL file.
|
||||||
|
CompileOutputType = types::TY_SIL;
|
||||||
|
} else if (OutputModeArg->getOption().matches(options::OPT_emit_silgen)) {
|
||||||
|
// The user has requested a raw SIL file.
|
||||||
|
CompileOutputType = types::TY_RawSIL;
|
||||||
|
} else if (OutputModeArg->getOption().matches(options::OPT_emit_ir)) {
|
||||||
|
// The user has requested LLVM IR.
|
||||||
|
CompileOutputType = types::TY_LLVM_IR;
|
||||||
|
} else if (OutputModeArg->getOption().matches(options::OPT_emit_bc)) {
|
||||||
|
// The user has requested LLVM BC.
|
||||||
|
CompileOutputType = types::TY_LLVM_BC;
|
||||||
|
} else if (OutputModeArg->getOption().matches(options::OPT_parse) ||
|
||||||
|
OutputModeArg->getOption().matches(options::OPT_dump_parse) ||
|
||||||
|
OutputModeArg->getOption().matches(options::OPT_dump_ast) ||
|
||||||
|
OutputModeArg->getOption().matches(options::OPT_print_ast) ||
|
||||||
|
OutputModeArg->getOption().matches(options::OPT_i) ||
|
||||||
|
OutputModeArg->getOption().matches(options::OPT_repl)) {
|
||||||
|
// These modes don't have any output.
|
||||||
|
CompileOutputType = types::TY_Nothing;
|
||||||
|
} else {
|
||||||
|
llvm_unreachable("Unknown output mode option!");
|
||||||
|
}
|
||||||
|
|
||||||
|
OM.CompilerOutputType = CompileOutputType;
|
||||||
|
}
|
||||||
|
|
||||||
void Driver::buildActions(const ToolChain &TC,
|
void Driver::buildActions(const ToolChain &TC,
|
||||||
const DerivedArgList &Args,
|
const DerivedArgList &Args,
|
||||||
const InputList &Inputs, ActionList &Actions) const {
|
const InputList &Inputs, const OutputMode &OM,
|
||||||
OutputMode Mode = getOutputMode(Args);
|
ActionList &Actions) const {
|
||||||
types::ID CompilerOutputType = Mode.CompilerOutputType;
|
|
||||||
|
|
||||||
if (Inputs.empty()) {
|
if (Inputs.empty()) {
|
||||||
// FIXME: emit diagnostic
|
// FIXME: emit diagnostic
|
||||||
llvm::errs() << "error: no input files\n";
|
llvm::errs() << "error: no input files\n";
|
||||||
@@ -269,18 +326,19 @@ void Driver::buildActions(const ToolChain &TC,
|
|||||||
const Arg *InputArg = Input.second;
|
const Arg *InputArg = Input.second;
|
||||||
|
|
||||||
std::unique_ptr<Action> Current(new InputAction(*InputArg, InputType));
|
std::unique_ptr<Action> Current(new InputAction(*InputArg, InputType));
|
||||||
Current.reset(new CompileJobAction(Current.release(), CompilerOutputType));
|
Current.reset(new CompileJobAction(Current.release(),
|
||||||
|
OM.CompilerOutputType));
|
||||||
// We've been told to link, so this action will be a linker input,
|
// We've been told to link, so this action will be a linker input,
|
||||||
// not a top-level action.
|
// not a top-level action.
|
||||||
CompileActions.push_back(Current.release());
|
CompileActions.push_back(Current.release());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Action> MergeModuleAction;
|
std::unique_ptr<Action> MergeModuleAction;
|
||||||
if (Mode.ShouldGenerateModule) {
|
if (OM.ShouldGenerateModule) {
|
||||||
MergeModuleAction.reset(new MergeModuleJobAction(CompileActions));
|
MergeModuleAction.reset(new MergeModuleJobAction(CompileActions));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Mode.ShouldLink) {
|
if (OM.ShouldLink) {
|
||||||
Action *LinkAction = new LinkJobAction(CompileActions);
|
Action *LinkAction = new LinkJobAction(CompileActions);
|
||||||
if (MergeModuleAction) {
|
if (MergeModuleAction) {
|
||||||
// We have a MergeModuleJobAction; this needs to be an input to the
|
// We have a MergeModuleJobAction; this needs to be an input to the
|
||||||
@@ -290,7 +348,7 @@ void Driver::buildActions(const ToolChain &TC,
|
|||||||
LinkAction->addInput(MergeModuleAction.release());
|
LinkAction->addInput(MergeModuleAction.release());
|
||||||
}
|
}
|
||||||
Actions.push_back(LinkAction);
|
Actions.push_back(LinkAction);
|
||||||
} else if (Mode.ShouldGenerateModule) {
|
} else if (OM.ShouldGenerateModule) {
|
||||||
assert(MergeModuleAction);
|
assert(MergeModuleAction);
|
||||||
Actions.push_back(MergeModuleAction.release());
|
Actions.push_back(MergeModuleAction.release());
|
||||||
} else {
|
} else {
|
||||||
@@ -652,53 +710,3 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
|
|||||||
}
|
}
|
||||||
return *TC;
|
return *TC;
|
||||||
}
|
}
|
||||||
|
|
||||||
Driver::OutputMode Driver::getOutputMode(const ArgList &Args) const {
|
|
||||||
bool ShouldLink = false;
|
|
||||||
bool ShouldGenerateModule = Args.hasArg(options::OPT_emit_module,
|
|
||||||
options::OPT_module_output_path);
|
|
||||||
types::ID CompileOutputType = types::TY_INVALID;
|
|
||||||
|
|
||||||
const Arg *const OutputModeArg = Args.getLastArg(options::OPT_modes_Group);
|
|
||||||
if (!OutputModeArg) {
|
|
||||||
if (Args.hasArg(options::OPT_emit_module, options::OPT_module_output_path))
|
|
||||||
CompileOutputType = types::TY_SwiftModuleFile;
|
|
||||||
else {
|
|
||||||
ShouldLink = true;
|
|
||||||
CompileOutputType = types::TY_Object;
|
|
||||||
}
|
|
||||||
} else if (OutputModeArg->getOption().matches(options::OPT_emit_executable)) {
|
|
||||||
ShouldLink = true;
|
|
||||||
CompileOutputType = types::TY_Object;
|
|
||||||
} else if (OutputModeArg->getOption().matches(options::OPT_c)) {
|
|
||||||
// The user has requested an object file.
|
|
||||||
CompileOutputType = types::TY_Object;
|
|
||||||
} else if (OutputModeArg->getOption().matches(options::OPT_S)) {
|
|
||||||
// The user has requested an assembly file.
|
|
||||||
CompileOutputType = types::TY_Assembly;
|
|
||||||
} else if (OutputModeArg->getOption().matches(options::OPT_emit_sil)) {
|
|
||||||
// The user has requested a SIL file.
|
|
||||||
CompileOutputType = types::TY_SIL;
|
|
||||||
} else if (OutputModeArg->getOption().matches(options::OPT_emit_silgen)) {
|
|
||||||
// The user has requested a raw SIL file.
|
|
||||||
CompileOutputType = types::TY_RawSIL;
|
|
||||||
} else if (OutputModeArg->getOption().matches(options::OPT_emit_ir)) {
|
|
||||||
// The user has requested LLVM IR.
|
|
||||||
CompileOutputType = types::TY_LLVM_IR;
|
|
||||||
} else if (OutputModeArg->getOption().matches(options::OPT_emit_bc)) {
|
|
||||||
// The user has requested LLVM BC.
|
|
||||||
CompileOutputType = types::TY_LLVM_BC;
|
|
||||||
} else if (OutputModeArg->getOption().matches(options::OPT_parse) ||
|
|
||||||
OutputModeArg->getOption().matches(options::OPT_dump_parse) ||
|
|
||||||
OutputModeArg->getOption().matches(options::OPT_dump_ast) ||
|
|
||||||
OutputModeArg->getOption().matches(options::OPT_print_ast) ||
|
|
||||||
OutputModeArg->getOption().matches(options::OPT_i) ||
|
|
||||||
OutputModeArg->getOption().matches(options::OPT_repl)) {
|
|
||||||
// These modes don't have any output.
|
|
||||||
CompileOutputType = types::TY_Nothing;
|
|
||||||
} else {
|
|
||||||
llvm_unreachable("Unknown output mode option!");
|
|
||||||
}
|
|
||||||
|
|
||||||
return OutputMode(CompileOutputType, ShouldLink, ShouldGenerateModule);
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user