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 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,
|
||||
DiagnosticEngine &Diags);
|
||||
~Driver();
|
||||
@@ -114,15 +128,25 @@ public:
|
||||
void buildInputs(const ToolChain &TC, const llvm::opt::DerivedArgList &Args,
|
||||
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,
|
||||
/// which are only done for a single architecture.
|
||||
///
|
||||
/// \param TC the default host tool chain.
|
||||
/// \param Args The input arguments.
|
||||
/// \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.
|
||||
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.
|
||||
void buildJobs(Compilation &C, const ActionList &Actions) const;
|
||||
@@ -174,25 +198,6 @@ public:
|
||||
private:
|
||||
const ToolChain &getToolChain(const llvm::opt::ArgList &Args,
|
||||
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
|
||||
|
||||
@@ -90,8 +90,16 @@ std::unique_ptr<Compilation> Driver::buildCompilation(
|
||||
InputList 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;
|
||||
buildActions(TC, *TranslatedArgList, Inputs, Actions);
|
||||
buildActions(TC, *TranslatedArgList, Inputs, OM, Actions);
|
||||
|
||||
if (DriverPrintActions) {
|
||||
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,
|
||||
const DerivedArgList &Args,
|
||||
const InputList &Inputs, ActionList &Actions) const {
|
||||
OutputMode Mode = getOutputMode(Args);
|
||||
types::ID CompilerOutputType = Mode.CompilerOutputType;
|
||||
|
||||
const InputList &Inputs, const OutputMode &OM,
|
||||
ActionList &Actions) const {
|
||||
if (Inputs.empty()) {
|
||||
// FIXME: emit diagnostic
|
||||
llvm::errs() << "error: no input files\n";
|
||||
@@ -269,18 +326,19 @@ void Driver::buildActions(const ToolChain &TC,
|
||||
const Arg *InputArg = Input.second;
|
||||
|
||||
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,
|
||||
// not a top-level action.
|
||||
CompileActions.push_back(Current.release());
|
||||
}
|
||||
|
||||
std::unique_ptr<Action> MergeModuleAction;
|
||||
if (Mode.ShouldGenerateModule) {
|
||||
if (OM.ShouldGenerateModule) {
|
||||
MergeModuleAction.reset(new MergeModuleJobAction(CompileActions));
|
||||
}
|
||||
|
||||
if (Mode.ShouldLink) {
|
||||
if (OM.ShouldLink) {
|
||||
Action *LinkAction = new LinkJobAction(CompileActions);
|
||||
if (MergeModuleAction) {
|
||||
// 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());
|
||||
}
|
||||
Actions.push_back(LinkAction);
|
||||
} else if (Mode.ShouldGenerateModule) {
|
||||
} else if (OM.ShouldGenerateModule) {
|
||||
assert(MergeModuleAction);
|
||||
Actions.push_back(MergeModuleAction.release());
|
||||
} else {
|
||||
@@ -652,53 +710,3 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
|
||||
}
|
||||
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