@@ -177,6 +177,16 @@ std::optional<const DiagnosticInfo *> Diagnostic::getWrappedDiagnostic() const {
177
177
return std::nullopt ;
178
178
}
179
179
180
+ SourceLoc Diagnostic::getLocOrDeclLoc () const {
181
+ if (auto loc = getLoc ())
182
+ return loc;
183
+
184
+ if (auto *D = getDecl ())
185
+ return D->getLoc ();
186
+
187
+ return SourceLoc ();
188
+ }
189
+
180
190
static CharSourceRange toCharSourceRange (SourceManager &SM, SourceRange SR) {
181
191
return CharSourceRange (SM, SR.Start , Lexer::getLocForEndOfToken (SM, SR.End ));
182
192
}
@@ -1438,24 +1448,18 @@ DiagnosticEngine::diagnosticInfoForDiagnostic(const Diagnostic &diagnostic,
1438
1448
return std::nullopt ;
1439
1449
1440
1450
// Figure out the source location.
1441
- SourceLoc loc = diagnostic.getLoc ();
1451
+ SourceLoc loc = diagnostic.getLocOrDeclLoc ();
1442
1452
if (loc.isInvalid () && diagnostic.getDecl ()) {
1453
+ // If the location of the decl is invalid, try to pretty-print it into a
1454
+ // buffer and capture the source location there. Make sure we don't have an
1455
+ // active request running since printing AST can kick requests that may
1456
+ // themselves emit diagnostics. This won't help the underlying cycle, but it
1457
+ // at least stops us from overflowing the stack.
1443
1458
const Decl *decl = diagnostic.getDecl ();
1444
- // If a declaration was provided instead of a location, and that declaration
1445
- // has a location we can point to, use that location.
1446
- loc = decl->getLoc ();
1447
-
1448
- // If the location of the decl is invalid still, try to pretty-print the
1449
- // declaration into a buffer and capture the source location there. Make
1450
- // sure we don't have an active request running since printing AST can
1451
- // kick requests that may themselves emit diagnostics. This won't help the
1452
- // underlying cycle, but it at least stops us from overflowing the stack.
1453
- if (loc.isInvalid ()) {
1454
- PrettyPrintDeclRequest req (decl);
1455
- auto &eval = decl->getASTContext ().evaluator ;
1456
- if (!eval.hasActiveRequest (req))
1457
- loc = evaluateOrDefault (eval, req, SourceLoc ());
1458
- }
1459
+ PrettyPrintDeclRequest req (decl);
1460
+ auto &eval = decl->getASTContext ().evaluator ;
1461
+ if (!eval.hasActiveRequest (req))
1462
+ loc = evaluateOrDefault (eval, req, SourceLoc ());
1459
1463
}
1460
1464
1461
1465
auto groupID = diagnostic.getGroupID ();
@@ -1785,6 +1789,20 @@ void DiagnosticEngine::onTentativeDiagnosticFlush(Diagnostic &diagnostic) {
1785
1789
}
1786
1790
}
1787
1791
1792
+ void DiagnosticQueue::forEach (
1793
+ llvm::function_ref<void (const Diagnostic &)> body) const {
1794
+ for (auto &activeDiag : QueueEngine.TentativeDiagnostics )
1795
+ body (activeDiag.Diag );
1796
+ }
1797
+
1798
+ void DiagnosticQueue::filter (
1799
+ llvm::function_ref<bool (const Diagnostic &)> predicate) {
1800
+ llvm::erase_if (QueueEngine.TentativeDiagnostics ,
1801
+ [&](detail::ActiveDiagnostic &activeDiag) {
1802
+ return !predicate (activeDiag.Diag );
1803
+ });
1804
+ }
1805
+
1788
1806
EncodedDiagnosticMessage::EncodedDiagnosticMessage (StringRef S)
1789
1807
: Message(Lexer::getEncodedStringSegment(S, Buf, /* IsFirstSegment=*/ true ,
1790
1808
/* IsLastSegment=*/ true ,
0 commit comments