Skip to content

Commit ef02d0b

Browse files
committed
Cleaner handling of cases where action produces no output or where there are no inputs.
1 parent ba4f2a8 commit ef02d0b

File tree

5 files changed

+62
-24
lines changed

5 files changed

+62
-24
lines changed

include/swift/Frontend/ArgsToFrontendOutputsConverter.h

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,24 @@ class SupplementaryOutputPathsComputer {
124124
const llvm::opt::ArgList &args, DiagnosticEngine &diags,
125125
const FrontendInputsAndOutputs &inputsAndOutputs,
126126
ArrayRef<std::string> outputFiles, StringRef moduleName);
127-
Optional<SupplementaryOutputPaths> computeOutputPaths() const;
127+
Optional<std::vector<SupplementaryOutputPaths>> computeOutputPaths() const;
128128

129129
private:
130-
/// \return None if error.
130+
/// \Return a set of supplementary output paths for each input that might
131+
/// produce supplementary outputs, or None to signal an error.
132+
/// \note
133+
/// At present, only one input can produce supplementary outputs, but
134+
/// in the future, batch-mode will support multiple primary inputs and thus,
135+
/// multiple sets of supplementary outputs. This function is written with that
136+
/// future in mind.
137+
/// \par
138+
/// The paths are derived from arguments
139+
/// such as -emit-module-path. These are not the final computed paths,
140+
/// merely the ones passed in via the command line.
141+
/// \note
142+
/// In the future, these will also include those passed in via whatever
143+
/// filelist scheme gets implemented to handle cases where the command line
144+
/// arguments become burdensome.
131145
Optional<std::vector<SupplementaryOutputPaths>>
132146
getSupplementaryOutputPathsFromArguments() const;
133147

lib/Frontend/ArgsToFrontendOptionsConverter.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -441,9 +441,6 @@ bool ArgsToFrontendOptionsConverter::
441441
.convert(mainOutputs, supplementaryOutputs);
442442
if (hadError)
443443
return true;
444-
assert(FrontendOptions::doesActionProduceOutput(Opts.RequestedAction) ||
445-
mainOutputs.empty() &&
446-
"Should be no main outputs if action does not produce them");
447444
Opts.InputsAndOutputs.setMainAndSupplementaryOutputs(mainOutputs,
448445
supplementaryOutputs);
449446
return false;

lib/Frontend/ArgsToFrontendOutputsConverter.cpp

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,6 @@ using namespace llvm::opt;
3434
bool ArgsToFrontendOutputsConverter::convert(
3535
std::vector<std::string> &mainOutputs,
3636
SupplementaryOutputPaths &supplementaryOutputs) {
37-
const auto requestedAction =
38-
ArgsToFrontendOptionsConverter::determineRequestedAction(Args);
39-
if (!FrontendOptions::doesActionProduceOutput(requestedAction))
40-
return false;
4137

4238
Optional<OutputFilesComputer> ofc =
4339
OutputFilesComputer::create(Args, Diags, InputsAndOutputs);
@@ -47,15 +43,18 @@ bool ArgsToFrontendOutputsConverter::convert(
4743
if (!mains)
4844
return true;
4945

50-
Optional<SupplementaryOutputPaths> supplementaries =
46+
Optional<std::vector<SupplementaryOutputPaths>> supplementaries =
5147
SupplementaryOutputPathsComputer(Args, Diags, InputsAndOutputs, *mains,
5248
ModuleName)
5349
.computeOutputPaths();
5450
if (!supplementaries)
5551
return true;
5652

5753
mainOutputs = std::move(*mains);
58-
supplementaryOutputs = std::move(*supplementaries);
54+
assert(supplementaries->size() <= 1 &&
55+
"Have not implemented multiple primaries yet");
56+
if (!supplementaries->empty())
57+
supplementaryOutputs = std::move(supplementaries->front());
5958
return false;
6059
}
6160

@@ -166,6 +165,13 @@ OutputFilesComputer::computeOutputFiles() const {
166165
Optional<std::string>
167166
OutputFilesComputer::computeOutputFile(StringRef outputArg,
168167
const InputFile &input) const {
168+
// Return an empty string to signify no output.
169+
// The frontend does not currently produce a diagnostic
170+
// if a -o argument is present for such an action
171+
// for instance swiftc -frontend -o foo -interpret foo.swift
172+
if (!FrontendOptions::doesActionProduceOutput(RequestedAction))
173+
return std::string();
174+
169175
if (!OutputDirectoryArgument.empty())
170176
return deriveOutputFileForDirectory(input);
171177

@@ -228,16 +234,41 @@ SupplementaryOutputPathsComputer::SupplementaryOutputPathsComputer(
228234
RequestedAction(
229235
ArgsToFrontendOptionsConverter::determineRequestedAction(Args)) {}
230236

231-
Optional<SupplementaryOutputPaths>
237+
Optional<std::vector<SupplementaryOutputPaths>>
232238
SupplementaryOutputPathsComputer::computeOutputPaths() const {
233239
Optional<std::vector<SupplementaryOutputPaths>> pathsFromUser =
234240
getSupplementaryOutputPathsFromArguments();
235241
if (!pathsFromUser)
236242
return None;
237243

238-
return computeOutputPathsForOneInput(
239-
OutputFiles[0], (*pathsFromUser)[0],
240-
InputsAndOutputs.firstInputProducingOutput());
244+
if (InputsAndOutputs.hasPrimaryInputs())
245+
assert(OutputFiles.size() == pathsFromUser->size());
246+
else if (InputsAndOutputs.isSingleThreadedWMO())
247+
assert(OutputFiles.size() == pathsFromUser->size() &&
248+
pathsFromUser->size() == 1);
249+
else {
250+
// Multi-threaded WMO is the exception
251+
assert(OutputFiles.size() == InputsAndOutputs.inputCount() &&
252+
pathsFromUser->size() == InputsAndOutputs.hasInputs()
253+
? 1
254+
: 0);
255+
}
256+
257+
std::vector<SupplementaryOutputPaths> outputPaths;
258+
unsigned i = 0;
259+
bool hadError = false;
260+
InputsAndOutputs.forEachInputProducingSupplementaryOutput(
261+
[&](const InputFile &input) -> void {
262+
if (auto suppPaths = computeOutputPathsForOneInput(
263+
OutputFiles[i], (*pathsFromUser)[i], input))
264+
outputPaths.push_back(*suppPaths);
265+
else
266+
hadError = true;
267+
++i;
268+
});
269+
if (hadError)
270+
return None;
271+
return outputPaths;
241272
}
242273

243274
Optional<std::vector<SupplementaryOutputPaths>>
@@ -302,7 +333,7 @@ SupplementaryOutputPathsComputer::getSupplementaryFilenamesFromArguments(
302333
return std::vector<std::string>(N, std::string());
303334

304335
Diags.diagnose(SourceLoc(), diag::error_wrong_number_of_arguments,
305-
Args.getLastArg(pathID)->getOption().getName(), N,
336+
Args.getLastArg(pathID)->getOption().getPrefixedName(), N,
306337
paths.size());
307338
return None;
308339
}
@@ -387,7 +418,6 @@ SupplementaryOutputPathsComputer::determineSupplementaryOutputFilename(
387418
options::ID emitOpt, std::string pathFromArguments, StringRef extension,
388419
StringRef mainOutputIfUsable,
389420
StringRef defaultSupplementaryOutputPathExcludingExtension) const {
390-
using namespace options;
391421

392422
if (!pathFromArguments.empty())
393423
return pathFromArguments;

lib/Frontend/FrontendInputsAndOutputs.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -289,9 +289,7 @@ void FrontendInputsAndOutputs::forEachInputProducingAMainOutputFile(
289289
void FrontendInputsAndOutputs::setMainAndSupplementaryOutputs(
290290
ArrayRef<std::string> outputFiles,
291291
SupplementaryOutputPaths supplementaryOutputs) {
292-
if (outputFiles.empty())
293-
;
294-
else if (hasPrimaryInputs()) {
292+
if (hasPrimaryInputs()) {
295293
unsigned i = 0;
296294
for (auto index : indices(AllInputs)) {
297295
InputFile &f = AllInputs[index];
@@ -344,15 +342,14 @@ bool FrontendInputsAndOutputs::hasNamedOutputFile() const {
344342

345343
unsigned
346344
FrontendInputsAndOutputs::countOfFilesProducingSupplementaryOutput() const {
347-
assertMustNotBeMoreThanOnePrimaryInput();
348-
return 1; // will be extended when batch mode is implemented
345+
return hasPrimaryInputs() ? primaryInputCount() : hasInputs() ? 1 : 0;
349346
}
350347

351348
void FrontendInputsAndOutputs::forEachInputProducingSupplementaryOutput(
352349
llvm::function_ref<void(const InputFile &)> fn) const {
353350
if (hasPrimaryInputs())
354351
forEachPrimaryInput(fn);
355-
else
352+
else if (hasInputs())
356353
fn(firstInput());
357354
}
358355

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
// 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
2-
// CHECK1: <unknown>:0: error: wrong number of 'emit-module-path' arguments (expected 1, got 2)
2+
// CHECK1: <unknown>:0: error: wrong number of '-emit-module-path' arguments (expected 1, got 2)

0 commit comments

Comments
 (0)