diff --git a/src/plugins/clangcodemodel/clangdiagnosticfilter.cpp b/src/plugins/clangcodemodel/clangdiagnosticfilter.cpp index 133b6915258..ecd1edf0e5c 100644 --- a/src/plugins/clangcodemodel/clangdiagnosticfilter.cpp +++ b/src/plugins/clangcodemodel/clangdiagnosticfilter.cpp @@ -25,6 +25,10 @@ #include "clangdiagnosticfilter.h" +#include + +#include + namespace { bool isWarningOrNote(ClangBackEnd::DiagnosticSeverity severity) @@ -41,6 +45,17 @@ bool isWarningOrNote(ClangBackEnd::DiagnosticSeverity severity) Q_UNREACHABLE(); } +bool isBlackListedDiagnostic(const ClangBackEnd::DiagnosticContainer &diagnostic, + bool isHeaderFile) +{ + static const Utf8StringVector blackList { + Utf8StringLiteral("warning: #pragma once in main file"), + Utf8StringLiteral("warning: #include_next in primary source file") + }; + + return isHeaderFile && blackList.contains(diagnostic.text()); +} + template QVector filterDiagnostics(const QVector &diagnostics, @@ -76,8 +91,13 @@ namespace Internal { void ClangDiagnosticFilter::filterDocumentRelatedWarnings( const QVector &diagnostics) { - const auto isLocalWarning = [this] (const ClangBackEnd::DiagnosticContainer &diagnostic) { + using namespace CppTools; + const bool isHeaderFile = ProjectFile::isHeader(ProjectFile::classify(m_filePath)); + + const auto isLocalWarning = [this, isHeaderFile] + (const ClangBackEnd::DiagnosticContainer &diagnostic) { return isWarningOrNote(diagnostic.severity()) + && !isBlackListedDiagnostic(diagnostic, isHeaderFile) && diagnostic.location().filePath() == m_filePath; }; diff --git a/src/plugins/cpptools/cpptoolsunittestfiles.pri b/src/plugins/cpptools/cpptoolsunittestfiles.pri index 2d011718e66..be0b6f7bdec 100644 --- a/src/plugins/cpptools/cpptoolsunittestfiles.pri +++ b/src/plugins/cpptools/cpptoolsunittestfiles.pri @@ -4,6 +4,10 @@ contains(CONFIG, dll) { DEFINES += CPPTOOLS_STATIC_LIBRARY } -HEADERS += $$PWD/senddocumenttracker.h +HEADERS += \ + $$PWD/cppprojectfile.h \ + $$PWD/senddocumenttracker.h \ -SOURCES += $$PWD/senddocumenttracker.cpp +SOURCES += \ + $$PWD/cppprojectfile.cpp \ + $$PWD/senddocumenttracker.cpp diff --git a/tests/unit/unittest/clangdiagnosticfiltertest.cpp b/tests/unit/unittest/clangdiagnosticfiltertest.cpp index 99be0359fe1..31b7588aa1b 100644 --- a/tests/unit/unittest/clangdiagnosticfiltertest.cpp +++ b/tests/unit/unittest/clangdiagnosticfiltertest.cpp @@ -64,6 +64,7 @@ DiagnosticContainer createDiagnostic(const QString &text, ); } +const QString mainFileHeaderPath = QString::fromUtf8(TESTDATA_DIR "/someHeader.h"); const QString mainFilePath = QString::fromUtf8(TESTDATA_DIR "/diagnostic_erroneous_source.cpp"); const QString includedFilePath = QString::fromUtf8(TESTDATA_DIR "/diagnostic_erroneous_header.cpp"); @@ -91,6 +92,22 @@ DiagnosticContainer warningFromMainFile() mainFilePath); } +DiagnosticContainer pragmaOnceWarningInHeader() +{ + return createDiagnostic( + QStringLiteral("warning: #pragma once in main file"), + ClangBackEnd::DiagnosticSeverity::Warning, + mainFileHeaderPath); +} + +DiagnosticContainer includeNextInPrimarySourceFileWarningInHeader() +{ + return createDiagnostic( + QStringLiteral("warning: #include_next in primary source file"), + ClangBackEnd::DiagnosticSeverity::Warning, + mainFileHeaderPath); +} + DiagnosticContainer errorFromMainFile() { return createDiagnostic( @@ -193,6 +210,16 @@ TEST_F(ClangDiagnosticFilter, WarningsAreEmptyAfterTaking) ASSERT_TRUE(clangDiagnosticFilter.takeWarnings().isEmpty()); } +TEST_F(ClangDiagnosticFilter, IgnoreCertainWarningsInHeaderFiles) +{ + ClangCodeModel::Internal::ClangDiagnosticFilter myClangDiagnosticFilter{mainFileHeaderPath}; + + myClangDiagnosticFilter.filter({pragmaOnceWarningInHeader(), + includeNextInPrimarySourceFileWarningInHeader()}); + + ASSERT_TRUE(myClangDiagnosticFilter.takeWarnings().isEmpty()); +} + TEST_F(ClangDiagnosticFilter, ErrorsAreEmptyAfterTaking) { clangDiagnosticFilter.filter({errorFromMainFile()});