diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp index a71813a103df3..c35f0b941c600 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp +++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp @@ -358,8 +358,27 @@ getFixIt(const tooling::Diagnostic &Diagnostic, bool AnyFix) { } // namespace clang::tidy +void ClangTidyDiagnosticConsumer::BeginSourceFile(const LangOptions &LangOpts, + const Preprocessor *PP) { + DiagnosticConsumer::BeginSourceFile(LangOpts, PP); + + assert(!InSourceFile); + InSourceFile = true; +} + +void ClangTidyDiagnosticConsumer::EndSourceFile() { + assert(InSourceFile); + InSourceFile = false; + + DiagnosticConsumer::EndSourceFile(); +} + void ClangTidyDiagnosticConsumer::HandleDiagnostic( DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info) { + // A diagnostic should not be reported outside of a + // BeginSourceFile()/EndSourceFile() pair if it has a source location. + assert(InSourceFile || Info.getLocation().isInvalid()); + if (LastErrorWasIgnored && DiagLevel == DiagnosticsEngine::Note) return; diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h index a8851e794f24b..e8887a3fe2bf8 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h +++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h @@ -292,6 +292,11 @@ class ClangTidyDiagnosticConsumer : public DiagnosticConsumer { void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info) override; + void BeginSourceFile(const LangOptions &LangOpts, + const Preprocessor *PP = nullptr) override; + + void EndSourceFile() override; + // Retrieve the diagnostics that were captured. std::vector take(); @@ -326,6 +331,7 @@ class ClangTidyDiagnosticConsumer : public DiagnosticConsumer { bool LastErrorRelatesToUserCode = false; bool LastErrorPassesLineFilter = false; bool LastErrorWasIgnored = false; + bool InSourceFile = false; }; } // end namespace tidy diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp index ef7ae27a2694a..f5996a8e1e88b 100644 --- a/clang/lib/Frontend/FrontendAction.cpp +++ b/clang/lib/Frontend/FrontendAction.cpp @@ -1243,13 +1243,15 @@ llvm::Error FrontendAction::Execute() { void FrontendAction::EndSourceFile() { CompilerInstance &CI = getCompilerInstance(); - // Inform the diagnostic client we are done with this source file. - CI.getDiagnosticClient().EndSourceFile(); - // Inform the preprocessor we are done. if (CI.hasPreprocessor()) CI.getPreprocessor().EndSourceFile(); + // Inform the diagnostic client we are done with this source file. + // Do this after notifying the preprocessor, so that end-of-file preprocessor + // callbacks can report diagnostics. + CI.getDiagnosticClient().EndSourceFile(); + // Finalize the action. EndSourceFileAction();