@@ -213,13 +213,43 @@ void DiagnosticEngine::issue(const Diagnostic& diagnostic) {
213213 severity == DiagnosticSeverity::Fatal;
214214 if (isError && errorLimit && numErrors >= errorLimit) {
215215 Diagnostic diag (diag::TooManyErrors, SourceLocation::NoLocation);
216- issueImpl (diag, DiagnosticSeverity::Fatal);
216+ auto info = getReportedDiag (diag);
217+ SLANG_ASSERT (info);
218+ ReportedDiagnostic report (std::move (*info), DiagnosticSeverity::Fatal);
219+ for (auto & client : clients)
220+ client->report (report);
217221 issuedOverLimitErr = true ;
218222 return ;
219223 }
220224
221- if (!issueImpl (diagnostic, severity))
225+ auto info = getReportedDiag (diagnostic);
226+ if (!info)
222227 return ;
228+ ReportedDiagnostic report (std::move (*info), severity);
229+
230+ for (const Diagnostic& note : diagnostic.notes ) {
231+ // Notes shouldn't have subnotes. We should change this shape too eventually, unless we
232+ // want to support that.
233+ SLANG_ASSERT (note.notes .empty ());
234+
235+ // Notes are ignored if location is "NoLocation" since they frequently make no
236+ // sense without location information.
237+ if (note.location == SourceLocation::NoLocation && !note.code .showNoteWithNoLocation ())
238+ continue ;
239+
240+ auto noteSeverity = getSeverity (note.code , note.location );
241+ if (noteSeverity == DiagnosticSeverity::Ignored)
242+ continue ;
243+
244+ SLANG_ASSERT (noteSeverity == DiagnosticSeverity::Note);
245+
246+ auto noteInfo = getReportedDiag (note);
247+ SLANG_ASSERT (noteInfo);
248+ report.notes .emplace_back (std::move (*noteInfo));
249+ }
250+
251+ for (auto & client : clients)
252+ client->report (report);
223253
224254 if (severity == DiagnosticSeverity::Warning)
225255 numWarnings++;
@@ -232,7 +262,8 @@ void DiagnosticEngine::issue(const Diagnostics& diagnostics) {
232262 issue (diag);
233263}
234264
235- bool DiagnosticEngine::issueImpl (const Diagnostic& diagnostic, DiagnosticSeverity severity) {
265+ std::optional<ReportedDiagnosticInfo> DiagnosticEngine::getReportedDiag (
266+ const Diagnostic& diagnostic) {
236267 // Walk out until we find a location for this diagnostic that isn't inside a macro.
237268 SmallVector<SourceLocation, 8 > expansionLocs;
238269 SourceLocation loc = diagnostic.location ;
@@ -256,12 +287,22 @@ bool DiagnosticEngine::issueImpl(const Diagnostic& diagnostic, DiagnosticSeverit
256287 }
257288
258289 showIncludeStack = reportedIncludeStack.emplace (loc.buffer ()).second ;
290+ }
291+
292+ ReportedDiagnosticInfo report (diagnostic);
293+ report.expansionLocs .assign (expansionLocs.begin () + ptrdiff_t (ignoreExpansionsUntil),
294+ expansionLocs.end ());
295+ report.ranges = diagnostic.ranges ;
296+ report.location = loc;
297+ report.shouldShowIncludeStack = showIncludeStack;
259298
260- auto checkSuppressed = [&](const std::vector<fs::path>& patterns, SourceLocation loc) {
299+ if (loc != SourceLocation::NoLocation &&
300+ getDefaultSeverity (diagnostic.code ) != DiagnosticSeverity::Note) {
301+ auto checkPath = [&](const std::vector<fs::path>& patterns, SourceLocation location) {
261302 if (patterns.empty ())
262303 return false ;
263304
264- auto & path = sourceManager.getFullPath (loc .buffer ());
305+ auto & path = sourceManager.getFullPath (location .buffer ());
265306 for (auto & pattern : patterns) {
266307 if (svGlobMatches (path, pattern))
267308 return true ;
@@ -270,43 +311,22 @@ bool DiagnosticEngine::issueImpl(const Diagnostic& diagnostic, DiagnosticSeverit
270311 };
271312
272313 if (getDefaultSeverity (diagnostic.code ) == DiagnosticSeverity::Warning) {
273- if (checkSuppressed (ignoreWarnPatterns, loc))
274- return false ;
314+ if (checkPath (ignoreWarnPatterns, loc))
315+ return std:: nullopt ;
275316
276- if (ignoreExpansionsUntil < expansionLocs.size () && !ignoreMacroWarnPatterns.empty ()) {
277- auto originalLoc = sourceManager.getFullyOriginalLoc (
278- expansionLocs[ignoreExpansionsUntil]);
279-
280- if (checkSuppressed (ignoreMacroWarnPatterns, originalLoc))
281- return false ;
317+ if (!report.expansionLocs .empty () && !ignoreMacroWarnPatterns.empty ()) {
318+ auto originalLoc = sourceManager.getFullyOriginalLoc (report.expansionLocs .front ());
319+ if (checkPath (ignoreMacroWarnPatterns, originalLoc))
320+ return std::nullopt ;
282321 }
283322 }
284323
285324 if (waiverManager && waiverManager->shouldWaive (diagnostic, loc, sourceManager, *this ))
286- return false ;
287- }
288-
289- std::string message = formatMessage (diagnostic);
290-
291- ReportedDiagnostic report (diagnostic);
292- report.expansionLocs = std::span<SourceLocation>(expansionLocs).subspan (ignoreExpansionsUntil);
293- report.ranges = diagnostic.ranges ;
294- report.location = loc;
295- report.severity = severity;
296- report.formattedMessage = message;
297- report.shouldShowIncludeStack = showIncludeStack;
298-
299- for (auto & client : clients)
300- client->report (report);
301-
302- // Notes are ignored if location is "NoLocation" since they frequently make no
303- // sense without location information.
304- for (const Diagnostic& note : diagnostic.notes ) {
305- if (note.location != SourceLocation::NoLocation || note.code .showNoteWithNoLocation ())
306- issue (note);
325+ return std::nullopt ;
307326 }
308327
309- return true ;
328+ report.formattedMessage = formatMessage (diagnostic);
329+ return report;
310330}
311331
312332const DiagnosticEngine::FormatterMap& DiagnosticEngine::getFormatters () const {
0 commit comments