@@ -1509,6 +1509,41 @@ computeStatsReporter(const CompilerInvocation &Invocation, CompilerInstance *Ins
1509
1509
ProfileEvents, ProfileEntities);
1510
1510
}
1511
1511
1512
+ // / Creates a diagnostic consumer that handles dispatching diagnostics to
1513
+ // / multiple output files, based on the supplementary output paths specified by
1514
+ // / \p inputsAndOutputs.
1515
+ // /
1516
+ // / If no output files are needed, returns null.
1517
+ static std::unique_ptr<DiagnosticConsumer>
1518
+ createDispatchingDiagnosticConsumerIfNeeded (
1519
+ const FrontendInputsAndOutputs &inputsAndOutputs,
1520
+ llvm::function_ref<std::unique_ptr<DiagnosticConsumer>(const InputFile &)>
1521
+ maybeCreateSingleConsumer) {
1522
+
1523
+ // The "4" here is somewhat arbitrary. In practice we're going to have one
1524
+ // sub-consumer for each diagnostic file we're trying to output, which (again
1525
+ // in practice) is going to be 1 in WMO mode and equal to the number of
1526
+ // primary inputs in batch mode. That in turn is going to be "the number of
1527
+ // files we need to recompile in this build, divided by the number of jobs".
1528
+ // So a value of "4" here means that there would be no heap allocation on a
1529
+ // clean build of a module with up to 32 files on an 8-core machine, if the
1530
+ // user doesn't customize anything.
1531
+ SmallVector<FileSpecificDiagnosticConsumer::ConsumerPair, 4 > subConsumers;
1532
+
1533
+ inputsAndOutputs.forEachInputProducingSupplementaryOutput (
1534
+ [&](const InputFile &input) -> bool {
1535
+ if (auto subConsumer = maybeCreateSingleConsumer (input))
1536
+ subConsumers.emplace_back (input.file (), std::move (subConsumer));
1537
+ return false ;
1538
+ });
1539
+
1540
+ if (subConsumers.empty ())
1541
+ return nullptr ;
1542
+ if (subConsumers.size () == 1 )
1543
+ return std::move (subConsumers.front ()).second ;
1544
+ return llvm::make_unique<FileSpecificDiagnosticConsumer>(subConsumers);
1545
+ }
1546
+
1512
1547
// / Creates a diagnostic consumer that handles serializing diagnostics, based on
1513
1548
// / the supplementary output paths specified by \p inputsAndOutputs.
1514
1549
// /
@@ -1520,39 +1555,39 @@ computeStatsReporter(const CompilerInvocation &Invocation, CompilerInstance *Ins
1520
1555
static std::unique_ptr<DiagnosticConsumer>
1521
1556
createSerializedDiagnosticConsumerIfNeeded (
1522
1557
const FrontendInputsAndOutputs &inputsAndOutputs) {
1523
-
1524
- // The "4" here is somewhat arbitrary. In practice we're going to have one
1525
- // sub-consumer for each .dia file we're trying to output, which (again in
1526
- // practice) is going to be 1 in WMO mode and equal to the number of primary
1527
- // inputs in batch mode. That in turn is going to be "the number of files we
1528
- // need to recompile in this build, divided by the number of jobs". So a
1529
- // value of "4" here means that there would be no heap allocation on a clean
1530
- // build of a module with up to 32 files on an 8-core machine, if the user
1531
- // doesn't customize anything.
1532
- SmallVector<FileSpecificDiagnosticConsumer::ConsumerPair, 4 >
1533
- serializedConsumers;
1534
-
1535
- inputsAndOutputs.forEachInputProducingSupplementaryOutput (
1536
- [&](const InputFile &Input) -> bool {
1537
- std::string serializedDiagnosticsPath = Input.serializedDiagnosticsPath ();
1558
+ return createDispatchingDiagnosticConsumerIfNeeded (
1559
+ inputsAndOutputs,
1560
+ [](const InputFile &input) -> std::unique_ptr<DiagnosticConsumer> {
1561
+ std::string serializedDiagnosticsPath = input.serializedDiagnosticsPath ();
1538
1562
if (serializedDiagnosticsPath.empty ())
1539
- return false ;
1540
-
1541
- serializedConsumers.emplace_back (
1542
- Input.file (),
1543
- serialized_diagnostics::createConsumer (serializedDiagnosticsPath));
1544
-
1545
- // Continue for other inputs.
1546
- return false ;
1563
+ return nullptr ;
1564
+ return serialized_diagnostics::createConsumer (serializedDiagnosticsPath);
1547
1565
});
1566
+ }
1548
1567
1549
- if (serializedConsumers.empty ())
1550
- return nullptr ;
1551
- if (serializedConsumers.size () == 1 )
1552
- return std::move (serializedConsumers.front ()).second ;
1553
- return llvm::make_unique<FileSpecificDiagnosticConsumer>(serializedConsumers);
1568
+ // / Creates a diagnostic consumer that handles serializing diagnostics, based on
1569
+ // / the supplementary output paths specified in \p options.
1570
+ // /
1571
+ // / The returned consumer will handle producing multiple serialized diagnostics
1572
+ // / files if necessary, by using sub-consumers for each file and dispatching to
1573
+ // / the right one.
1574
+ // /
1575
+ // / If no serialized diagnostics are being produced, returns null.
1576
+ static std::unique_ptr<DiagnosticConsumer>
1577
+ createJSONFixItDiagnosticConsumerIfNeeded (
1578
+ const CompilerInvocation &invocation) {
1579
+ return createDispatchingDiagnosticConsumerIfNeeded (
1580
+ invocation.getFrontendOptions ().InputsAndOutputs ,
1581
+ [&](const InputFile &input) -> std::unique_ptr<DiagnosticConsumer> {
1582
+ std::string fixItsOutputPath = input.fixItsOutputPath ();
1583
+ if (fixItsOutputPath.empty ())
1584
+ return nullptr ;
1585
+ return llvm::make_unique<JSONFixitWriter>(
1586
+ fixItsOutputPath, invocation.getDiagnosticOptions ());
1587
+ });
1554
1588
}
1555
1589
1590
+
1556
1591
int swift::performFrontend (ArrayRef<const char *> Args,
1557
1592
const char *Argv0, void *MainAddr,
1558
1593
FrontendObserver *observer) {
@@ -1671,17 +1706,10 @@ int swift::performFrontend(ArrayRef<const char *> Args,
1671
1706
if (SerializedConsumerDispatcher)
1672
1707
Instance->addDiagnosticConsumer (SerializedConsumerDispatcher.get ());
1673
1708
1674
- // FIXME: The fix-its need to be multiplexed like the serialized diagnostics.
1675
- std::unique_ptr<DiagnosticConsumer> FixitsConsumer;
1676
- {
1677
- const std::string &FixitsOutputPath =
1678
- Invocation.getFrontendOptions ().FixitsOutputPath ;
1679
- if (!FixitsOutputPath.empty ()) {
1680
- FixitsConsumer.reset (new JSONFixitWriter (FixitsOutputPath,
1681
- Invocation.getDiagnosticOptions ()));
1682
- Instance->addDiagnosticConsumer (FixitsConsumer.get ());
1683
- }
1684
- }
1709
+ std::unique_ptr<DiagnosticConsumer> FixItsConsumer =
1710
+ createJSONFixItDiagnosticConsumerIfNeeded (Invocation);
1711
+ if (FixItsConsumer)
1712
+ Instance->addDiagnosticConsumer (FixItsConsumer.get ());
1685
1713
1686
1714
if (Invocation.getDiagnosticOptions ().UseColor )
1687
1715
PDC.forceColors ();
0 commit comments