Index: clangd/ClangdServer.cpp =================================================================== --- clangd/ClangdServer.cpp +++ clangd/ClangdServer.cpp @@ -534,6 +534,7 @@ // Inject the resource dir. // FIXME: Don't overwrite it if it's already there. C->CommandLine.push_back("-resource-dir=" + ResourceDir); + C->CommandLine.push_back("-Wdeprecated-declarations"); return std::move(*C); } Index: clangd/Diagnostics.cpp =================================================================== --- clangd/Diagnostics.cpp +++ clangd/Diagnostics.cpp @@ -292,10 +292,11 @@ D.Message = Message.str(); D.InsideMainFile = InsideMainFile; D.File = Info.getSourceManager().getFilename(Info.getLocation()); - D.Severity = DiagLevel; D.Category = DiagnosticIDs::getCategoryNameFromID( DiagnosticIDs::getCategoryNumberForDiag(Info.getID())) .str(); + D.Severity = + D.Category == "Deprecations" ? DiagnosticsEngine::Note : DiagLevel; return D; }; Index: unittests/clangd/ClangdUnitTests.cpp =================================================================== --- unittests/clangd/ClangdUnitTests.cpp +++ unittests/clangd/ClangdUnitTests.cpp @@ -38,6 +38,13 @@ return arg.Range == Range && arg.Message == Message; } +MATCHER_P3(Diag, Range, Message, Severity, + "Diag at " + llvm::to_string(Range) + " = [" + Message + + "] with Severity:" + llvm::to_string(Severity)) { + return arg.Range == Range && arg.Message == Message && + arg.Severity == Severity; +} + MATCHER_P3(Fix, Range, Replacement, Message, "Fix " + llvm::to_string(Range) + " => " + testing::PrintToString(Replacement) + " = [" + Message + "]") { @@ -220,6 +227,46 @@ } } +TEST(DiagnosticsTest, DiagnosticDeprecated) { + Annotations Test(R"cpp( + void foo() __attribute__(($foodeprecation[[deprecated]])); + class A { + public: + int x __attribute__(($xdeprecation[[deprecated]])); + }; + int main() { + $foo[[foo]](); + return A().$x[[x]]; + } + )cpp"); + EXPECT_THAT( + TestTU::withCode(Test.code()).build().getDiagnostics(), + ElementsAre( + AllOf(Diag(Test.range("foo"), "'foo' is deprecated", + DiagnosticsEngine::Note), + WithNote( + Diag(Test.range("foodeprecation"), + "'foo' has been explicitly marked deprecated here"))), + AllOf(Diag(Test.range("x"), "'x' is deprecated", + DiagnosticsEngine::Note), + WithNote( + Diag(Test.range("xdeprecation"), + "'x' has been explicitly marked deprecated here"))))); +} + +TEST(DiagnosticsTest, DiagnosticDeprecatedWithFix) { + Annotations Test(R"cpp( + void bar(); + void foo() __attribute__((deprecated("", "bar"))); + int main() { + $deprecated[[foo]](); + } + )cpp"); + EXPECT_THAT(TestTU::withCode(Test.code()).build().getDiagnostics(), + ElementsAre(WithFix(Fix(Test.range("deprecated"), "bar", + "change 'foo' to 'bar'")))); +} + } // namespace } // namespace clangd } // namespace clang