diff --git a/clang-tools-extra/clang-tidy/modernize/DeprecatedHeadersCheck.h b/clang-tools-extra/clang-tidy/modernize/DeprecatedHeadersCheck.h --- a/clang-tools-extra/clang-tidy/modernize/DeprecatedHeadersCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/DeprecatedHeadersCheck.h @@ -49,6 +49,7 @@ bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { return LangOpts.CPlusPlus; } + void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; @@ -59,6 +60,7 @@ friend class detail::IncludeModernizePPCallbacks; friend class detail::ExternCRefutationVisitor; std::vector IncludesToBeProcessed; + bool WarnIntoHeaders; }; } // namespace modernize diff --git a/clang-tools-extra/clang-tidy/modernize/DeprecatedHeadersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/DeprecatedHeadersCheck.cpp --- a/clang-tools-extra/clang-tidy/modernize/DeprecatedHeadersCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/DeprecatedHeadersCheck.cpp @@ -24,7 +24,8 @@ class IncludeModernizePPCallbacks : public PPCallbacks { public: explicit IncludeModernizePPCallbacks(DeprecatedHeadersCheck &Check, - LangOptions LangOpts); + LangOptions LangOpts, + const SourceManager &SM); void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, @@ -38,6 +39,7 @@ LangOptions LangOpts; llvm::StringMap CStyledHeaderToCxx; llvm::StringSet<> DeleteHeaders; + const SourceManager &SM; }; class ExternCRefutationVisitor @@ -72,12 +74,17 @@ DeprecatedHeadersCheck::DeprecatedHeadersCheck(StringRef Name, ClangTidyContext *Context) - : ClangTidyCheck(Name, Context) {} + : ClangTidyCheck(Name, Context), + WarnIntoHeaders(Options.get("WarnIntoHeaders", false)) {} + +void DeprecatedHeadersCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "WarnIntoHeaders", WarnIntoHeaders); +} void DeprecatedHeadersCheck::registerPPCallbacks( const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { PP->addPPCallbacks(::std::make_unique( - *this, getLangOpts())); + *this, getLangOpts(), PP->getSourceManager())); } void DeprecatedHeadersCheck::registerMatchers( ast_matchers::MatchFinder *Finder) { @@ -121,8 +128,9 @@ } detail::IncludeModernizePPCallbacks::IncludeModernizePPCallbacks( - DeprecatedHeadersCheck &Check, LangOptions LangOpts) - : Check(Check), LangOpts(LangOpts) { + DeprecatedHeadersCheck &Check, LangOptions LangOpts, + const SourceManager &SM) + : Check(Check), LangOpts(LangOpts), SM(SM) { for (const auto &KeyValue : std::vector>( {{"assert.h", "cassert"}, @@ -168,6 +176,12 @@ bool IsAngled, CharSourceRange FilenameRange, Optional File, StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) { + + // If we don't want to warn for non-main file reports and this is one, skip + // it. + if (!Check.WarnIntoHeaders && !SM.isInMainFile(HashLoc)) + return; + // FIXME: Take care of library symbols from the global namespace. // // Reasonable options for the check: diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -174,6 +174,10 @@ ` involving including C header files from C++ files wrapped by ``extern "C" { ... }`` blocks. Such includes will be ignored by now. + By default now it doesn't warn for including deprecated headers from header + files, since that header file might be used from C source files. By passing + the ``WarnIntoHeaders=true`` option if header files of the project only + included by c++ source files. - Improved :doc:`performance-inefficient-vector-operation ` to work when diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize-deprecated-headers-extern-c.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize-deprecated-headers-extern-c.cpp --- a/clang-tools-extra/test/clang-tidy/checkers/modernize-deprecated-headers-extern-c.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize-deprecated-headers-extern-c.cpp @@ -8,6 +8,13 @@ // RUN: && cp %S/Inputs/modernize-deprecated-headers/mylib.h %t/usr/mylib.h // RUN: %check_clang_tidy -std=c++11 %s modernize-deprecated-headers %t \ +// RUN: -check-suffixes=DEFAULT \ +// RUN: --header-filter='.*' --system-headers \ +// RUN: -- -I %t/usr -isystem %t/sys -isystem %S/Inputs/modernize-deprecated-headers + +// RUN: %check_clang_tidy -std=c++11 %s modernize-deprecated-headers %t \ +// RUN: -check-suffixes=DEFAULT,WARN-INTO-HEADERS \ +// RUN: -config="{CheckOptions: [{key: modernize-deprecated-headers.WarnIntoHeaders, value: 'true'}]}" \ // RUN: --header-filter='.*' --system-headers \ // RUN: -- -I %t/usr -isystem %t/sys -isystem %S/Inputs/modernize-deprecated-headers @@ -18,20 +25,20 @@ extern "C++" { // We should still have the warnings here. #include -// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'stdbool.h' has no effect in C++; consider removing it [modernize-deprecated-headers] +// CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:10: warning: including 'stdbool.h' has no effect in C++; consider removing it [modernize-deprecated-headers] } #include -// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'assert.h'; consider using 'cassert' instead [modernize-deprecated-headers] +// CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'assert.h'; consider using 'cassert' instead [modernize-deprecated-headers] #include -// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'stdbool.h' has no effect in C++; consider removing it [modernize-deprecated-headers] +// CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:10: warning: including 'stdbool.h' has no effect in C++; consider removing it [modernize-deprecated-headers] #include // FIXME: We should have no warning into system headers. -// CHECK-MESSAGES: mysystemlib.h:1:10: warning: inclusion of deprecated C++ header 'assert.h'; consider using 'cassert' instead [modernize-deprecated-headers] +// CHECK-MESSAGES-WARN-INTO-HEADERS: mysystemlib.h:1:10: warning: inclusion of deprecated C++ header 'assert.h'; consider using 'cassert' instead [modernize-deprecated-headers] #include -// CHECK-MESSAGES: mylib.h:1:10: warning: inclusion of deprecated C++ header 'assert.h'; consider using 'cassert' instead [modernize-deprecated-headers] +// CHECK-MESSAGES-WARN-INTO-HEADERS: mylib.h:1:10: warning: inclusion of deprecated C++ header 'assert.h'; consider using 'cassert' instead [modernize-deprecated-headers] namespace wrapping { extern "C" {