diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp --- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp +++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp @@ -446,6 +446,9 @@ case DiagnosticsEngine::Warning: CheckName = "clang-diagnostic-warning"; break; + case DiagnosticsEngine::Remark: + CheckName = "clang-diagnostic-remark"; + break; default: CheckName = "clang-diagnostic-unknown"; break; @@ -460,7 +463,10 @@ Level = ClangTidyError::Error; LastErrorRelatesToUserCode = true; LastErrorPassesLineFilter = true; + } else if (DiagLevel == DiagnosticsEngine::Remark) { + Level = ClangTidyError::Remark; } + bool IsWarningAsError = DiagLevel == DiagnosticsEngine::Warning && Context.treatAsError(CheckName); Errors.emplace_back(CheckName, Level, Context.getCurrentBuildDirectory(), diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/remarks/A.h b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/remarks/A.h new file mode 100644 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/remarks/A.h @@ -0,0 +1 @@ +// A diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/remarks/module.modulemap b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/remarks/module.modulemap new file mode 100644 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/remarks/module.modulemap @@ -0,0 +1 @@ +module A { header "A.h" } diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/remarks.cpp b/clang-tools-extra/test/clang-tidy/infrastructure/remarks.cpp new file mode 100644 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/infrastructure/remarks.cpp @@ -0,0 +1,15 @@ +// RUN: rm -rf %t +// RUN: cp -r %S/Inputs/remarks %t +// RUN: cp %s %t/t.cpp + +// RUN: clang-tidy -checks='-*,modernize-use-override,clang-diagnostic-module-import' t.cpp -- \ +// RUN: -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache \ +// RUN: -fsyntax-only \ +// RUN: -I%S/Inputs/remarks \ +// RUN: -working-directory=%t \ +// RUN: -Rmodule-build -Rmodule-import t.cpp 2>&1 |\ +// RUN: FileCheck %s -implicit-check-not "remark:" + +#include "A.h" +// CHECK: remark: importing module 'A' from {{.*}} [clang-diagnostic-module-import] + diff --git a/clang/include/clang/Tooling/Core/Diagnostic.h b/clang/include/clang/Tooling/Core/Diagnostic.h --- a/clang/include/clang/Tooling/Core/Diagnostic.h +++ b/clang/include/clang/Tooling/Core/Diagnostic.h @@ -68,7 +68,8 @@ struct Diagnostic { enum Level { Warning = DiagnosticsEngine::Warning, - Error = DiagnosticsEngine::Error + Error = DiagnosticsEngine::Error, + Remark = DiagnosticsEngine::Remark }; Diagnostic() = default; diff --git a/clang/include/clang/Tooling/DiagnosticsYaml.h b/clang/include/clang/Tooling/DiagnosticsYaml.h --- a/clang/include/clang/Tooling/DiagnosticsYaml.h +++ b/clang/include/clang/Tooling/DiagnosticsYaml.h @@ -106,6 +106,7 @@ static void enumeration(IO &IO, clang::tooling::Diagnostic::Level &Value) { IO.enumCase(Value, "Warning", clang::tooling::Diagnostic::Warning); IO.enumCase(Value, "Error", clang::tooling::Diagnostic::Error); + IO.enumCase(Value, "Remark", clang::tooling::Diagnostic::Remark); } }; diff --git a/clang/unittests/Tooling/DiagnosticsYamlTest.cpp b/clang/unittests/Tooling/DiagnosticsYamlTest.cpp --- a/clang/unittests/Tooling/DiagnosticsYamlTest.cpp +++ b/clang/unittests/Tooling/DiagnosticsYamlTest.cpp @@ -47,10 +47,11 @@ const std::string &Message, int FileOffset, const std::string &FilePath, const StringMap &Fix, - const SmallVector &Ranges) { + const SmallVector &Ranges, + Diagnostic::Level DiagnosticLevel) { return Diagnostic(DiagnosticName, makeMessage(Message, FileOffset, FilePath, Fix, Ranges), {}, - Diagnostic::Warning, "path/to/build/directory"); + DiagnosticLevel, "path/to/build/directory"); } static const char *YAMLContent = @@ -102,6 +103,14 @@ " Replacements: []\n" " Level: Warning\n" " BuildDirectory: 'path/to/build/directory'\n" + " - DiagnosticName: 'diagnostic#4'\n" + " DiagnosticMessage:\n" + " Message: 'message #4'\n" + " FilePath: 'path/to/source3.cpp'\n" + " FileOffset: 72\n" + " Replacements: []\n" + " Level: Remark\n" + " BuildDirectory: 'path/to/build/directory'\n" "...\n"; TEST(DiagnosticsYamlTest, serializesDiagnostics) { @@ -112,7 +121,8 @@ {"path/to/source.cpp", Replacements({"path/to/source.cpp", 100, 12, "replacement #1"})}}; TUD.Diagnostics.push_back(makeDiagnostic("diagnostic#1", "message #1", 55, - "path/to/source.cpp", Fix1, {})); + "path/to/source.cpp", Fix1, {}, + Diagnostic::Warning)); StringMap Fix2 = { {"path/to/header.h", @@ -120,15 +130,21 @@ SmallVector Ranges2 = {makeByteRange(10, 10, "path/to/source.cpp")}; TUD.Diagnostics.push_back(makeDiagnostic("diagnostic#2", "message #2", 60, - "path/to/header.h", Fix2, Ranges2)); + "path/to/header.h", Fix2, Ranges2, + Diagnostic::Warning)); TUD.Diagnostics.push_back(makeDiagnostic("diagnostic#3", "message #3", 72, - "path/to/source2.cpp", {}, {})); + "path/to/source2.cpp", {}, {}, + Diagnostic::Warning)); TUD.Diagnostics.back().Notes.push_back( makeMessage("Note1", 88, "path/to/note1.cpp", {}, {})); TUD.Diagnostics.back().Notes.push_back( makeMessage("Note2", 99, "path/to/note2.cpp", {}, {})); + TUD.Diagnostics.push_back(makeDiagnostic("diagnostic#4", "message #4", 72, + "path/to/source3.cpp", {}, {}, + Diagnostic::Remark)); + std::string YamlContent; raw_string_ostream YamlContentStream(YamlContent); @@ -144,7 +160,7 @@ YAML >> TUDActual; ASSERT_FALSE(YAML.error()); - ASSERT_EQ(3u, TUDActual.Diagnostics.size()); + ASSERT_EQ(4u, TUDActual.Diagnostics.size()); EXPECT_EQ("path/to/source.cpp", TUDActual.MainSourceFile); auto getFixes = [](const StringMap &Fix) {