Mercurial > hg > CbC > CbC_llvm
view clang-tools-extra/clang-tidy/readability/SimplifySubscriptExprCheck.cpp @ 214:0cf2d4ade63d
...
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 13 Jul 2021 09:53:52 +0900 |
parents | 2e18cbf3894f |
children | c4bab56944e8 |
line wrap: on
line source
//===--- SimplifySubscriptExprCheck.cpp - clang-tidy-----------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "SimplifySubscriptExprCheck.h" #include "../utils/OptionsUtils.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" using namespace clang::ast_matchers; namespace clang { namespace tidy { namespace readability { static const char KDefaultTypes[] = "::std::basic_string;::std::basic_string_view;::std::vector;::std::array"; SimplifySubscriptExprCheck::SimplifySubscriptExprCheck( StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), Types(utils::options::parseStringList( Options.get("Types", KDefaultTypes))) { } void SimplifySubscriptExprCheck::registerMatchers(MatchFinder *Finder) { const auto TypesMatcher = hasUnqualifiedDesugaredType( recordType(hasDeclaration(cxxRecordDecl(hasAnyName( llvm::SmallVector<StringRef, 8>(Types.begin(), Types.end())))))); Finder->addMatcher( arraySubscriptExpr(hasBase( cxxMemberCallExpr( has(memberExpr().bind("member")), on(hasType(qualType( unless(anyOf(substTemplateTypeParmType(), hasDescendant(substTemplateTypeParmType()))), anyOf(TypesMatcher, pointerType(pointee(TypesMatcher)))))), callee(namedDecl(hasName("data")))) .bind("call"))), this); } void SimplifySubscriptExprCheck::check(const MatchFinder::MatchResult &Result) { const auto *Call = Result.Nodes.getNodeAs<CXXMemberCallExpr>("call"); if (Result.Context->getSourceManager().isMacroBodyExpansion( Call->getExprLoc())) return; const auto *Member = Result.Nodes.getNodeAs<MemberExpr>("member"); auto DiagBuilder = diag(Member->getMemberLoc(), "accessing an element of the container does not require a call to " "'data()'; did you mean to use 'operator[]'?"); if (Member->isArrow()) DiagBuilder << FixItHint::CreateInsertion(Member->getBeginLoc(), "(*") << FixItHint::CreateInsertion(Member->getOperatorLoc(), ")"); DiagBuilder << FixItHint::CreateRemoval( {Member->getOperatorLoc(), Call->getEndLoc()}); } void SimplifySubscriptExprCheck::storeOptions( ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "Types", utils::options::serializeStringList(Types)); } } // namespace readability } // namespace tidy } // namespace clang