diff --git a/clang-tools-extra/clangd/ParsedAST.cpp b/clang-tools-extra/clangd/ParsedAST.cpp --- a/clang-tools-extra/clangd/ParsedAST.cpp +++ b/clang-tools-extra/clangd/ParsedAST.cpp @@ -424,15 +424,15 @@ CTFinder.matchAST(Clang->getASTContext()); } + // XXX: This is messy: clang-tidy checks flush some diagnostics at EOF. + // However Action->EndSourceFile() would destroy the ASTContext! + // So just inform the preprocessor of EOF, while keeping everything alive. + Clang->getPreprocessor().EndSourceFile(); // UnitDiagsConsumer is local, we can not store it in CompilerInstance that // has a longer lifetime. Clang->getDiagnostics().setClient(new IgnoreDiagnostics); // CompilerInstance won't run this callback, do it directly. ASTDiags.EndSourceFile(); - // XXX: This is messy: clang-tidy checks flush some diagnostics at EOF. - // However Action->EndSourceFile() would destroy the ASTContext! - // So just inform the preprocessor of EOF, while keeping everything alive. - Clang->getPreprocessor().EndSourceFile(); std::vector Diags = CompilerInvocationDiags; // Add diagnostics from the preamble, if any. diff --git a/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp b/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp --- a/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp +++ b/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp @@ -29,6 +29,8 @@ namespace { using ::testing::_; +using ::testing::AllOf; +using ::testing::Contains; using ::testing::ElementsAre; using ::testing::Field; using ::testing::IsEmpty; @@ -278,6 +280,23 @@ "use a trailing return type for this function"))))); } +TEST(DiagnosticsTest, ClangTidyEOF) { + // clang-format off + Annotations Test(R"cpp( + [[#]]include + #include "a.h")cpp"); + // clang-format on + auto TU = TestTU::withCode(Test.code()); + TU.ExtraArgs = {"-isystem."}; + TU.AdditionalFiles["a.h"] = TU.AdditionalFiles["b.h"] = ""; + TU.ClangTidyChecks = "-*, llvm-include-order"; + EXPECT_THAT( + TU.build().getDiagnostics(), + Contains(AllOf(Diag(Test.range(), "#includes are not sorted properly"), + DiagSource(Diag::ClangTidy), + DiagName("llvm-include-order")))); +} + TEST(DiagnosticTest, TemplatesInHeaders) { // Diagnostics from templates defined in headers are placed at the expansion. Annotations Main(R"cpp(