Index: clang-tidy/modernize/AvoidFunctionalCheck.h =================================================================== --- clang-tidy/modernize/AvoidFunctionalCheck.h +++ clang-tidy/modernize/AvoidFunctionalCheck.h @@ -0,0 +1,35 @@ +//===--- AvoidFunctionalCheck.h - clang-tidy---------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_AVOIDFUNCTIONALCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_AVOIDFUNCTIONALCHECK_H + +#include "../ClangTidy.h" + +namespace clang { +namespace tidy { +namespace modernize { + +/// Check for several deprecated types and classes from header. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/modernize-avoid-functional.html +class AvoidFunctionalCheck : public ClangTidyCheck { +public: + AvoidFunctionalCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; +}; + +} // namespace modernize +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_AVOIDFUNCTIONALCHECK_H Index: clang-tidy/modernize/AvoidFunctionalCheck.cpp =================================================================== --- clang-tidy/modernize/AvoidFunctionalCheck.cpp +++ clang-tidy/modernize/AvoidFunctionalCheck.cpp @@ -0,0 +1,59 @@ +//===--- AvoidFunctionalCheck.cpp - clang-tidy-----------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "AvoidFunctionalCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace modernize { + +void AvoidFunctionalCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher( + cxxRecordDecl(allOf(isDerivedFrom(classTemplateSpecializationDecl( + hasAnyName("::std::binary_function", + "::std::unary_function")) + .bind("base")), + anyOf(isClass(), ast_matchers::isStruct()), + ast_matchers::isDefinition())) + .bind("un_or_binary_derived"), + this); + Finder->addMatcher(callExpr(callee(functionDecl(hasName("std::ptr_fun")))) + .bind("ptr_fun_call"), + this); + Finder->addMatcher(callExpr(callee(functionDecl(hasName("std::mem_fun")))) + .bind("mem_fun_call"), + this); +} + +void AvoidFunctionalCheck::check(const MatchFinder::MatchResult &Result) { + const StringRef Message = "%0 is deprecated in C++11 and removed in C++17"; + if (const auto *const Decl = + Result.Nodes.getNodeAs("un_or_binary_derived")) { + const auto *SpecDecl = + Result.Nodes.getNodeAs("base"); + for (CXXBaseSpecifier Base : Decl->bases()) { + if (SpecDecl == Base.getType()->getAsCXXRecordDecl()) + diag(Base.getLocStart(), Message) << SpecDecl->getSpecializedTemplate(); + } + } else if (const auto *const Call = + Result.Nodes.getNodeAs("ptr_fun_call")) { + diag(Call->getLocStart(), Message) << "'std::ptr_fun'"; + } else if (const auto *const Call = + Result.Nodes.getNodeAs("mem_fun_call")) { + diag(Call->getLocStart(), Message) << "'std::mem_fun'"; + } +} + +} // namespace modernize +} // namespace tidy +} // namespace clang Index: clang-tidy/modernize/CMakeLists.txt =================================================================== --- clang-tidy/modernize/CMakeLists.txt +++ clang-tidy/modernize/CMakeLists.txt @@ -2,6 +2,7 @@ add_clang_library(clangTidyModernizeModule AvoidBindCheck.cpp + AvoidFunctionalCheck.cpp DeprecatedHeadersCheck.cpp LoopConvertCheck.cpp LoopConvertUtils.cpp Index: clang-tidy/modernize/ModernizeTidyModule.cpp =================================================================== --- clang-tidy/modernize/ModernizeTidyModule.cpp +++ clang-tidy/modernize/ModernizeTidyModule.cpp @@ -11,6 +11,7 @@ #include "../ClangTidyModule.h" #include "../ClangTidyModuleRegistry.h" #include "AvoidBindCheck.h" +#include "AvoidFunctionalCheck.h" #include "DeprecatedHeadersCheck.h" #include "LoopConvertCheck.h" #include "MakeSharedCheck.h" @@ -45,6 +46,8 @@ public: void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { CheckFactories.registerCheck("modernize-avoid-bind"); + CheckFactories.registerCheck( + "modernize-avoid-functional"); CheckFactories.registerCheck( "modernize-deprecated-headers"); CheckFactories.registerCheck("modernize-loop-convert"); Index: docs/ReleaseNotes.rst =================================================================== --- docs/ReleaseNotes.rst +++ docs/ReleaseNotes.rst @@ -89,6 +89,12 @@ using decltype specifiers and lambda with otherwise unutterable return types. +- New `modernize-avoid-functional + `_ check + + Warns if types, classes and functions from '' header which are + deprecated in C++11 and removed in C++17 are used. + - New alias `hicpp-avoid-goto `_ to `cppcoreguidelines-avoid-goto `_ Index: docs/clang-tidy/checks/list.rst =================================================================== --- docs/clang-tidy/checks/list.rst +++ docs/clang-tidy/checks/list.rst @@ -154,6 +154,7 @@ misc-unused-raii misc-unused-using-decls modernize-avoid-bind + modernize-avoid-functional modernize-deprecated-headers modernize-loop-convert modernize-make-shared Index: docs/clang-tidy/checks/modernize-avoid-functional.rst =================================================================== --- docs/clang-tidy/checks/modernize-avoid-functional.rst +++ docs/clang-tidy/checks/modernize-avoid-functional.rst @@ -0,0 +1,14 @@ +.. title:: clang-tidy - modernize-avoid-functional + +modernize-avoid-functional +========================== + +Warns if types, classes and functions from '' header which are + deprecated in C++11 and removed in C++17 are used. +In particular, this check warns if one of the following deprecated objects is +used: + +- 'std::unary_function' +- 'std::binary_function' +- 'std::ptr_fun' +- 'std::mem_fun' Index: test/clang-tidy/modernize-avoid-functional.cpp =================================================================== --- test/clang-tidy/modernize-avoid-functional.cpp +++ test/clang-tidy/modernize-avoid-functional.cpp @@ -0,0 +1,63 @@ +// RUN: %check_clang_tidy %s modernize-avoid-functional %t + +namespace std { + +template +class binary_function {}; + +template +class unary_function {}; + +template +class pointer_to_unary_function + : public std::unary_function { // NOLINT +}; + +template +pointer_to_unary_function ptr_fun(Result (*f)(Arg)) { + pointer_to_unary_function Nothing; + return Nothing; +} + +template +class mem_fun_t {}; + +template +mem_fun_t mem_fun(Res (T::*f)()) {} + +} // namespace std + +// CHECK-MESSAGES: [[@LINE+1]]:25: warning: 'binary_function' is deprecated in C++11 and removed in C++17 [modernize-avoid-functional] +class BinaryTestClass : public std::binary_function { + public: + BinaryTestClass(); +}; + +// CHECK-MESSAGES: [[@LINE+1]]:24: warning: 'unary_function' is deprecated in C++11 and removed in C++17 [modernize-avoid-functional] +class UnaryTestClass : public std::unary_function { + public: + UnaryTestClass(); +}; + +class TestClass { + public: + int test() { return 1; } +}; + +// CHECK-MESSAGES: [[@LINE+2]]:31: warning: 'unary_function' is deprecated in C++11 and removed in C++17 [modernize-avoid-functional] +class AnotherUnaryTestClass : public TestClass, + public std::unary_function { + public: + AnotherUnaryTestClass(); +}; + + +int simpleFunc(int X) { return X + 1; }; + +void foo(void) { +// CHECK-MESSAGES: [[@LINE+1]]:3: warning: 'std::ptr_fun' is deprecated in C++11 and removed in C++17 [modernize-avoid-functional] + std::ptr_fun(simpleFunc); + +// CHECK-MESSAGES: [[@LINE+1]]:3: warning: 'std::mem_fun' is deprecated in C++11 and removed in C++17 [modernize-avoid-functional] + std::mem_fun(&TestClass::test); +}