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