mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Cleaner handling of cases where action produces no output or where there are no inputs.
This commit is contained in:
@@ -124,10 +124,24 @@ public:
|
||||
const llvm::opt::ArgList &args, DiagnosticEngine &diags,
|
||||
const FrontendInputsAndOutputs &inputsAndOutputs,
|
||||
ArrayRef<std::string> outputFiles, StringRef moduleName);
|
||||
Optional<SupplementaryOutputPaths> computeOutputPaths() const;
|
||||
Optional<std::vector<SupplementaryOutputPaths>> computeOutputPaths() const;
|
||||
|
||||
private:
|
||||
/// \return None if error.
|
||||
/// \Return a set of supplementary output paths for each input that might
|
||||
/// produce supplementary outputs, or None to signal an error.
|
||||
/// \note
|
||||
/// At present, only one input can produce supplementary outputs, but
|
||||
/// in the future, batch-mode will support multiple primary inputs and thus,
|
||||
/// multiple sets of supplementary outputs. This function is written with that
|
||||
/// future in mind.
|
||||
/// \par
|
||||
/// The paths are derived from arguments
|
||||
/// such as -emit-module-path. These are not the final computed paths,
|
||||
/// merely the ones passed in via the command line.
|
||||
/// \note
|
||||
/// In the future, these will also include those passed in via whatever
|
||||
/// filelist scheme gets implemented to handle cases where the command line
|
||||
/// arguments become burdensome.
|
||||
Optional<std::vector<SupplementaryOutputPaths>>
|
||||
getSupplementaryOutputPathsFromArguments() const;
|
||||
|
||||
|
||||
@@ -441,9 +441,6 @@ bool ArgsToFrontendOptionsConverter::
|
||||
.convert(mainOutputs, supplementaryOutputs);
|
||||
if (hadError)
|
||||
return true;
|
||||
assert(FrontendOptions::doesActionProduceOutput(Opts.RequestedAction) ||
|
||||
mainOutputs.empty() &&
|
||||
"Should be no main outputs if action does not produce them");
|
||||
Opts.InputsAndOutputs.setMainAndSupplementaryOutputs(mainOutputs,
|
||||
supplementaryOutputs);
|
||||
return false;
|
||||
|
||||
@@ -34,10 +34,6 @@ using namespace llvm::opt;
|
||||
bool ArgsToFrontendOutputsConverter::convert(
|
||||
std::vector<std::string> &mainOutputs,
|
||||
SupplementaryOutputPaths &supplementaryOutputs) {
|
||||
const auto requestedAction =
|
||||
ArgsToFrontendOptionsConverter::determineRequestedAction(Args);
|
||||
if (!FrontendOptions::doesActionProduceOutput(requestedAction))
|
||||
return false;
|
||||
|
||||
Optional<OutputFilesComputer> ofc =
|
||||
OutputFilesComputer::create(Args, Diags, InputsAndOutputs);
|
||||
@@ -47,7 +43,7 @@ bool ArgsToFrontendOutputsConverter::convert(
|
||||
if (!mains)
|
||||
return true;
|
||||
|
||||
Optional<SupplementaryOutputPaths> supplementaries =
|
||||
Optional<std::vector<SupplementaryOutputPaths>> supplementaries =
|
||||
SupplementaryOutputPathsComputer(Args, Diags, InputsAndOutputs, *mains,
|
||||
ModuleName)
|
||||
.computeOutputPaths();
|
||||
@@ -55,7 +51,10 @@ bool ArgsToFrontendOutputsConverter::convert(
|
||||
return true;
|
||||
|
||||
mainOutputs = std::move(*mains);
|
||||
supplementaryOutputs = std::move(*supplementaries);
|
||||
assert(supplementaries->size() <= 1 &&
|
||||
"Have not implemented multiple primaries yet");
|
||||
if (!supplementaries->empty())
|
||||
supplementaryOutputs = std::move(supplementaries->front());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -166,6 +165,13 @@ OutputFilesComputer::computeOutputFiles() const {
|
||||
Optional<std::string>
|
||||
OutputFilesComputer::computeOutputFile(StringRef outputArg,
|
||||
const InputFile &input) const {
|
||||
// Return an empty string to signify no output.
|
||||
// The frontend does not currently produce a diagnostic
|
||||
// if a -o argument is present for such an action
|
||||
// for instance swiftc -frontend -o foo -interpret foo.swift
|
||||
if (!FrontendOptions::doesActionProduceOutput(RequestedAction))
|
||||
return std::string();
|
||||
|
||||
if (!OutputDirectoryArgument.empty())
|
||||
return deriveOutputFileForDirectory(input);
|
||||
|
||||
@@ -228,16 +234,41 @@ SupplementaryOutputPathsComputer::SupplementaryOutputPathsComputer(
|
||||
RequestedAction(
|
||||
ArgsToFrontendOptionsConverter::determineRequestedAction(Args)) {}
|
||||
|
||||
Optional<SupplementaryOutputPaths>
|
||||
Optional<std::vector<SupplementaryOutputPaths>>
|
||||
SupplementaryOutputPathsComputer::computeOutputPaths() const {
|
||||
Optional<std::vector<SupplementaryOutputPaths>> pathsFromUser =
|
||||
getSupplementaryOutputPathsFromArguments();
|
||||
if (!pathsFromUser)
|
||||
return None;
|
||||
|
||||
return computeOutputPathsForOneInput(
|
||||
OutputFiles[0], (*pathsFromUser)[0],
|
||||
InputsAndOutputs.firstInputProducingOutput());
|
||||
if (InputsAndOutputs.hasPrimaryInputs())
|
||||
assert(OutputFiles.size() == pathsFromUser->size());
|
||||
else if (InputsAndOutputs.isSingleThreadedWMO())
|
||||
assert(OutputFiles.size() == pathsFromUser->size() &&
|
||||
pathsFromUser->size() == 1);
|
||||
else {
|
||||
// Multi-threaded WMO is the exception
|
||||
assert(OutputFiles.size() == InputsAndOutputs.inputCount() &&
|
||||
pathsFromUser->size() == InputsAndOutputs.hasInputs()
|
||||
? 1
|
||||
: 0);
|
||||
}
|
||||
|
||||
std::vector<SupplementaryOutputPaths> outputPaths;
|
||||
unsigned i = 0;
|
||||
bool hadError = false;
|
||||
InputsAndOutputs.forEachInputProducingSupplementaryOutput(
|
||||
[&](const InputFile &input) -> void {
|
||||
if (auto suppPaths = computeOutputPathsForOneInput(
|
||||
OutputFiles[i], (*pathsFromUser)[i], input))
|
||||
outputPaths.push_back(*suppPaths);
|
||||
else
|
||||
hadError = true;
|
||||
++i;
|
||||
});
|
||||
if (hadError)
|
||||
return None;
|
||||
return outputPaths;
|
||||
}
|
||||
|
||||
Optional<std::vector<SupplementaryOutputPaths>>
|
||||
@@ -302,7 +333,7 @@ SupplementaryOutputPathsComputer::getSupplementaryFilenamesFromArguments(
|
||||
return std::vector<std::string>(N, std::string());
|
||||
|
||||
Diags.diagnose(SourceLoc(), diag::error_wrong_number_of_arguments,
|
||||
Args.getLastArg(pathID)->getOption().getName(), N,
|
||||
Args.getLastArg(pathID)->getOption().getPrefixedName(), N,
|
||||
paths.size());
|
||||
return None;
|
||||
}
|
||||
@@ -387,7 +418,6 @@ SupplementaryOutputPathsComputer::determineSupplementaryOutputFilename(
|
||||
options::ID emitOpt, std::string pathFromArguments, StringRef extension,
|
||||
StringRef mainOutputIfUsable,
|
||||
StringRef defaultSupplementaryOutputPathExcludingExtension) const {
|
||||
using namespace options;
|
||||
|
||||
if (!pathFromArguments.empty())
|
||||
return pathFromArguments;
|
||||
|
||||
@@ -289,9 +289,7 @@ void FrontendInputsAndOutputs::forEachInputProducingAMainOutputFile(
|
||||
void FrontendInputsAndOutputs::setMainAndSupplementaryOutputs(
|
||||
ArrayRef<std::string> outputFiles,
|
||||
SupplementaryOutputPaths supplementaryOutputs) {
|
||||
if (outputFiles.empty())
|
||||
;
|
||||
else if (hasPrimaryInputs()) {
|
||||
if (hasPrimaryInputs()) {
|
||||
unsigned i = 0;
|
||||
for (auto index : indices(AllInputs)) {
|
||||
InputFile &f = AllInputs[index];
|
||||
@@ -344,15 +342,14 @@ bool FrontendInputsAndOutputs::hasNamedOutputFile() const {
|
||||
|
||||
unsigned
|
||||
FrontendInputsAndOutputs::countOfFilesProducingSupplementaryOutput() const {
|
||||
assertMustNotBeMoreThanOnePrimaryInput();
|
||||
return 1; // will be extended when batch mode is implemented
|
||||
return hasPrimaryInputs() ? primaryInputCount() : hasInputs() ? 1 : 0;
|
||||
}
|
||||
|
||||
void FrontendInputsAndOutputs::forEachInputProducingSupplementaryOutput(
|
||||
llvm::function_ref<void(const InputFile &)> fn) const {
|
||||
if (hasPrimaryInputs())
|
||||
forEachPrimaryInput(fn);
|
||||
else
|
||||
else if (hasInputs())
|
||||
fn(firstInput());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
// RUN: not %swift -c -primary-file a.swift b.swift -emit-module-path one -emit-module-path two 2>&1 | %FileCheck %s -check-prefix=CHECK1
|
||||
// CHECK1: <unknown>:0: error: wrong number of 'emit-module-path' arguments (expected 1, got 2)
|
||||
// CHECK1: <unknown>:0: error: wrong number of '-emit-module-path' arguments (expected 1, got 2)
|
||||
|
||||
Reference in New Issue
Block a user