blob: 005edcb88438204646dbd7760214f63e236cddae [file] [log] [blame]
Alexander Kornienkoe4a75fd2016-02-24 13:36:34 +00001//===--- 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
18namespace clang {
19namespace tidy {
20namespace modernize {
21
22namespace {
23class IncludeModernizePPCallbacks : public PPCallbacks {
24public:
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
34private:
35 ClangTidyCheck &Check;
36 LangOptions LangOpts;
37 llvm::StringMap<std::string> CStyledHeaderToCxx;
38};
39} // namespace
40
41void 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
49IncludeModernizePPCallbacks::IncludeModernizePPCallbacks(ClangTidyCheck &Check,
50 LangOptions LangOpts)
Alexander Kornienko4f933372016-02-25 00:39:11 +000051 : 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 }
Alexander Kornienkoe4a75fd2016-02-24 13:36:34 +000067 // Add C++ 11 headers.
68 if (LangOpts.CPlusPlus11) {
Alexander Kornienko4432e122016-02-24 23:48:24 +000069 for (const auto &KeyValue :
Alexander Kornienko4f933372016-02-25 00:39:11 +000070 std::vector<std::pair<llvm::StringRef, std::string>>(
Alexander Kornienkoe4a75fd2016-02-24 13:36:34 +000071 {{"fenv.h", "cfenv"},
72 {"stdalign.h", "cstdalign"},
73 {"stdbool.h", "cstdbool"},
74 {"tgmath.h", "ctgmath"},
75 {"uchar.h", "cuchar"}})) {
Alexander Kornienko4432e122016-02-24 23:48:24 +000076 CStyledHeaderToCxx.insert(KeyValue);
Alexander Kornienkoe4a75fd2016-02-24 13:36:34 +000077 }
78 }
79}
80
81void 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