clang-tools  3.9.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 
16 #include <vector>
17 
18 namespace clang {
19 namespace tidy {
20 namespace modernize {
21 
22 namespace {
23 class IncludeModernizePPCallbacks : public PPCallbacks {
24 public:
25  explicit IncludeModernizePPCallbacks(ClangTidyCheck &Check,
26  LangOptions LangOpts);
27 
28  void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
29  StringRef FileName, bool IsAngled,
30  CharSourceRange FilenameRange, const FileEntry *File,
31  StringRef SearchPath, StringRef RelativePath,
32  const Module *Imported) override;
33 
34 private:
35  ClangTidyCheck &Check;
36  LangOptions LangOpts;
37  llvm::StringMap<std::string> CStyledHeaderToCxx;
38 };
39 } // namespace
40 
41 void DeprecatedHeadersCheck::registerPPCallbacks(CompilerInstance &Compiler) {
42  if (this->getLangOpts().CPlusPlus) {
43  Compiler.getPreprocessor().addPPCallbacks(
44  ::llvm::make_unique<IncludeModernizePPCallbacks>(*this,
45  this->getLangOpts()));
46  }
47 }
48 
49 IncludeModernizePPCallbacks::IncludeModernizePPCallbacks(ClangTidyCheck &Check,
50  LangOptions LangOpts)
51  : Check(Check), LangOpts(LangOpts) {
52  for (const auto &KeyValue :
53  std::vector<std::pair<llvm::StringRef, std::string>>(
54  {{"assert.h", "cassert"}, {"complex.h", "ccomplex"},
55  {"ctype.h", "cctype"}, {"errno.h", "cerrno"},
56  {"float.h", "cfloat"}, {"inttypes.h", "cinttypes"},
57  {"iso646.h", "ciso646"}, {"limits.h", "climits"},
58  {"locale.h", "clocale"}, {"math.h", "cmath"},
59  {"setjmp.h", "csetjmp"}, {"signal.h", "csignal"},
60  {"stdarg.h", "cstdarg"}, {"stddef.h", "cstddef"},
61  {"stdint.h", "cstdint"}, {"stdio.h", "cstdio"},
62  {"stdlib.h", "cstdlib"}, {"string.h", "cstring"},
63  {"time.h", "ctime"}, {"wchar.h", "cwchar"},
64  {"wctype.h", "cwctype"}})) {
65  CStyledHeaderToCxx.insert(KeyValue);
66  }
67  // Add C++ 11 headers.
68  if (LangOpts.CPlusPlus11) {
69  for (const auto &KeyValue :
70  std::vector<std::pair<llvm::StringRef, std::string>>(
71  {{"fenv.h", "cfenv"},
72  {"stdalign.h", "cstdalign"},
73  {"stdbool.h", "cstdbool"},
74  {"tgmath.h", "ctgmath"},
75  {"uchar.h", "cuchar"}})) {
76  CStyledHeaderToCxx.insert(KeyValue);
77  }
78  }
79 }
80 
81 void IncludeModernizePPCallbacks::InclusionDirective(
82  SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName,
83  bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File,
84  StringRef SearchPath, StringRef RelativePath, const Module *Imported) {
85  // FIXME: Take care of library symbols from the global namespace.
86  //
87  // Reasonable options for the check:
88  //
89  // 1. Insert std prefix for every such symbol occurance.
90  // 2. Insert `using namespace std;` to the beginning of TU.
91  // 3. Do nothing and let the user deal with the migration himself.
92  if (CStyledHeaderToCxx.count(FileName) != 0) {
93  std::string Replacement =
94  (llvm::Twine("<") + CStyledHeaderToCxx[FileName] + ">").str();
95  Check.diag(FilenameRange.getBegin(),
96  "inclusion of deprecated C++ header '%0'; consider using '%1' instead")
97  << FileName << CStyledHeaderToCxx[FileName]
98  << FixItHint::CreateReplacement(FilenameRange.getAsRange(),
99  Replacement);
100  }
101 }
102 
103 } // namespace modernize
104 } // namespace tidy
105 } // namespace clang
LangOptions getLangOpts() const
Returns the language options from the context.
Definition: ClangTidy.h:170
HeaderHandle File
Base class for all clang-tidy checks.
Definition: ClangTidy.h:110
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:352
ClangTidyCheck & Check
llvm::StringMap< std::string > CStyledHeaderToCxx
void registerPPCallbacks(CompilerInstance &Compiler) override
Override this to register PPCallbacks with Compiler.