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" 23 class IncludeModernizePPCallbacks :
public PPCallbacks {
25 explicit IncludeModernizePPCallbacks(ClangTidyCheck &Check,
26 LangOptions LangOpts);
28 void InclusionDirective(SourceLocation HashLoc,
const Token &IncludeTok,
30 CharSourceRange FilenameRange,
const FileEntry *File,
31 StringRef SearchPath, StringRef RelativePath,
32 const Module *Imported,
33 SrcMgr::CharacteristicKind FileType)
override;
36 ClangTidyCheck &Check;
38 llvm::StringMap<std::string> CStyledHeaderToCxx;
39 llvm::StringSet<> DeleteHeaders;
44 const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
45 if (getLangOpts().CPlusPlus) {
47 ::llvm::make_unique<IncludeModernizePPCallbacks>(*
this, getLangOpts()));
51 IncludeModernizePPCallbacks::IncludeModernizePPCallbacks(
ClangTidyCheck &Check,
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"},
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"},
72 {
"wchar.h",
"cwchar"},
73 {
"wctype.h",
"cwctype"}})) {
74 CStyledHeaderToCxx.insert(KeyValue);
77 if (LangOpts.CPlusPlus11) {
78 for (
const auto &KeyValue :
79 std::vector<std::pair<llvm::StringRef, std::string>>(
81 {
"stdint.h",
"cstdint"},
82 {
"inttypes.h",
"cinttypes"},
83 {
"tgmath.h",
"ctgmath"},
84 {
"uchar.h",
"cuchar"}})) {
85 CStyledHeaderToCxx.insert(KeyValue);
88 for (
const auto &Key :
89 std::vector<std::string>({
"stdalign.h",
"stdbool.h",
"iso646.h"})) {
90 DeleteHeaders.insert(Key);
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) {
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(),
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()));
Base class for all clang-tidy checks.
bool IsAngled
true if this was an include with angle brackets
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
DiagnosticBuilder diag(SourceLocation Loc, StringRef Description, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Add a diagnostic with the check's name.