clang-tools  4.0.0
DeprecatedHeadersCheck.cpp
Go to the documentation of this file.
1 //===--- DeprecatedHeadersCheck.cpp - clang-tidy---------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "DeprecatedHeadersCheck.h"
11 #include "clang/Frontend/CompilerInstance.h"
12 #include "clang/Lex/PPCallbacks.h"
13 #include "clang/Lex/Preprocessor.h"
14 #include "llvm/ADT/StringMap.h"
15 #include "llvm/ADT/StringSet.h"
16 
17 #include <vector>
18 
19 namespace clang {
20 namespace tidy {
21 namespace modernize {
22 
23 namespace {
24 class IncludeModernizePPCallbacks : public PPCallbacks {
25 public:
26  explicit IncludeModernizePPCallbacks(ClangTidyCheck &Check,
27  LangOptions LangOpts);
28 
29  void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
30  StringRef FileName, bool IsAngled,
31  CharSourceRange FilenameRange, const FileEntry *File,
32  StringRef SearchPath, StringRef RelativePath,
33  const Module *Imported) override;
34 
35 private:
36  ClangTidyCheck &Check;
37  LangOptions LangOpts;
38  llvm::StringMap<std::string> CStyledHeaderToCxx;
39  llvm::StringSet<> DeleteHeaders;
40 };
41 } // namespace
42 
43 void DeprecatedHeadersCheck::registerPPCallbacks(CompilerInstance &Compiler) {
44  if (this->getLangOpts().CPlusPlus) {
45  Compiler.getPreprocessor().addPPCallbacks(
46  ::llvm::make_unique<IncludeModernizePPCallbacks>(*this,
47  this->getLangOpts()));
48  }
49 }
50 
51 IncludeModernizePPCallbacks::IncludeModernizePPCallbacks(ClangTidyCheck &Check,
52  LangOptions LangOpts)
53  : Check(Check), LangOpts(LangOpts) {
54  for (const auto &KeyValue :
55  std::vector<std::pair<llvm::StringRef, std::string>>(
56  {{"assert.h", "cassert"},
57  {"complex.h", "complex"},
58  {"ctype.h", "cctype"},
59  {"errno.h", "cerrno"},
60  {"float.h", "cfloat"},
61  {"limits.h", "climits"},
62  {"locale.h", "clocale"},
63  {"math.h", "cmath"},
64  {"setjmp.h", "csetjmp"},
65  {"signal.h", "csignal"},
66  {"stdarg.h", "cstdarg"},
67  {"stddef.h", "cstddef"},
68  {"stdio.h", "cstdio"},
69  {"stdlib.h", "cstdlib"},
70  {"string.h", "cstring"},
71  {"time.h", "ctime"},
72  {"wchar.h", "cwchar"},
73  {"wctype.h", "cwctype"}})) {
74  CStyledHeaderToCxx.insert(KeyValue);
75  }
76  // Add C++ 11 headers.
77  if (LangOpts.CPlusPlus11) {
78  for (const auto &KeyValue :
79  std::vector<std::pair<llvm::StringRef, std::string>>(
80  {{"fenv.h", "cfenv"},
81  {"stdint.h", "cstdint"},
82  {"inttypes.h", "cinttypes"},
83  {"tgmath.h", "ctgmath"},
84  {"uchar.h", "cuchar"}})) {
85  CStyledHeaderToCxx.insert(KeyValue);
86  }
87  }
88  for (const auto &Key :
89  std::vector<std::string>({"stdalign.h", "stdbool.h", "iso646.h"})) {
90  DeleteHeaders.insert(Key);
91  }
92 }
93 
94 void IncludeModernizePPCallbacks::InclusionDirective(
95  SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName,
96  bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File,
97  StringRef SearchPath, StringRef RelativePath, const Module *Imported) {
98  // FIXME: Take care of library symbols from the global namespace.
99  //
100  // Reasonable options for the check:
101  //
102  // 1. Insert std prefix for every such symbol occurrence.
103  // 2. Insert `using namespace std;` to the beginning of TU.
104  // 3. Do nothing and let the user deal with the migration himself.
105  if (CStyledHeaderToCxx.count(FileName) != 0) {
106  std::string Replacement =
107  (llvm::Twine("<") + CStyledHeaderToCxx[FileName] + ">").str();
108  Check.diag(FilenameRange.getBegin(), "inclusion of deprecated C++ header "
109  "'%0'; consider using '%1' instead")
110  << FileName << CStyledHeaderToCxx[FileName]
111  << FixItHint::CreateReplacement(FilenameRange.getAsRange(),
112  Replacement);
113  } else if (DeleteHeaders.count(FileName) != 0) {
114  Check.diag(FilenameRange.getBegin(),
115  "including '%0' has no effect in C++; consider removing it")
116  << FileName << FixItHint::CreateRemoval(
117  SourceRange(HashLoc, FilenameRange.getEnd()));
118  }
119 }
120 
121 } // namespace modernize
122 } // namespace tidy
123 } // namespace clang
LangOptions getLangOpts() const
Returns the language options from the context.
Definition: ClangTidy.h:187
HeaderHandle File
llvm::StringSet DeleteHeaders
Base class for all clang-tidy checks.
Definition: ClangTidy.h:127
LangOptions LangOpts
bool IsAngled
true if this was an include with angle brackets
DiagnosticBuilder diag(SourceLocation Loc, StringRef Description, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Add a diagnostic with the check's name.
Definition: ClangTidy.cpp:403
ClangTidyCheck & Check
llvm::StringMap< std::string > CStyledHeaderToCxx
void registerPPCallbacks(CompilerInstance &Compiler) override
Override this to register PPCallbacks with Compiler.