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 
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
static const llvm::StringMap< StringRef > ReplacementTypes
llvm::Optional< llvm::Expected< tooling::AtomicChanges > > Result
static const llvm::SmallVector< StringRef, 5 > DeprecatedTypes
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
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))