diff --git a/clang-tools-extra/clangd/Diagnostics.h b/clang-tools-extra/clangd/Diagnostics.h --- a/clang-tools-extra/clangd/Diagnostics.h +++ b/clang-tools-extra/clangd/Diagnostics.h @@ -171,7 +171,6 @@ SourceManager *OrigSrcMgr = nullptr; llvm::DenseSet> IncludedErrorLocations; - bool LastPrimaryDiagnosticWasSuppressed = false; }; /// Determine whether a (non-clang-tidy) diagnostic is suppressed by config. diff --git a/clang-tools-extra/clangd/Diagnostics.cpp b/clang-tools-extra/clangd/Diagnostics.cpp --- a/clang-tools-extra/clangd/Diagnostics.cpp +++ b/clang-tools-extra/clangd/Diagnostics.cpp @@ -727,44 +727,37 @@ // Handle the new main diagnostic. flushLastDiag(); - if (Adjuster) { + // FIXME: Merge with feature modules. + if (Adjuster) DiagLevel = Adjuster(DiagLevel, Info); - if (DiagLevel == DiagnosticsEngine::Ignored) { - LastPrimaryDiagnosticWasSuppressed = true; - return; - } - } - LastPrimaryDiagnosticWasSuppressed = false; LastDiag = Diag(); FillDiagBase(*LastDiag); LastDiagLoc.emplace(Info.getLocation(), Info.getSourceManager()); LastDiagOriginallyError = OriginallyError; + if (DiagCB) + DiagCB(Info, *LastDiag); if (!Info.getFixItHints().empty()) AddFix(true /* try to invent a message instead of repeating the diag */); if (Fixer) { - auto ExtraFixes = Fixer(DiagLevel, Info); + auto ExtraFixes = Fixer(LastDiag->Severity, Info); LastDiag->Fixes.insert(LastDiag->Fixes.end(), ExtraFixes.begin(), ExtraFixes.end()); } - if (DiagCB) - DiagCB(Info, *LastDiag); } else { // Handle a note to an existing diagnostic. - - // If a diagnostic was suppressed due to the suppression filter, - // also suppress notes associated with it. - if (LastPrimaryDiagnosticWasSuppressed) { - return; - } - if (!LastDiag) { assert(false && "Adding a note without main diagnostic"); IgnoreDiagnostics::log(DiagLevel, Info); return; } + // If a diagnostic was suppressed due to the suppression filter, + // also suppress notes associated with it. + if (LastDiag->Severity == DiagnosticsEngine::Ignored) + return; + if (!Info.getFixItHints().empty()) { // A clang note with fix-it is not a separate diagnostic in clangd. We // attach it as a Fix to the main diagnostic instead. @@ -789,7 +782,7 @@ LastDiag.reset(); }); - if (isExcluded(*LastDiag)) + if (LastDiag->Severity == DiagnosticsEngine::Ignored || isExcluded(*LastDiag)) return; // Move errors that occur from headers into main file. if (!LastDiag->InsideMainFile && LastDiagLoc && LastDiagOriginallyError) { diff --git a/clang-tools-extra/clangd/unittests/FeatureModulesTests.cpp b/clang-tools-extra/clangd/unittests/FeatureModulesTests.cpp --- a/clang-tools-extra/clangd/unittests/FeatureModulesTests.cpp +++ b/clang-tools-extra/clangd/unittests/FeatureModulesTests.cpp @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// +#include "Annotations.h" #include "FeatureModule.h" #include "Selection.h" #include "TestTU.h" @@ -53,6 +54,37 @@ EXPECT_EQ(Actual->get()->id(), TweakID); } +TEST(FeatureModulesTest, SuppressDiags) { + struct DiagModifierModule final : public FeatureModule { + struct Listener : public FeatureModule::ASTListener { + void sawDiagnostic(const clang::Diagnostic &Info, + clangd::Diag &Diag) override { + Diag.Severity = DiagnosticsEngine::Ignored; + } + }; + std::unique_ptr astListeners() override { + return std::make_unique(); + }; + }; + FeatureModuleSet FMS; + FMS.add(std::make_unique()); + + Annotations Code("[[test]]; /* error-ok */"); + TestTU TU; + TU.Code = Code.code().str(); + + { + auto AST = TU.build(); + EXPECT_THAT(*AST.getDiagnostics(), testing::Not(testing::IsEmpty())); + } + + TU.FeatureModules = &FMS; + { + auto AST = TU.build(); + EXPECT_THAT(*AST.getDiagnostics(), testing::IsEmpty()); + } +} + } // namespace } // namespace clangd } // namespace clang