Index: clang-tidy/modernize/CMakeLists.txt =================================================================== --- clang-tidy/modernize/CMakeLists.txt +++ clang-tidy/modernize/CMakeLists.txt @@ -1,6 +1,7 @@ set(LLVM_LINK_COMPONENTS support) add_clang_library(clangTidyModernizeModule + DeprecatedHeadersCheck.cpp LoopConvertCheck.cpp LoopConvertUtils.cpp MakeUniqueCheck.cpp Index: clang-tidy/modernize/DeprecatedHeadersCheck.h =================================================================== --- /dev/null +++ clang-tidy/modernize/DeprecatedHeadersCheck.h @@ -0,0 +1,42 @@ +//===--- DeprecatedHeadersCheck.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_C_HEADERS_TO_CXX_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_C_HEADERS_TO_CXX_H + +#include "../ClangTidy.h" + +namespace clang { +namespace tidy { +namespace modernize { + +/// This check replaces deprecated C library headers with their C++ STL +/// alternatives. +/// +/// Before: +/// #include +/// After: +/// #include +/// +/// Example: => +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/modernize-deprecated-headers.html +class DeprecatedHeadersCheck : public ClangTidyCheck { +public: + DeprecatedHeadersCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerPPCallbacks(CompilerInstance &Compiler) override; +}; + +} // namespace modernize +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_C_HEADERS_TO_CXX_H Index: clang-tidy/modernize/DeprecatedHeadersCheck.cpp =================================================================== --- /dev/null +++ clang-tidy/modernize/DeprecatedHeadersCheck.cpp @@ -0,0 +1,101 @@ +//===--- DeprecatedHeadersCheck.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 "DeprecatedHeadersCheck.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Lex/PPCallbacks.h" +#include "clang/Lex/Preprocessor.h" + +#include +#include +#include + +namespace clang { +namespace tidy { +namespace modernize { + +namespace { +class IncludeModernizePPCallbacks : public PPCallbacks { +public: + explicit IncludeModernizePPCallbacks(ClangTidyCheck &Check, + LangOptions LangOpts); + + void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, + StringRef FileName, bool IsAngled, + CharSourceRange FilenameRange, const FileEntry *File, + StringRef SearchPath, StringRef RelativePath, + const Module *Imported) override; + +private: + std::map CStyledHeaderToCxx; + + ClangTidyCheck &Check; + LangOptions LangOpts; +}; +} // namespace + +void DeprecatedHeadersCheck::registerPPCallbacks(CompilerInstance &Compiler) { + if (this->getLangOpts().CPlusPlus) { + Compiler.getPreprocessor().addPPCallbacks( + ::llvm::make_unique(*this, + this->getLangOpts())); + } +} + +IncludeModernizePPCallbacks::IncludeModernizePPCallbacks(ClangTidyCheck &Check, + LangOptions LangOpts) + : Check(Check), LangOpts(LangOpts) { + CStyledHeaderToCxx["assert.h"] = "cassert"; + CStyledHeaderToCxx["float.h"] = "cfloat"; + CStyledHeaderToCxx["math.h"] = "cmath"; + CStyledHeaderToCxx["stddef.h"] = "cstddef"; + CStyledHeaderToCxx["setjmp.h"] = "csetjmp"; + CStyledHeaderToCxx["stdio.h"] = "cstdio"; + CStyledHeaderToCxx["time.h"] = "ctime"; + CStyledHeaderToCxx["ctype.h"] = "cctype"; + CStyledHeaderToCxx["iso646.h"] = "ciso646"; + CStyledHeaderToCxx["signal.h"] = "csignal"; + CStyledHeaderToCxx["errno.h"] = "cerrno"; + CStyledHeaderToCxx["limits.h"] = "climits"; + CStyledHeaderToCxx["stdarg.h"] = "cstdarg"; + CStyledHeaderToCxx["stdlib.h"] = "cstdlib"; + CStyledHeaderToCxx["wchar.h"] = "cwchar"; + CStyledHeaderToCxx["locale.h"] = "clocale"; + CStyledHeaderToCxx["string.h"] = "cstring"; + CStyledHeaderToCxx["wctype.h"] = "cwctype"; + CStyledHeaderToCxx["complex.h"] = "ccomplex"; + CStyledHeaderToCxx["stdint.h"] = "cstdint"; + CStyledHeaderToCxx["inttypes.h"] = "cinttypes"; + + // C++ 11 headers + if (LangOpts.CPlusPlus11) { + CStyledHeaderToCxx["stdbool.h"] = "cstdbool"; + CStyledHeaderToCxx["fenv.h"] = "cfenv"; + CStyledHeaderToCxx["tgmath.h"] = "ctgmath"; + CStyledHeaderToCxx["uchar.h"] = "cuchar"; + CStyledHeaderToCxx["stdalign.h"] = "cstdalign"; + } +} + +void IncludeModernizePPCallbacks::InclusionDirective( + SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, + bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File, + StringRef SearchPath, StringRef RelativePath, const Module *Imported) { + if (CStyledHeaderToCxx.count(std::string(FileName)) != 0) { + std::string Replacement = + "<" + CStyledHeaderToCxx[std::string(FileName)] + ">"; + Check.diag(FilenameRange.getBegin(), "including deprecated C++ header") + << FixItHint::CreateReplacement(FilenameRange.getAsRange(), + Replacement); + } +} + +} // namespace modernize +} // namespace tidy +} // namespace clang Index: clang-tidy/modernize/ModernizeTidyModule.cpp =================================================================== --- clang-tidy/modernize/ModernizeTidyModule.cpp +++ clang-tidy/modernize/ModernizeTidyModule.cpp @@ -10,6 +10,7 @@ #include "../ClangTidy.h" #include "../ClangTidyModule.h" #include "../ClangTidyModuleRegistry.h" +#include "DeprecatedHeadersCheck.h" #include "LoopConvertCheck.h" #include "MakeUniqueCheck.h" #include "PassByValueCheck.h" @@ -30,6 +31,8 @@ class ModernizeModule : public ClangTidyModule { public: void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { + CheckFactories.registerCheck( + "modernize-deprecated-headers"); CheckFactories.registerCheck("modernize-loop-convert"); CheckFactories.registerCheck("modernize-make-unique"); CheckFactories.registerCheck("modernize-pass-by-value"); Index: docs/clang-tidy/checks/list.rst =================================================================== --- docs/clang-tidy/checks/list.rst +++ docs/clang-tidy/checks/list.rst @@ -72,6 +72,7 @@ misc-unused-parameters misc-unused-raii misc-virtual-near-miss + modernize-deprecated-headers modernize-loop-convert modernize-make-unique modernize-pass-by-value Index: docs/clang-tidy/checks/modernize-deprecated-headers.rst =================================================================== --- /dev/null +++ docs/clang-tidy/checks/modernize-deprecated-headers.rst @@ -0,0 +1,66 @@ +.. title:: clang-tidy - modernize-deprecated-headers + +modernize-deprecated-headers +========================== + +This check replaces C standard library headers with their C++ alternatives. + + Annex D (normative) + Compatibility features [depr] + + D.5 C standard library headers [depr.c.headers] + 1 For compatibility with the C standard library and the C Unicode TR, the C++ + standard library provides the 26 C headers, as shown in Table 155 + + ... + + Every C header, each of which has a name of the form name.h, behaves as if + each name placed in the standard library namespace by the corresponding cname + header is placed within the global namespace scope. It is unspecified whether + these names are first declared or defined within namespace scope (3.3.6) of + the namespace std and are then injected into the global namespace scope by + explicit using-declarations (7.3.3). + + [ Example: The header assuredly provides its declarations and + definitions within the namespace std. It may also provide these names within + the global namespace. The header assuredly provides the same + declarations and definitions within the global namespace, much as in the C + Standard. It may also provide these names within the namespace std. + —end example ] + + -- C++ 14 Standard + +The following headers were deprecated before C++ 11: + +* `` +* `` +* `` +* `` +* `` +* `` +* `` +* `` +* `` +* `` +* `` +* `` +* `` +* `` +* `` +* `` +* `` +* `` +* `` +* `` +* `` + +The following headers were deprecated in C++ 11: + +* `` +* `` +* `` +* `` +* `` + +If the specified standard is older than C++11 the check will only replace +headers from the first list, otherwise -- every header that appeared before. Index: test/clang-tidy/modernize-deprecated-headers-cxx03.cpp =================================================================== --- /dev/null +++ test/clang-tidy/modernize-deprecated-headers-cxx03.cpp @@ -0,0 +1,103 @@ +// RUN: %check_clang_tidy %s modernize-deprecated-headers %t -- -- -std=c++03 -isystem %S/Inputs/Headers + +#include "assert.h" +#include "float.h" +#include "math.h" +#include "stddef.h" +#include "setjmp.h" +#include "stdio.h" +#include "time.h" +#include "ctype.h" +#include "iso646.h" +#include "signal.h" +#include "errno.h" +#include "limits.h" +#include "stdarg.h" +#include "stdlib.h" +#include "wchar.h" +#include "locale.h" +#include "string.h" +#include "wctype.h" +#include "complex.h" +#include "stdint.h" +#include "inttypes.h" + +// C++11 deprecated headers +#include "stdalign.h" +#include "stdbool.h" +#include "fenv.h" +#include "tgmath.h" +#include "uchar.h" + +// CHECK-FIXES: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// C++11 deprecated headers +#include +#include +#include +#include +#include + +// CHECK-FIXES: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include Index: test/clang-tidy/modernize-deprecated-headers-cxx11.cpp =================================================================== --- /dev/null +++ test/clang-tidy/modernize-deprecated-headers-cxx11.cpp @@ -0,0 +1,117 @@ +// RUN: %check_clang_tidy %s modernize-deprecated-headers %t -- -- -std=c++11 -isystem %S/Inputs/Headers + +#include "assert.h" +#include "float.h" +#include "math.h" +#include "stddef.h" +#include "setjmp.h" +#include "stdio.h" +#include "time.h" +#include "ctype.h" +#include "iso646.h" +#include "signal.h" +#include "errno.h" +#include "limits.h" +#include "stdarg.h" +#include "stdlib.h" +#include "wchar.h" +#include "locale.h" +#include "string.h" +#include "wctype.h" +#include "complex.h" +#include "stdint.h" +#include "inttypes.h" + +// C++11 deprecated headers +#include "stdalign.h" +#include "stdbool.h" +#include "fenv.h" +#include "tgmath.h" +#include "uchar.h" + +// CHECK-FIXES: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include + +// C++11 headers +// CHECK-FIXES: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// C++11 deprecated headers +#include +#include +#include +#include +#include + +// CHECK-FIXES: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include + +// C++11 headers +// CHECK-FIXES: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include +// CHECK-FIXES-NEXT: #include