Skip to content

Commit b4dce82

Browse files
author
David Ungar
committed
Track errors
1 parent 524d88e commit b4dce82

File tree

3 files changed

+35
-32
lines changed

3 files changed

+35
-32
lines changed

include/swift/AST/DiagnosticConsumer.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ class FileSpecificDiagnosticConsumer : public DiagnosticConsumer {
162162
/// This allows diagnostics to be emitted before files are actually opened,
163163
/// as long as they don't have source locations.
164164
///
165-
/// \see #consumerForLocation
165+
/// \see #consumerSpecificInformationForLocation
166166
SmallVector<ConsumerSpecificInformation, 4> ConsumersOrderedByRange;
167167

168168
/// Indicates which consumer to send Note diagnostics too.
@@ -172,7 +172,8 @@ class FileSpecificDiagnosticConsumer : public DiagnosticConsumer {
172172
///
173173
/// If None, Note diagnostics are sent to every consumer.
174174
/// If null, diagnostics are suppressed.
175-
Optional<DiagnosticConsumer *> ConsumerForSubsequentNotes = None;
175+
Optional<ConsumerSpecificInformation *>
176+
ConsumerSpecificInfoForSubsequentNotes = None;
176177

177178
bool WasAnErrorSuppressed = false;
178179

@@ -200,8 +201,9 @@ class FileSpecificDiagnosticConsumer : public DiagnosticConsumer {
200201
/// Returns nullptr if diagnostic is to be suppressed,
201202
/// None if diagnostic is to be distributed to every consumer,
202203
/// a particular consumer if diagnostic goes there.
203-
Optional<DiagnosticConsumer *> consumerForLocation(SourceManager &SM,
204-
SourceLoc loc) const;
204+
Optional<ConsumerSpecificInformation *>
205+
consumerSpecificInformationForLocation(SourceManager &SM,
206+
SourceLoc loc) const;
205207
};
206208

207209
} // end namespace swift

lib/AST/DiagnosticConsumer.cpp

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -101,16 +101,9 @@ void FileSpecificDiagnosticConsumer::computeConsumersOrderedByRange(
101101
"overlapping ranges despite having distinct files");
102102
}
103103

104-
Optional<DiagnosticConsumer *>
105-
FileSpecificDiagnosticConsumer::consumerForLocation(SourceManager &SM,
106-
SourceLoc loc) const {
107-
// If there's only one consumer, we'll use it no matter what, because...
108-
// - ...all diagnostics within the file will go to that consumer.
109-
// - ...all diagnostics not within the file will not be claimed by any
110-
// consumer, and so will go to all (one) consumers.
111-
if (SubConsumers.size() == 1)
112-
return SubConsumers.front().second.get();
113-
104+
Optional<FileSpecificDiagnosticConsumer::ConsumerSpecificInformation *>
105+
FileSpecificDiagnosticConsumer::consumerSpecificInformationForLocation(
106+
SourceManager &SM, SourceLoc loc) const {
114107
// Diagnostics with invalid locations always go to every consumer.
115108
if (loc.isInvalid())
116109
return None;
@@ -141,17 +134,19 @@ FileSpecificDiagnosticConsumer::consumerForLocation(SourceManager &SM,
141134
// that /might/ contain 'loc'. Specifically, since the ranges are sorted
142135
// by end location, it's looking for the first range where the end location
143136
// is greater than or equal to 'loc'.
144-
auto possiblyContainingRangeIter = std::lower_bound(
145-
ConsumersOrderedByRange.begin(), ConsumersOrderedByRange.end(), loc,
146-
[](const ConsumerSpecificInformation &entry, SourceLoc loc) -> bool {
147-
auto compare = std::less<const char *>();
148-
return compare(getRawLoc(entry.range.getEnd()).getPointer(),
149-
getRawLoc(loc).getPointer());
150-
});
137+
const ConsumerSpecificInformation *possiblyContainingRangeIter =
138+
std::lower_bound(
139+
ConsumersOrderedByRange.begin(), ConsumersOrderedByRange.end(), loc,
140+
[](const ConsumerSpecificInformation &entry, SourceLoc loc) -> bool {
141+
auto compare = std::less<const char *>();
142+
return compare(getRawLoc(entry.range.getEnd()).getPointer(),
143+
getRawLoc(loc).getPointer());
144+
});
151145

152146
if (possiblyContainingRangeIter != ConsumersOrderedByRange.end() &&
153147
possiblyContainingRangeIter->range.contains(loc)) {
154-
return possiblyContainingRangeIter->consumer;
148+
return const_cast<ConsumerSpecificInformation *>(
149+
possiblyContainingRangeIter);
155150
}
156151

157152
return None;
@@ -162,31 +157,36 @@ void FileSpecificDiagnosticConsumer::handleDiagnostic(
162157
StringRef FormatString, ArrayRef<DiagnosticArgument> FormatArgs,
163158
const DiagnosticInfo &Info) {
164159

165-
Optional<DiagnosticConsumer *> specificConsumer;
160+
Optional<ConsumerSpecificInformation *> consumerSpecificInfo;
166161
switch (Kind) {
167162
case DiagnosticKind::Error:
168163
case DiagnosticKind::Warning:
169164
case DiagnosticKind::Remark:
170-
specificConsumer = consumerForLocation(SM, Loc);
171-
ConsumerForSubsequentNotes = specificConsumer;
165+
consumerSpecificInfo = consumerSpecificInformationForLocation(SM, Loc);
166+
ConsumerSpecificInfoForSubsequentNotes = consumerSpecificInfo;
172167
break;
173168
case DiagnosticKind::Note:
174-
specificConsumer = ConsumerForSubsequentNotes;
169+
consumerSpecificInfo = ConsumerSpecificInfoForSubsequentNotes;
175170
break;
176171
}
177-
178-
if (!specificConsumer.hasValue()) {
172+
if (!consumerSpecificInfo.hasValue()) {
179173
for (auto &subConsumer : SubConsumers) {
180174
if (subConsumer.second) {
181175
subConsumer.second->handleDiagnostic(SM, Loc, Kind, FormatString,
182176
FormatArgs, Info);
183177
}
184178
}
185-
} else if (DiagnosticConsumer *c = specificConsumer.getValue())
186-
c->handleDiagnostic(SM, Loc, Kind, FormatString, FormatArgs, Info);
187-
else
179+
return;
180+
}
181+
if (!consumerSpecificInfo.getValue()->consumer) {
188182
WasAnErrorSuppressed =
189183
true; // Suppress non-primary diagnostic in batch mode.
184+
return;
185+
}
186+
consumerSpecificInfo.getValue()->consumer->handleDiagnostic(
187+
SM, Loc, Kind, FormatString, FormatArgs, Info);
188+
consumerSpecificInfo.getValue()->hasAnErrorBeenEmitted |=
189+
Kind == DiagnosticKind::Error;
190190
}
191191

192192
bool FileSpecificDiagnosticConsumer::finishProcessing(SourceManager &SM) {

test/Misc/serialized-diagnostics-batch-mode-nonspecific-error.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@
1616

1717
// Ensure the error is in the serialized diagnostics:
1818

19-
// RUN: %FileCheck -check-prefix=NONSPECIFIC-ERROR %s <%t.main.txt
19+
// RUN: %FileCheck -check-prefix=NO-NONSPECIFIC-ERROR %s <%t.main.txt
2020
// RUN: %FileCheck -check-prefix=NONSPECIFIC-ERROR %s <%t.empty.txt
2121
// NONSPECIFIC-ERROR: error: some error occured in a file that was used by this one
22+
// NO-NONSPECIFIC-ERROR-NOT: error: some error occured in a file that was used by this one
2223

2324
func test(x: SomeType) {
2425
nonexistent()

0 commit comments

Comments
 (0)