clang-tools 23.0.0git
SimplifySubscriptExprCheck.cpp
Go to the documentation of this file.
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-exception
6//
7//===----------------------------------------------------------------------===//
8
11#include "clang/AST/ASTContext.h"
12#include "clang/ASTMatchers/ASTMatchFinder.h"
13
14using namespace clang::ast_matchers;
15
17
18static constexpr char DefaultTypes[] =
19 "::std::basic_string;::std::basic_string_view;::std::vector;::std::array;::"
20 "std::span";
21
23 StringRef Name, ClangTidyContext *Context)
24 : ClangTidyCheck(Name, Context), Types(utils::options::parseStringList(
25 Options.get("Types", DefaultTypes))) {}
26
28 const auto TypesMatcher = hasUnqualifiedDesugaredType(
29 recordType(hasDeclaration(cxxRecordDecl(hasAnyName(Types)))));
30
31 Finder->addMatcher(
32 arraySubscriptExpr(
33 hasBase(cxxMemberCallExpr(
34 has(memberExpr().bind("member")),
35 on(hasType(qualType(anyOf(
36 TypesMatcher, pointerType(pointee(TypesMatcher)))))),
37 callee(namedDecl(hasName("data"))))
38 .bind("call"))),
39 this);
40}
41
42void SimplifySubscriptExprCheck::check(const MatchFinder::MatchResult &Result) {
43 const auto *Call = Result.Nodes.getNodeAs<CXXMemberCallExpr>("call");
44 if (Result.Context->getSourceManager().isMacroBodyExpansion(
45 Call->getExprLoc()))
46 return;
47
48 const auto *Member = Result.Nodes.getNodeAs<MemberExpr>("member");
49 auto DiagBuilder =
50 diag(Member->getMemberLoc(),
51 "accessing an element of the container does not require a call to "
52 "'data()'; did you mean to use 'operator[]'?");
53 if (Member->isArrow())
54 DiagBuilder << FixItHint::CreateInsertion(Member->getBeginLoc(), "(*")
55 << FixItHint::CreateInsertion(Member->getOperatorLoc(), ")");
56 DiagBuilder << FixItHint::CreateRemoval(
57 {Member->getOperatorLoc(), Call->getEndLoc()});
58}
59
64
65} // namespace clang::tidy::readability
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.
void registerMatchers(ast_matchers::MatchFinder *Finder) override
void check(const ast_matchers::MatchFinder::MatchResult &Result) override
SimplifySubscriptExprCheck(StringRef Name, ClangTidyContext *Context)
void storeOptions(ClangTidyOptions::OptionMap &Opts) override
std::string serializeStringList(ArrayRef< StringRef > Strings)
Serialize a sequence of names that can be parsed by parseStringList.
llvm::StringMap< ClangTidyValue > OptionMap