@@ -1334,7 +1334,7 @@ static bool performCompileStepsPostSILGen(
1334
1334
1335
1335
// Just because we had an AST error it doesn't mean we can't performLLVM.
1336
1336
bool HadError = Instance.getASTContext ().hadError ();
1337
-
1337
+
1338
1338
// If the AST Context has no errors but no IRModule is available,
1339
1339
// parallelIRGen happened correctly, since parallel IRGen produces multiple
1340
1340
// modules.
@@ -1508,6 +1508,50 @@ computeStatsReporter(const CompilerInvocation &Invocation, CompilerInstance *Ins
1508
1508
ProfileEvents, ProfileEntities);
1509
1509
}
1510
1510
1511
+ // / Creates a diagnostic consumer that handles serializing diagnostics, based on
1512
+ // / the supplementary output paths specified by \p inputsAndOutputs.
1513
+ // /
1514
+ // / The returned consumer will handle producing multiple serialized diagnostics
1515
+ // / files if necessary, by using sub-consumers for each file and dispatching to
1516
+ // / the right one.
1517
+ // /
1518
+ // / If no serialized diagnostics are being produced, returns null.
1519
+ static std::unique_ptr<DiagnosticConsumer>
1520
+ createSerializedDiagnosticConsumerIfNeeded (
1521
+ const FrontendInputsAndOutputs &inputsAndOutputs) {
1522
+
1523
+ // The "4" here is somewhat arbitrary. In practice we're going to have one
1524
+ // sub-consumer for each .dia file we're trying to output, which (again in
1525
+ // practice) is going to be 1 in WMO mode and equal to the number of primary
1526
+ // inputs in batch mode. That in turn is going to be "the number of files we
1527
+ // need to recompile in this build, divided by the number of jobs". So a
1528
+ // value of "4" here means that there would be no heap allocation on a clean
1529
+ // build of a module with up to 32 files on an 8-core machine, if the user
1530
+ // doesn't customize anything.
1531
+ SmallVector<FileSpecificDiagnosticConsumer::ConsumerPair, 4 >
1532
+ serializedConsumers;
1533
+
1534
+ inputsAndOutputs.forEachInputProducingSupplementaryOutput (
1535
+ [&](const InputFile &Input) -> bool {
1536
+ std::string serializedDiagnosticsPath = Input.serializedDiagnosticsPath ();
1537
+ if (serializedDiagnosticsPath.empty ())
1538
+ return false ;
1539
+
1540
+ serializedConsumers.emplace_back (
1541
+ Input.file (),
1542
+ serialized_diagnostics::createConsumer (serializedDiagnosticsPath));
1543
+
1544
+ // Continue for other inputs.
1545
+ return false ;
1546
+ });
1547
+
1548
+ if (serializedConsumers.empty ())
1549
+ return nullptr ;
1550
+ if (serializedConsumers.size () == 1 )
1551
+ return std::move (serializedConsumers.front ()).second ;
1552
+ return llvm::make_unique<FileSpecificDiagnosticConsumer>(serializedConsumers);
1553
+ }
1554
+
1511
1555
int swift::performFrontend (ArrayRef<const char *> Args,
1512
1556
const char *Argv0, void *MainAddr,
1513
1557
FrontendObserver *observer) {
@@ -1623,20 +1667,13 @@ int swift::performFrontend(ArrayRef<const char *> Args,
1623
1667
// arguments are generated by the driver, not directly by a user. The driver
1624
1668
// is responsible for emitting diagnostics for its own errors. See SR-2683
1625
1669
// for details.
1626
- //
1627
- // FIXME: Do we need one SerializedConsumer per primary? Owned by the
1628
- // SourceFile?
1629
- std::unique_ptr<DiagnosticConsumer> SerializedConsumer;
1630
- {
1631
- const std::string &SerializedDiagnosticsPath =
1632
- Invocation.getSerializedDiagnosticsPathForAtMostOnePrimary ();
1633
- if (!SerializedDiagnosticsPath.empty ()) {
1634
- SerializedConsumer.reset (
1635
- serialized_diagnostics::createConsumer (SerializedDiagnosticsPath));
1636
- Instance->addDiagnosticConsumer (SerializedConsumer.get ());
1637
- }
1638
- }
1670
+ std::unique_ptr<DiagnosticConsumer> SerializedConsumerDispatcher =
1671
+ createSerializedDiagnosticConsumerIfNeeded (
1672
+ Invocation.getFrontendOptions ().InputsAndOutputs );
1673
+ if (SerializedConsumerDispatcher)
1674
+ Instance->addDiagnosticConsumer (SerializedConsumerDispatcher.get ());
1639
1675
1676
+ // FIXME: The fix-its need to be multiplexed like the serialized diagnostics.
1640
1677
std::unique_ptr<DiagnosticConsumer> FixitsConsumer;
1641
1678
{
1642
1679
const std::string &FixitsOutputPath =
0 commit comments