30AST_MATCHER_P2(Stmt, argumentOf,
bool, AllowPartialMove, StatementMatcher,
33 return stmt(anyOf(Ref, hasDescendant(Ref))).matches(Node, Finder, Builder);
39 auto ToParam = hasAnyParameter(parmVarDecl(equalsBoundNode(
"param")));
41 const StatementMatcher MoveCallMatcher =
44 anyOf(callee(functionDecl(hasName(MoveFunction))),
45 callee(unresolvedLookupExpr(hasAnyDeclaration(
46 namedDecl(hasUnderlyingDecl(hasName(MoveFunction))))))),
50 declRefExpr(to(equalsBoundNode(
"param"))).bind(
"ref"))),
52 lambdaExpr(valueCapturesVar(equalsBoundNode(
"param"))))),
53 unless(anyOf(hasAncestor(typeLoc()),
54 hasAncestor(expr(hasUnevaluatedContext())))))
59 hasType(type(rValueReferenceType())), parmVarDecl().bind(
"param"),
60 unless(hasType(references(qualType(
61 anyOf(isConstQualified(), substTemplateTypeParmType()))))),
62 optionally(hasType(qualType(references(templateTypeParmType(
63 hasDeclaration(templateTypeParmDecl().bind(
"template-type"))))))),
66 isDefinition(), unless(isDeleted()), unless(isDefaulted()),
67 unless(cxxConstructorDecl(isMoveConstructor())),
68 unless(cxxMethodDecl(isMoveAssignmentOperator())), ToParam,
69 anyOf(cxxConstructorDecl(
70 optionally(hasDescendant(MoveCallMatcher))),
71 functionDecl(unless(cxxConstructorDecl()),
73 hasDescendant(MoveCallMatcher))))))
79 const MatchFinder::MatchResult &Result) {
80 const auto *Param = Result.Nodes.getNodeAs<ParmVarDecl>(
"param");
81 const auto *Function = Result.Nodes.getNodeAs<FunctionDecl>(
"func");
82 const auto *TemplateType =
83 Result.Nodes.getNodeAs<TemplateTypeParmDecl>(
"template-type");
85 if (!Param || !Function)
88 if (IgnoreUnnamedParams && Param->getName().empty())
91 if (!Param->isUsed() && Param->hasAttr<UnusedAttr>())
94 if (IgnoreNonDeducedTemplateTypes && TemplateType)
98 if (
const FunctionTemplateDecl *FuncTemplate =
99 Function->getDescribedFunctionTemplate()) {
100 const TemplateParameterList *Params =
101 FuncTemplate->getTemplateParameters();
102 if (llvm::is_contained(*Params, TemplateType)) {
109 const auto *MoveCall = Result.Nodes.getNodeAs<CallExpr>(
"move-call");
111 diag(Param->getLocation(),
112 "rvalue reference parameter %0 is never moved from "
113 "inside the function body")
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.