diff --git a/clang-tools-extra/clangd/Preamble.cpp b/clang-tools-extra/clangd/Preamble.cpp --- a/clang-tools-extra/clangd/Preamble.cpp +++ b/clang-tools-extra/clangd/Preamble.cpp @@ -8,6 +8,7 @@ #include "Preamble.h" #include "Compiler.h" +#include "Config.h" #include "Headers.h" #include "SourceCode.h" #include "support/Logger.h" @@ -340,20 +341,24 @@ llvm::IntrusiveRefCntPtr PreambleDiagsEngine = CompilerInstance::createDiagnostics(&CI.getDiagnosticOpts(), &PreambleDiagnostics, false); - PreambleDiagnostics.setLevelAdjuster( - [&](DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &Info) { - switch (Info.getID()) { - case diag::warn_no_newline_eof: - case diag::warn_cxx98_compat_no_newline_eof: - case diag::ext_no_newline_eof: - // If the preamble doesn't span the whole file, drop the no newline at - // eof warnings. - return Bounds.Size != ContentsBuffer->getBufferSize() - ? DiagnosticsEngine::Level::Ignored - : DiagLevel; - } - return DiagLevel; - }); + const Config &Cfg = Config::current(); + PreambleDiagnostics.setLevelAdjuster([&](DiagnosticsEngine::Level DiagLevel, + const clang::Diagnostic &Info) { + if (Cfg.Diagnostics.SuppressAll || + isBuiltinDiagnosticSuppressed(Info.getID(), Cfg.Diagnostics.Suppress)) + return DiagnosticsEngine::Ignored; + switch (Info.getID()) { + case diag::warn_no_newline_eof: + case diag::warn_cxx98_compat_no_newline_eof: + case diag::ext_no_newline_eof: + // If the preamble doesn't span the whole file, drop the no newline at + // eof warnings. + return Bounds.Size != ContentsBuffer->getBufferSize() + ? DiagnosticsEngine::Level::Ignored + : DiagLevel; + } + return DiagLevel; + }); // Skip function bodies when building the preamble to speed up building // the preamble and make it smaller. 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 @@ -449,6 +449,21 @@ "use of undeclared identifier 'unknown'"))); } +TEST(DiagnosticTest, RespectsDiagnosticConfigInHeader) { + Annotations Header(R"cpp( + int x = "42"; // error-ok + )cpp"); + Annotations Main(R"cpp( + #include "header.hpp" + )cpp"); + auto TU = TestTU::withCode(Main.code()); + TU.AdditionalFiles["header.hpp"] = std::string(Header.code()); + Config Cfg; + Cfg.Diagnostics.Suppress.insert("init_conversion_failed"); + WithContextValue WithCfg(Config::Key, std::move(Cfg)); + EXPECT_THAT(*TU.build().getDiagnostics(), IsEmpty()); +} + TEST(DiagnosticTest, ClangTidySuppressionComment) { Annotations Main(R"cpp( int main() {