brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.7 KiB · 7e43165 Raw
75 lines · cpp
1//===----------------------------------------------------------------------===//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "DeprecatedIosBaseAliasesCheck.h"10#include "clang/ASTMatchers/ASTMatchFinder.h"11#include <optional>12 13using namespace clang::ast_matchers;14 15namespace clang::tidy::modernize {16 17static constexpr std::array<StringRef, 5> DeprecatedTypes = {18    "::std::ios_base::io_state", "::std::ios_base::open_mode",19    "::std::ios_base::seek_dir", "::std::ios_base::streamoff",20    "::std::ios_base::streampos"};21 22static std::optional<const char *> getReplacementType(StringRef Type) {23  return llvm::StringSwitch<std::optional<const char *>>(Type)24      .Case("io_state", "iostate")25      .Case("open_mode", "openmode")26      .Case("seek_dir", "seekdir")27      .Default(std::nullopt);28}29 30void DeprecatedIosBaseAliasesCheck::registerMatchers(MatchFinder *Finder) {31  auto IoStateDecl = typedefDecl(hasAnyName(DeprecatedTypes)).bind("TypeDecl");32  auto IoStateType = typedefType(hasDeclaration(IoStateDecl));33 34  Finder->addMatcher(typeLoc(loc(IoStateType)).bind("TypeLoc"), this);35}36 37void DeprecatedIosBaseAliasesCheck::check(38    const MatchFinder::MatchResult &Result) {39  const SourceManager &SM = *Result.SourceManager;40 41  const auto *Typedef = Result.Nodes.getNodeAs<TypedefDecl>("TypeDecl");42  const StringRef TypeName = Typedef->getName();43  auto Replacement = getReplacementType(TypeName);44 45  TypeLoc TL = *Result.Nodes.getNodeAs<TypeLoc>("TypeLoc");46  if (auto QTL = TL.getAs<QualifiedTypeLoc>())47    TL = QTL.getUnqualifiedLoc();48 49  SourceLocation IoStateLoc = TL.castAs<TypedefTypeLoc>().getNameLoc();50  // Do not generate fixits for matches depending on template arguments and51  // macro expansions.52  bool Fix = Replacement && !TL.getType()->isDependentType();53  if (IoStateLoc.isMacroID()) {54    IoStateLoc = SM.getSpellingLoc(IoStateLoc);55    Fix = false;56  }57 58  const SourceLocation EndLoc =59      IoStateLoc.getLocWithOffset(TypeName.size() - 1);60 61  if (Replacement) {62    const char *FixName = *Replacement;63    auto Builder = diag(IoStateLoc, "'std::ios_base::%0' is deprecated; use "64                                    "'std::ios_base::%1' instead")65                   << TypeName << FixName;66 67    if (Fix)68      Builder << FixItHint::CreateReplacement(SourceRange(IoStateLoc, EndLoc),69                                              FixName);70  } else71    diag(IoStateLoc, "'std::ios_base::%0' is deprecated") << TypeName;72}73 74} // namespace clang::tidy::modernize75