Skip to content

Commit 416b439

Browse files
committed
Wire up FileSpecificDiagnosticConsumer for serialized diagnostics
It appears to work!
1 parent d0b649a commit 416b439

File tree

7 files changed

+78
-16
lines changed

7 files changed

+78
-16
lines changed

include/swift/Frontend/InputFile.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ class InputFile {
9191
std::string loadedModuleTracePath() const {
9292
return getPrimarySpecificPaths().SupplementaryOutputs.LoadedModuleTracePath;
9393
}
94+
std::string serializedDiagnosticsPath() const {
95+
return getPrimarySpecificPaths().SupplementaryOutputs
96+
.SerializedDiagnosticsPath;
97+
}
9498
};
9599
} // namespace swift
96100

include/swift/Frontend/SerializedDiagnosticConsumer.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,14 @@ namespace swift {
2929
class DiagnosticConsumer;
3030

3131
namespace serialized_diagnostics {
32-
/// \brief Create a DiagnosticConsumer that serializes diagnostics to a
33-
/// file.
32+
/// Create a DiagnosticConsumer that serializes diagnostics to a file, using
33+
/// Clang's serialized diagnostics format.
3434
///
35-
/// \param serializedDiagnosticsPath the file path to write the diagnostics.
35+
/// \param outputPath the file path to write the diagnostics to.
3636
///
3737
/// \returns A new diagnostic consumer that serializes diagnostics.
38-
DiagnosticConsumer *createConsumer(llvm::StringRef serializedDiagnosticsPath);
38+
std::unique_ptr<DiagnosticConsumer>
39+
createConsumer(llvm::StringRef outputPath);
3940
}
4041
}
4142

lib/Frontend/SerializedDiagnosticConsumer.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,9 +222,10 @@ class SerializedDiagnosticConsumer : public DiagnosticConsumer {
222222
};
223223
} // end anonymous namespace
224224

225-
namespace swift { namespace serialized_diagnostics {
226-
DiagnosticConsumer *createConsumer(StringRef serializedDiagnosticsPath) {
227-
return new SerializedDiagnosticConsumer(serializedDiagnosticsPath);
225+
namespace swift {
226+
namespace serialized_diagnostics {
227+
std::unique_ptr<DiagnosticConsumer> createConsumer(StringRef outputPath) {
228+
return llvm::make_unique<SerializedDiagnosticConsumer>(outputPath);
228229
}
229230
} // namespace serialized_diagnostics
230231
} // namespace swift

lib/FrontendTool/FrontendTool.cpp

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1623,20 +1623,34 @@ int swift::performFrontend(ArrayRef<const char *> Args,
16231623
// arguments are generated by the driver, not directly by a user. The driver
16241624
// is responsible for emitting diagnostics for its own errors. See SR-2683
16251625
// for details.
1626-
//
1627-
// FIXME: Do we need one SerializedConsumer per primary? Owned by the
1628-
// SourceFile?
1629-
std::unique_ptr<DiagnosticConsumer> SerializedConsumer;
1626+
std::unique_ptr<DiagnosticConsumer> SerializedConsumerDispatcher;
16301627
{
1631-
const std::string &SerializedDiagnosticsPath =
1632-
Invocation.getSerializedDiagnosticsPathForAtMostOnePrimary();
1633-
if (!SerializedDiagnosticsPath.empty()) {
1634-
SerializedConsumer.reset(
1628+
SmallVector<FileSpecificDiagnosticConsumer::ConsumerPair, 4>
1629+
SerializedConsumers;
1630+
Invocation.getFrontendOptions().InputsAndOutputs
1631+
.forEachInputProducingSupplementaryOutput(
1632+
[&](const InputFile &Input) -> bool {
1633+
std::string SerializedDiagnosticsPath = Input.serializedDiagnosticsPath();
1634+
if (SerializedDiagnosticsPath.empty())
1635+
return false;
1636+
1637+
SerializedConsumers.emplace_back(
1638+
Input.file(),
16351639
serialized_diagnostics::createConsumer(SerializedDiagnosticsPath));
1636-
Instance->addDiagnosticConsumer(SerializedConsumer.get());
1640+
1641+
// Continue for other inputs.
1642+
return false;
1643+
});
1644+
1645+
if (!SerializedConsumers.empty()) {
1646+
SerializedConsumerDispatcher.reset(
1647+
new FileSpecificDiagnosticConsumer(SerializedConsumers));
1648+
Instance->addDiagnosticConsumer(SerializedConsumerDispatcher.get());
16371649
}
16381650
}
16391651

1652+
// FIXME: Do the fix-its need to be multiplexed like the serialized
1653+
// diagnostics?
16401654
std::unique_ptr<DiagnosticConsumer> FixitsConsumer;
16411655
{
16421656
const std::string &FixitsOutputPath =
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
func testHelper() {
2+
nonexistent()
3+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
func foo() {}
2+
func foo() {}
3+
4+
func bar() {
5+
shouldNotShowUpInOutput()
6+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// RUN: rm -f %t.*
2+
3+
// RUN: not %target-swift-frontend -typecheck -primary-file %s -serialize-diagnostics-path %t.main.dia -primary-file %S/Inputs/serialized-diagnostics-batch-mode-helper.swift -serialize-diagnostics-path %t.helper.dia %S/Inputs/serialized-diagnostics-batch-mode-other.swift 2> %t.stderr.txt
4+
// RUN: %FileCheck -check-prefix=CHECK-STDERR %s < %t.stderr.txt
5+
// RUN: %FileCheck -check-prefix=NEGATIVE-STDERR %s < %t.stderr.txt
6+
7+
// RUN: c-index-test -read-diagnostics %t.main.dia 2> %t.main.txt
8+
// RUN: %FileCheck -check-prefix=CHECK-MAIN %s < %t.main.txt
9+
// RUN: %FileCheck -check-prefix=NEGATIVE-MAIN %s < %t.main.txt
10+
11+
// RUN: c-index-test -read-diagnostics %t.helper.dia 2> %t.helper.txt
12+
// RUN: %FileCheck -check-prefix=CHECK-HELPER %s < %t.helper.txt
13+
// RUN: %FileCheck -check-prefix=NEGATIVE-HELPER %s < %t.helper.txt
14+
15+
// NEGATIVE-MAIN-NOT: shouldNotShowUpInOutput
16+
// NEGATIVE-HELPER-NOT: shouldNotShowUpInOutput
17+
// NEGATIVE-STDERR-NOT: shouldNotShowUpInOutput
18+
19+
// NEGATIVE-MAIN-NOT: serialized-diagnostics-batch-mode-helper.swift
20+
// NEGATIVE-HELPER-NOT: serialized-diagnostics-batch-mode.swift
21+
22+
// CHECK-MAIN-DAG: serialized-diagnostics-batch-mode-other.swift:{{[0-9]+}}:6: error: invalid redeclaration of 'foo()'
23+
// CHECK-HELPER-DAG: serialized-diagnostics-batch-mode-other.swift:{{[0-9]+}}:6: error: invalid redeclaration of 'foo()'
24+
// CHECK-STDERR-DAG: serialized-diagnostics-batch-mode-other.swift:{{[0-9]+}}:6: error: invalid redeclaration of 'foo()'
25+
26+
func test() {
27+
nonexistent() // CHECK-MAIN-DAG: serialized-diagnostics-batch-mode.swift:[[@LINE]]:3: error: use of unresolved identifier 'nonexistent'
28+
// CHECK-STDERR-DAG: serialized-diagnostics-batch-mode.swift:[[@LINE-1]]:3: error: use of unresolved identifier 'nonexistent'
29+
30+
// The other file has a similar call.
31+
// CHECK-HELPER-DAG: serialized-diagnostics-batch-mode-helper.swift:{{[0-9]+}}:3: error: use of unresolved identifier 'nonexistent'
32+
// CHECK-STDERR-DAG: serialized-diagnostics-batch-mode-helper.swift:{{[0-9]+}}:3: error: use of unresolved identifier 'nonexistent'
33+
}

0 commit comments

Comments
 (0)