Skip to content

Commit 372f8ce

Browse files
committed
Truncate serialized dia files instead of non-specific error.
1 parent 8f6028d commit 372f8ce

7 files changed

+41
-39
lines changed

include/swift/AST/DiagnosticConsumer.h

+13-3
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(SourceManager &SM) { 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.
@@ -198,8 +207,9 @@ class FileSpecificDiagnosticConsumer : public DiagnosticConsumer {
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/DiagnosticsFrontend.def

-2
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

+5-21
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ void FileSpecificDiagnosticConsumer::handleDiagnostic(
190190
}
191191

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

195195
// Deliberately don't use std::any_of here because we don't want early-exit
196196
// behavior.
@@ -201,29 +201,13 @@ bool FileSpecificDiagnosticConsumer::finishProcessing(SourceManager &SM) {
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/Frontend/SerializedDiagnosticConsumer.cpp

+19-2
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)) {
@@ -168,11 +170,26 @@ class SerializedDiagnosticConsumer : public DiagnosticConsumer {
168170
return true;
169171
}
170172

171-
OS->write((char *)&State->Buffer.front(), State->Buffer.size());
172-
OS->flush();
173+
if (CompilationWasComplete) {
174+
OS->write((char *)&State->Buffer.front(), State->Buffer.size());
175+
OS->flush();
176+
}
173177
return false;
174178
}
175179

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

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

+2-6
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

+1-2
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

+1-3
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-

0 commit comments

Comments
 (0)