@@ -177,6 +177,16 @@ std::optional<const DiagnosticInfo *> Diagnostic::getWrappedDiagnostic() const {
177177 return std::nullopt ;
178178}
179179
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+
180190static CharSourceRange toCharSourceRange (SourceManager &SM, SourceRange SR) {
181191 return CharSourceRange (SM, SR.Start , Lexer::getLocForEndOfToken (SM, SR.End ));
182192}
@@ -1438,24 +1448,18 @@ DiagnosticEngine::diagnosticInfoForDiagnostic(const Diagnostic &diagnostic,
14381448 return std::nullopt ;
14391449
14401450 // Figure out the source location.
1441- SourceLoc loc = diagnostic.getLoc ();
1451+ SourceLoc loc = diagnostic.getLocOrDeclLoc ();
14421452 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.
14431458 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 ());
14591463 }
14601464
14611465 auto groupID = diagnostic.getGroupID ();
@@ -1785,6 +1789,20 @@ void DiagnosticEngine::onTentativeDiagnosticFlush(Diagnostic &diagnostic) {
17851789 }
17861790}
17871791
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+
17881806EncodedDiagnosticMessage::EncodedDiagnosticMessage (StringRef S)
17891807 : Message(Lexer::getEncodedStringSegment(S, Buf, /* IsFirstSegment=*/ true ,
17901808 /* IsLastSegment=*/ true ,
0 commit comments