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 @@ -15,6 +15,7 @@ #include "support/Trace.h" #include "clang/AST/DeclTemplate.h" #include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticLex.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" @@ -341,6 +342,16 @@ llvm::IntrusiveRefCntPtr PreambleDiagsEngine = CompilerInstance::createDiagnostics(&CI.getDiagnosticOpts(), &PreambleDiagnostics, false); + // If the preamble doesn't span the whole file, drop the no newline at eof + // warnings. + if (Bounds.Size != ContentsBuffer->getBufferSize()) { + PreambleDiagnostics.setLevelAdjuster( + [&](DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &Info) { + return Info.getID() == diag::warn_no_newline_eof + ? DiagnosticsEngine::Level::Ignored + : 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 @@ -1373,6 +1373,25 @@ EXPECT_THAT(*AST.getDiagnostics(), testing::Contains(Diag(Code.range(), KDiagMsg.str()))); } + +TEST(Preamble, EndsOnNonEmptyLine) { + TestTU TU; + TU.ExtraArgs = {"-Wnewline-eof"}; + + { + TU.Code = "#define FOO\n void bar();\n"; + auto AST = TU.build(); + EXPECT_THAT(*AST.getDiagnostics(), IsEmpty()); + } + { + Annotations Code("#define FOO[[]]"); + TU.Code = Code.code().str(); + auto AST = TU.build(); + EXPECT_THAT( + *AST.getDiagnostics(), + testing::Contains(Diag(Code.range(), "no newline at end of file"))); + } +} } // namespace } // namespace clangd } // namespace clang