clang-tools  10.0.0
DeprecatedHeadersCheck.cpp
Go to the documentation of this file.
1 //===--- DeprecatedHeadersCheck.cpp - clang-tidy---------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 #include "clang/Frontend/CompilerInstance.h"
11 #include "clang/Lex/PPCallbacks.h"
12 #include "clang/Lex/Preprocessor.h"
13 #include "llvm/ADT/StringMap.h"
14 #include "llvm/ADT/StringSet.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,
33  SrcMgr::CharacteristicKind FileType) override;
34 
35 private:
36  ClangTidyCheck &Check;
37  LangOptions LangOpts;
38  llvm::StringMap<std::string> CStyledHeaderToCxx;
39  llvm::StringSet<> DeleteHeaders;
40 };
41 } // namespace
42 
44  const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
45  if (getLangOpts().CPlusPlus) {
46  PP->addPPCallbacks(
47  ::std::make_unique<IncludeModernizePPCallbacks>(*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  SrcMgr::CharacteristicKind FileType) {
99  // FIXME: Take care of library symbols from the global namespace.
100  //
101  // Reasonable options for the check:
102  //
103  // 1. Insert std prefix for every such symbol occurrence.
104  // 2. Insert `using namespace std;` to the beginning of TU.
105  // 3. Do nothing and let the user deal with the migration himself.
106  if (CStyledHeaderToCxx.count(FileName) != 0) {
107  std::string Replacement =
108  (llvm::Twine("<") + CStyledHeaderToCxx[FileName] + ">").str();
109  Check.diag(FilenameRange.getBegin(), "inclusion of deprecated C++ header "
110  "'%0'; consider using '%1' instead")
111  << FileName << CStyledHeaderToCxx[FileName]
112  << FixItHint::CreateReplacement(FilenameRange.getAsRange(),
113  Replacement);
114  } else if (DeleteHeaders.count(FileName) != 0) {
115  Check.diag(FilenameRange.getBegin(),
116  "including '%0' has no effect in C++; consider removing it")
117  << FileName << FixItHint::CreateRemoval(
118  SourceRange(HashLoc, FilenameRange.getEnd()));
119  }
120 }
121 
122 } // namespace modernize
123 } // namespace tidy
124 } // namespace clang
Base class for all clang-tidy checks.
bool IsAngled
true if this was an include with angle brackets
PathRef FileName
void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) override
Override this to register PPCallbacks in the preprocessor.
===– 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.