43 has(cxxMethodDecl(isPublic(), hasName(
"data")).bind(
"data")))
47 const auto NonTemplateContainerType =
48 qualType(hasUnqualifiedDesugaredType(recordType(hasDeclaration(Record))));
49 const auto TemplateContainerType =
50 qualType(hasUnqualifiedDesugaredType(templateSpecializationType(
51 hasDeclaration(classTemplateDecl(has(Record))))));
53 const auto Container =
54 qualType(anyOf(NonTemplateContainerType, TemplateContainerType));
56 const auto ContainerExpr = anyOf(
62 unaryOperator(hasOperatorName(
"&"),
63 hasUnaryOperand(expr(anyOf(hasType(Container),
64 hasType(references(Container))))
67 expr(anyOf(hasType(Container), hasType(pointsTo(Container)),
68 hasType(references(Container))))
71 const auto Zero = integerLiteral(equals(0));
73 const auto SubscriptOperator = callee(cxxMethodDecl(hasName(
"operator[]")));
77 unless(isExpansionInSystemHeader()), hasOperatorName(
"&"),
79 anyOf(cxxOperatorCallExpr(SubscriptOperator, argumentCountIs(2),
80 hasArgument(0, ContainerExpr),
81 hasArgument(1, Zero)),
82 cxxMemberCallExpr(SubscriptOperator, on(ContainerExpr),
83 argumentCountIs(1), hasArgument(0, Zero)),
84 arraySubscriptExpr(hasLHS(ContainerExpr), hasRHS(Zero))))))
90 const auto *UO = Result.Nodes.getNodeAs<UnaryOperator>(
AddressOfName);
98 if (DCE && !CE->getType()->isPointerType())
103 const SourceRange SrcRange = CE->getSourceRange();
105 std::string ReplacementText{
106 Lexer::getSourceText(CharSourceRange::getTokenRange(SrcRange),
107 *Result.SourceManager, getLangOpts())};
109 const auto *OpCall = dyn_cast<CXXOperatorCallExpr>(CE);
110 const bool NeedsParens =
111 OpCall ? (OpCall->getOperator() != OO_Subscript)
112 : !isa<DeclRefExpr, MemberExpr, ArraySubscriptExpr, CallExpr>(CE);
114 ReplacementText =
"(" + ReplacementText +
")";
116 if (CE->getType()->isPointerType())
117 ReplacementText +=
"->data()";
119 ReplacementText +=
".data()";
121 const FixItHint Hint =
122 FixItHint::CreateReplacement(UO->getSourceRange(), ReplacementText);
123 diag(UO->getBeginLoc(),
124 "'data' should be used for accessing the data pointer instead of taking "
125 "the address of the 0-th element")
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.