clang-tools 8.0.0

DeprecatedIosBaseAliasesCheck.cpp
Go to the documentation of this file.
1 //===--- DeprecatedIosBaseAliasesCheck.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 "DeprecatedIosBaseAliasesCheck.h"
11 #include "clang/AST/ASTContext.h"
12 #include "clang/ASTMatchers/ASTMatchFinder.h"
13
14 using namespace clang::ast_matchers;
15
16 namespace clang {
17 namespace tidy {
18 namespace modernize {
19
20 static const llvm::SmallVector<StringRef, 5> DeprecatedTypes = {
21 {"::std::ios_base::io_state"},
22 {"::std::ios_base::open_mode"},
23 {"::std::ios_base::seek_dir"},
24 {"::std::ios_base::streamoff"},
25 {"::std::ios_base::streampos"}};
26
27 static const llvm::StringMap<StringRef> ReplacementTypes = {
28 {"io_state", "iostate"},
29 {"open_mode", "openmode"},
30 {"seek_dir", "seekdir"}};
31
32 void DeprecatedIosBaseAliasesCheck::registerMatchers(MatchFinder *Finder) {
33 // Only register the matchers for C++; the functionality currently does not
34 // provide any benefit to other languages, despite being benign.
35 if (!getLangOpts().CPlusPlus)
36 return;
37
38 auto IoStateDecl = typedefDecl(hasAnyName(DeprecatedTypes)).bind("TypeDecl");
39 auto IoStateType =
40 qualType(hasDeclaration(IoStateDecl), unless(elaboratedType()));
41
42 Finder->addMatcher(typeLoc(loc(IoStateType)).bind("TypeLoc"), this);
43 }
44
45 void DeprecatedIosBaseAliasesCheck::check(
46 const MatchFinder::MatchResult &Result) {
47 SourceManager &SM = *Result.SourceManager;
48
49 const auto *Typedef = Result.Nodes.getNodeAs<TypedefDecl>("TypeDecl");
50 StringRef TypeName = Typedef->getName();
51 bool HasReplacement = ReplacementTypes.count(TypeName);
52
53 const auto *TL = Result.Nodes.getNodeAs<TypeLoc>("TypeLoc");
54 SourceLocation IoStateLoc = TL->getBeginLoc();
55
56 // Do not generate fixits for matches depending on template arguments and
57 // macro expansions.
58 bool Fix = HasReplacement && !TL->getType()->isDependentType();
59 if (IoStateLoc.isMacroID()) {
60 IoStateLoc = SM.getSpellingLoc(IoStateLoc);
61 Fix = false;
62 }
63
64 SourceLocation EndLoc = IoStateLoc.getLocWithOffset(TypeName.size() - 1);
65
66 if (HasReplacement) {
67 auto FixName = ReplacementTypes.lookup(TypeName);
68 auto Builder = diag(IoStateLoc, "'std::ios_base::%0' is deprecated; use "
69 "'std::ios_base::%1' instead")
70 << TypeName << FixName;
71
72 if (Fix)
73 Builder << FixItHint::CreateReplacement(SourceRange(IoStateLoc, EndLoc),
74 FixName);
75 } else
76 diag(IoStateLoc, "'std::ios_base::%0' is deprecated") << TypeName;
77 }
78
79 } // namespace modernize
80 } // namespace tidy
81 } // namespace clang
clang::ast_matchers
Definition: AbseilMatcher.h:15
clang::tidy::modernize::ReplacementTypes
static const llvm::StringMap< StringRef > ReplacementTypes
Definition: DeprecatedIosBaseAliasesCheck.cpp:27
Result
llvm::Optional< llvm::Expected< tooling::AtomicChanges > > Result
Definition: ClangdServer.cpp:60
clang::tidy::modernize::DeprecatedTypes
static const llvm::SmallVector< StringRef, 5 > DeprecatedTypes
Definition: DeprecatedIosBaseAliasesCheck.cpp:20
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ChangeNamespace.cpp:18
DeprecatedIosBaseAliasesCheck.h
Fix
static cl::opt< bool > Fix("fix", cl::desc(R"( Apply suggested fixes. Without -fix-errors clang-tidy will bail out if any compilation errors were found. )"), cl::init(false), cl::cat(ClangTidyCategory))