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 @@ -288,10 +288,12 @@ Patch->apply(*CI); PreserveDiags = Patch->preserveDiagnostics(); } + IgnoreDiagnostics DropDiags; auto Clang = prepareCompilerInstance( std::move(CI), PreamblePCH, llvm::MemoryBuffer::getMemBufferCopy(Inputs.Contents, Filename), VFS, - ASTDiags); + PreserveDiags ? static_cast(ASTDiags) + : static_cast(DropDiags)); if (!Clang) { // The last diagnostic contains information about the reason of this // failure. @@ -301,6 +303,10 @@ : "unknown error"); return None; } + if (!PreserveDiags) { + // Skips some analysis. + Clang->getDiagnosticOpts().IgnoreWarnings = true; + } auto Action = std::make_unique(); const FrontendInputFile &MainInput = Clang->getFrontendOpts().Inputs[0]; @@ -329,7 +335,9 @@ std::vector> CTChecks; ast_matchers::MatchFinder CTFinder; llvm::Optional CTContext; - { + // No need to initalize a clang-tidy context if we are not going to surface + // diagnostics. + if (PreserveDiags) { trace::Span Tracer("ClangTidyInit"); tidy::ClangTidyOptions ClangTidyOpts = getTidyOptionsForFile(Inputs.ClangTidyProvider, Filename); diff --git a/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp b/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp --- a/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp +++ b/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp @@ -460,77 +460,6 @@ Code.substr(FileRange.Begin - 1, FileRange.End - FileRange.Begin + 2)); EXPECT_EQ(SkippedFiles[I].kind(), tok::header_name); } - - TU.AdditionalFiles["a.h"] = ""; - TU.AdditionalFiles["b.h"] = ""; - TU.AdditionalFiles["c.h"] = ""; - // Make sure replay logic works with patched preambles. - llvm::StringLiteral Baseline = R"cpp( - #include "a.h" - #include "c.h")cpp"; - MockFS FS; - TU.Code = Baseline.str(); - auto Inputs = TU.inputs(FS); - auto BaselinePreamble = TU.preamble(); - ASSERT_TRUE(BaselinePreamble); - - // First make sure we don't crash on various modifications to the preamble. - llvm::StringLiteral Cases[] = { - // clang-format off - // New include in middle. - R"cpp( - #include "a.h" - #include "b.h" - #include "c.h")cpp", - // New include at top. - R"cpp( - #include "b.h" - #include "a.h" - #include "c.h")cpp", - // New include at bottom. - R"cpp( - #include "a.h" - #include "c.h" - #include "b.h")cpp", - // Same size with a missing include. - R"cpp( - #include "a.h" - #include "b.h")cpp", - // Smaller with no new includes. - R"cpp( - #include "a.h")cpp", - // Smaller with a new includes. - R"cpp( - #include "b.h")cpp", - // clang-format on - }; - for (llvm::StringLiteral Case : Cases) { - TU.Code = Case.str(); - - IgnoreDiagnostics Diags; - auto CI = buildCompilerInvocation(TU.inputs(FS), Diags); - auto PatchedAST = ParsedAST::build(testPath(TU.Filename), TU.inputs(FS), - std::move(CI), {}, BaselinePreamble); - ASSERT_TRUE(PatchedAST); - EXPECT_FALSE(PatchedAST->getDiagnostics()); - } - - // Then ensure correctness by making sure includes were seen only once. - // Note that we first see the includes from the patch, as preamble includes - // are replayed after exiting the built-in file. - Includes.clear(); - TU.Code = R"cpp( - #include "a.h" - #include "b.h")cpp"; - IgnoreDiagnostics Diags; - auto CI = buildCompilerInvocation(TU.inputs(FS), Diags); - auto PatchedAST = ParsedAST::build(testPath(TU.Filename), TU.inputs(FS), - std::move(CI), {}, BaselinePreamble); - ASSERT_TRUE(PatchedAST); - EXPECT_FALSE(PatchedAST->getDiagnostics()); - EXPECT_THAT(Includes, - ElementsAre(WithFileName(testPath("__preamble_patch__.h")), - WithFileName("b.h"), WithFileName("a.h"))); } TEST(ParsedASTTest, PatchesAdditionalIncludes) {