Skip to content

Commit 1d1e4f3

Browse files
author
David Ungar
authored
Merge pull request #17131 from davidungar/rdar-40167351-repl-non-specifics-w-zero-length-serialized-diagnostics
[Batch Mode] rdar://40167351 Replace non-specific error with truncated serialized diagnostics files.
2 parents 39cd2f9 + 20d099d commit 1d1e4f3

11 files changed

+63
-60
lines changed

include/swift/AST/DiagnosticConsumer.h

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,16 @@ class DiagnosticConsumer {
100100
const DiagnosticInfo &Info) = 0;
101101

102102
/// \returns true if an error occurred while finishing-up.
103-
virtual bool finishProcessing(SourceManager &) { return false; }
103+
virtual bool finishProcessing() { return false; }
104+
105+
/// In batch mode, any error causes failure for all primary files, but
106+
/// anyone consulting .dia files will only see an error for a particular
107+
/// primary in that primary's serialized diagnostics file. For other
108+
/// primaries' serialized diagnostics files, do something to signal the driver
109+
/// what happened. This is only meaningful for SerializedDiagnosticConsumers,
110+
/// so here's a placeholder.
111+
112+
virtual void informDriverOfIncompleteBatchModeCompilation() {}
104113
};
105114

106115
/// \brief DiagnosticConsumer that discards all diagnostics.
@@ -193,13 +202,14 @@ class FileSpecificDiagnosticConsumer : public DiagnosticConsumer {
193202
ArrayRef<DiagnosticArgument> FormatArgs,
194203
const DiagnosticInfo &Info) override;
195204

196-
bool finishProcessing(SourceManager &) override;
205+
bool finishProcessing() override;
197206

198207
private:
199208
/// In batch mode, any error causes failure for all primary files, but
200209
/// Xcode will only see an error for a particular primary in that primary's
201-
/// serialized diagnostics file. So, emit errors for all other primaries here.
202-
void addNonSpecificErrors(SourceManager &SM);
210+
/// serialized diagnostics file. So, tell the subconsumers to inform the
211+
/// driver of incomplete batch mode compilation.
212+
void tellSubconsumersToInformDriverOfIncompleteBatchModeCompilation() const;
203213

204214
void computeConsumersOrderedByRange(SourceManager &SM);
205215

include/swift/AST/DiagnosticEngine.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -759,7 +759,7 @@ namespace swift {
759759

760760
/// \returns true if any diagnostic consumer gave an error while invoking
761761
//// \c finishProcessing.
762-
bool finishProcessing(SourceManager &);
762+
bool finishProcessing();
763763

764764
/// \brief Format the given diagnostic text and place the result in the given
765765
/// buffer.

include/swift/AST/DiagnosticsFrontend.def

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,6 @@ WARNING(cannot_assign_value_to_conditional_compilation_flag,none,
235235
ERROR(error_optimization_remark_pattern, none, "%0 in '%1'",
236236
(StringRef, StringRef))
237237

238-
ERROR(error_compilation_stopped_by_errors_in_other_files,none, "compilation stopped by errors in other files", ())
239-
240238
#ifndef DIAG_NO_UNDEF
241239
# if defined(DIAG)
242240
# undef DIAG

lib/AST/DiagnosticConsumer.cpp

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -189,41 +189,25 @@ void FileSpecificDiagnosticConsumer::handleDiagnostic(
189189
Kind == DiagnosticKind::Error;
190190
}
191191

192-
bool FileSpecificDiagnosticConsumer::finishProcessing(SourceManager &SM) {
193-
addNonSpecificErrors(SM);
192+
bool FileSpecificDiagnosticConsumer::finishProcessing() {
193+
tellSubconsumersToInformDriverOfIncompleteBatchModeCompilation();
194194

195195
// Deliberately don't use std::any_of here because we don't want early-exit
196196
// behavior.
197197

198198
bool hadError = false;
199199
for (auto &subConsumer : SubConsumers)
200-
hadError |= subConsumer.second && subConsumer.second->finishProcessing(SM);
200+
hadError |= subConsumer.second && subConsumer.second->finishProcessing();
201201
return hadError;
202202
}
203203

204-
static void produceNonSpecificError(
205-
FileSpecificDiagnosticConsumer::ConsumerSpecificInformation &consumerInfo,
206-
SourceManager &SM) {
207-
Diagnostic diagnostic(
208-
diag::error_compilation_stopped_by_errors_in_other_files);
209-
210-
// Stolen from DiagnosticEngine::emitDiagnostic
211-
DiagnosticInfo Info;
212-
Info.ID = diagnostic.getID();
213-
214-
consumerInfo.consumer->handleDiagnostic(
215-
SM, consumerInfo.range.getStart(), DiagnosticKind::Error,
216-
DiagnosticEngine::diagnosticStringFor(diagnostic.getID()), {}, Info);
217-
}
218-
219-
void FileSpecificDiagnosticConsumer::addNonSpecificErrors(SourceManager &SM) {
204+
void FileSpecificDiagnosticConsumer::
205+
tellSubconsumersToInformDriverOfIncompleteBatchModeCompilation() const {
220206
if (!HasAnErrorBeenConsumed)
221207
return;
222208
for (auto &info : ConsumersOrderedByRange) {
223-
if (!info.hasAnErrorBeenEmitted && info.consumer) {
224-
produceNonSpecificError(info, SM);
225-
info.hasAnErrorBeenEmitted = true;
226-
}
209+
if (!info.hasAnErrorBeenEmitted && info.consumer)
210+
info.consumer->informDriverOfIncompleteBatchModeCompilation();
227211
}
228212
}
229213

lib/AST/DiagnosticEngine.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,10 +251,10 @@ bool DiagnosticEngine::isDiagnosticPointsToFirstBadToken(DiagID ID) const {
251251
return storedDiagnosticInfos[(unsigned) ID].pointsToFirstBadToken;
252252
}
253253

254-
bool DiagnosticEngine::finishProcessing(SourceManager &SM) {
254+
bool DiagnosticEngine::finishProcessing() {
255255
bool hadError = false;
256256
for (auto &Consumer : Consumers) {
257-
hadError |= Consumer->finishProcessing(SM);
257+
hadError |= Consumer->finishProcessing();
258258
}
259259
return hadError;
260260
}

lib/Frontend/SerializedDiagnosticConsumer.cpp

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ class SerializedDiagnosticConsumer : public DiagnosticConsumer {
130130
/// \brief State shared among the various clones of this diagnostic consumer.
131131
llvm::IntrusiveRefCntPtr<SharedState> State;
132132
bool CalledFinishProcessing = false;
133+
bool CompilationWasComplete = true;
134+
133135
public:
134136
SerializedDiagnosticConsumer(StringRef serializedDiagnosticsPath)
135137
: State(new SharedState(serializedDiagnosticsPath)) {
@@ -140,7 +142,7 @@ class SerializedDiagnosticConsumer : public DiagnosticConsumer {
140142
assert(CalledFinishProcessing && "did not call finishProcessing()");
141143
}
142144

143-
bool finishProcessing(SourceManager &SM) override {
145+
bool finishProcessing() override {
144146
assert(!CalledFinishProcessing &&
145147
"called finishProcessing() multiple times");
146148
CalledFinishProcessing = true;
@@ -160,19 +162,35 @@ class SerializedDiagnosticConsumer : public DiagnosticConsumer {
160162
llvm::sys::fs::F_None));
161163
if (EC) {
162164
// Create a temporary diagnostics engine to print the error to stderr.
163-
DiagnosticEngine DE(SM);
165+
SourceManager dummyMgr;
166+
DiagnosticEngine DE(dummyMgr);
164167
PrintingDiagnosticConsumer PDC;
165168
DE.addConsumer(PDC);
166169
DE.diagnose(SourceLoc(), diag::cannot_open_serialized_file,
167170
State->SerializedDiagnosticsPath, EC.message());
168171
return true;
169172
}
170173

171-
OS->write((char *)&State->Buffer.front(), State->Buffer.size());
172-
OS->flush();
174+
if (CompilationWasComplete) {
175+
OS->write((char *)&State->Buffer.front(), State->Buffer.size());
176+
OS->flush();
177+
}
173178
return false;
174179
}
175180

181+
/// In batch mode, if any error occurs, no primaries can be compiled.
182+
/// Some primaries will have errors in their diagnostics files and so
183+
/// a client (such as Xcode) can see that those primaries failed.
184+
/// Other primaries will have no errors in their diagnostics files.
185+
/// In order for the driver to distinguish the two cases without parsing
186+
/// the diagnostics, the frontend emits a truncated diagnostics file
187+
/// for the latter case.
188+
/// The unfortunate aspect is that the truncation discards warnings, etc.
189+
190+
void informDriverOfIncompleteBatchModeCompilation() override {
191+
CompilationWasComplete = false;
192+
}
193+
176194
void handleDiagnostic(SourceManager &SM, SourceLoc Loc,
177195
DiagnosticKind Kind,
178196
StringRef FormatString,

lib/FrontendTool/FrontendTool.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ class JSONFixitWriter
405405
}
406406
}
407407

408-
bool finishProcessing(SourceManager &) override {
408+
bool finishProcessing() override {
409409
std::error_code EC;
410410
std::unique_ptr<llvm::raw_fd_ostream> OS;
411411
OS.reset(new llvm::raw_fd_ostream(FixitsOutputPath,
@@ -1659,7 +1659,7 @@ int swift::performFrontend(ArrayRef<const char *> Args,
16591659

16601660
auto finishDiagProcessing = [&](int retValue) -> int {
16611661
FinishDiagProcessingCheckRAII.CalledFinishDiagProcessing = true;
1662-
bool err = Instance->getDiags().finishProcessing(Instance->getSourceMgr());
1662+
bool err = Instance->getDiags().finishProcessing();
16631663
return retValue ? retValue : err;
16641664
};
16651665

test/Misc/serialized-diagnostics-batch-mode-nonprimary-errors-only.swift

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,9 @@
33
// RUN: rm -f %t.*
44

55
// RUN: not %target-swift-frontend -typecheck -primary-file %s -serialize-diagnostics-path %t.main.dia -primary-file %S/../Inputs/empty.swift -serialize-diagnostics-path %t.empty.dia %S/Inputs/serialized-diagnostics-batch-mode-suppression-helper.swift 2> %t.stderr.txt
6-
// RUN: c-index-test -read-diagnostics %t.main.dia 2> %t.main.txt
7-
// RUN: c-index-test -read-diagnostics %t.empty.dia 2> %t.empty.txt
8-
9-
// RUN: %FileCheck -check-prefix=GENERAL-ERROR-OCCURRED %s <%t.main.txt
10-
// RUN: %FileCheck -check-prefix=GENERAL-ERROR-OCCURRED %s <%t.empty.txt
11-
// GENERAL-ERROR-OCCURRED: compilation stopped by errors in other files
126

7+
// RUN: test -e %t.main.dia -a ! -s %t.empty.dia
8+
// RUN: test -e %t.empty.dia -a ! -s %t.empty.dia
139

1410
func test(x: SomeType) {
1511
}

test/Misc/serialized-diagnostics-batch-mode-nonprimary-errors.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@
44

55
// RUN: not %target-swift-frontend -typecheck -primary-file %s -serialize-diagnostics-path %t.main.dia -primary-file %S/../Inputs/empty.swift -serialize-diagnostics-path %t.empty.dia %S/Inputs/serialized-diagnostics-batch-mode-suppression-helper.swift 2> %t.stderr.txt
66
// RUN: c-index-test -read-diagnostics %t.main.dia 2> %t.main.txt
7-
// RUN: c-index-test -read-diagnostics %t.empty.dia 2> %t.empty.txt
87

98
// RUN: %FileCheck -check-prefix=NO-GENERAL-ERROR-OCCURRED %s <%t.main.txt
10-
// RUN: %FileCheck -check-prefix=GENERAL-ERROR-OCCURRED %s <%t.empty.txt
9+
// RUN: test -e %t.empty.dia -a ! -s %t.empty.dia
1110
// GENERAL-ERROR-OCCURRED: compilation stopped by errors in other files
1211
// NO-GENERAL-ERROR-OCCURRED-NOT: compilation stopped by errors in other files
1312

test/Misc/serialized-diagnostics-batch-mode-primary-errors.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,10 @@
44

55
// RUN: not %target-swift-frontend -typecheck -primary-file %s -serialize-diagnostics-path %t.main.dia -primary-file %S/../Inputs/empty.swift -serialize-diagnostics-path %t.empty.dia 2> %t.stderr.txt
66
// RUN: c-index-test -read-diagnostics %t.main.dia 2> %t.main.txt
7-
// RUN: c-index-test -read-diagnostics %t.empty.dia 2> %t.empty.txt
87

98
// RUN: %FileCheck -check-prefix=ERROR %s <%t.main.txt
109
// RUN: %FileCheck -check-prefix=NO-NONSPECIFIC-ERROR %s <%t.main.txt
11-
// RUN: %FileCheck -check-prefix=NONSPECIFIC-ERROR %s <%t.empty.txt
10+
// RUN: test -e %t.empty.dia -a ! -s %t.empty.dia
1211

1312
// ERROR: error:
1413
// NONSPECIFIC-ERROR: error: compilation stopped by errors in other files
@@ -17,4 +16,3 @@
1716
func test(x: SomeType) {
1817
nonexistent()
1918
}
20-

unittests/AST/DiagnosticConsumerTests.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ namespace {
4343
expected.erase(expected.begin());
4444
}
4545

46-
bool finishProcessing(SourceManager &) override {
46+
bool finishProcessing() override {
4747
EXPECT_FALSE(hasFinished);
4848
if (previous)
4949
EXPECT_TRUE(previous->hasFinished);
@@ -68,7 +68,7 @@ TEST(FileSpecificDiagnosticConsumer, SubConsumersFinishInOrder) {
6868
consumers.emplace_back("", std::move(consumerUnaffiliated));
6969

7070
FileSpecificDiagnosticConsumer topConsumer(consumers);
71-
topConsumer.finishProcessing(sourceMgr);
71+
topConsumer.finishProcessing();
7272
}
7373

7474
TEST(FileSpecificDiagnosticConsumer, InvalidLocDiagsGoToEveryConsumer) {
@@ -89,7 +89,7 @@ TEST(FileSpecificDiagnosticConsumer, InvalidLocDiagsGoToEveryConsumer) {
8989
FileSpecificDiagnosticConsumer topConsumer(consumers);
9090
topConsumer.handleDiagnostic(sourceMgr, SourceLoc(), DiagnosticKind::Error,
9191
"dummy", {}, DiagnosticInfo());
92-
topConsumer.finishProcessing(sourceMgr);
92+
topConsumer.finishProcessing();
9393
}
9494

9595
TEST(FileSpecificDiagnosticConsumer, ErrorsWithLocationsGoToExpectedConsumers) {
@@ -139,7 +139,7 @@ TEST(FileSpecificDiagnosticConsumer, ErrorsWithLocationsGoToExpectedConsumers) {
139139
"back", {}, DiagnosticInfo());
140140
topConsumer.handleDiagnostic(sourceMgr, backOfB, DiagnosticKind::Error,
141141
"back", {}, DiagnosticInfo());
142-
topConsumer.finishProcessing(sourceMgr);
142+
topConsumer.finishProcessing();
143143
}
144144

145145
TEST(FileSpecificDiagnosticConsumer,
@@ -193,7 +193,7 @@ TEST(FileSpecificDiagnosticConsumer,
193193
"back", {}, DiagnosticInfo());
194194
topConsumer.handleDiagnostic(sourceMgr, backOfB, DiagnosticKind::Error,
195195
"back", {}, DiagnosticInfo());
196-
topConsumer.finishProcessing(sourceMgr);
196+
topConsumer.finishProcessing();
197197
}
198198

199199
TEST(FileSpecificDiagnosticConsumer, WarningsAndRemarksAreTreatedLikeErrors) {
@@ -234,7 +234,7 @@ TEST(FileSpecificDiagnosticConsumer, WarningsAndRemarksAreTreatedLikeErrors) {
234234
"remark", {}, DiagnosticInfo());
235235
topConsumer.handleDiagnostic(sourceMgr, frontOfB, DiagnosticKind::Remark,
236236
"remark", {}, DiagnosticInfo());
237-
topConsumer.finishProcessing(sourceMgr);
237+
topConsumer.finishProcessing();
238238
}
239239

240240
TEST(FileSpecificDiagnosticConsumer, NotesAreAttachedToErrors) {
@@ -296,7 +296,7 @@ TEST(FileSpecificDiagnosticConsumer, NotesAreAttachedToErrors) {
296296
"note", {}, DiagnosticInfo());
297297
topConsumer.handleDiagnostic(sourceMgr, backOfA, DiagnosticKind::Note,
298298
"note", {}, DiagnosticInfo());
299-
topConsumer.finishProcessing(sourceMgr);
299+
topConsumer.finishProcessing();
300300
}
301301

302302
TEST(FileSpecificDiagnosticConsumer, NotesAreAttachedToWarningsAndRemarks) {
@@ -358,7 +358,7 @@ TEST(FileSpecificDiagnosticConsumer, NotesAreAttachedToWarningsAndRemarks) {
358358
"note", {}, DiagnosticInfo());
359359
topConsumer.handleDiagnostic(sourceMgr, backOfA, DiagnosticKind::Note,
360360
"note", {}, DiagnosticInfo());
361-
topConsumer.finishProcessing(sourceMgr);
361+
topConsumer.finishProcessing();
362362
}
363363

364364
TEST(FileSpecificDiagnosticConsumer, NotesAreAttachedToErrorsEvenAcrossFiles) {
@@ -417,7 +417,7 @@ TEST(FileSpecificDiagnosticConsumer, NotesAreAttachedToErrorsEvenAcrossFiles) {
417417
"note", {}, DiagnosticInfo());
418418
topConsumer.handleDiagnostic(sourceMgr, backOfA, DiagnosticKind::Note,
419419
"note", {}, DiagnosticInfo());
420-
topConsumer.finishProcessing(sourceMgr);
420+
topConsumer.finishProcessing();
421421
}
422422

423423
TEST(FileSpecificDiagnosticConsumer,
@@ -480,7 +480,7 @@ TEST(FileSpecificDiagnosticConsumer,
480480
"note", {}, DiagnosticInfo());
481481
topConsumer.handleDiagnostic(sourceMgr, backOfA, DiagnosticKind::Note,
482482
"note", {}, DiagnosticInfo());
483-
topConsumer.finishProcessing(sourceMgr);
483+
topConsumer.finishProcessing();
484484
}
485485

486486

@@ -529,5 +529,5 @@ TEST(FileSpecificDiagnosticConsumer,
529529
"error", {}, DiagnosticInfo());
530530
topConsumer.handleDiagnostic(sourceMgr, SourceLoc(), DiagnosticKind::Note,
531531
"note", {}, DiagnosticInfo());
532-
topConsumer.finishProcessing(sourceMgr);
532+
topConsumer.finishProcessing();
533533
}

0 commit comments

Comments
 (0)