12 #include "clang/AST/ASTContext.h"
13 #include "clang/AST/DeclCXX.h"
14 #include "clang/ASTMatchers/ASTMatchFinder.h"
19 namespace decl_ref_expr {
21 using namespace ::clang::ast_matchers;
22 using llvm::SmallPtrSet;
26 template <
typename S>
bool isSetDifferenceEmpty(
const S &S1,
const S &S2) {
27 for (
const auto &E : S1)
34 template <
typename Node>
35 void extractNodesByIdTo(ArrayRef<BoundNodes> Matches, StringRef ID,
36 SmallPtrSet<const Node *, 16> &Nodes) {
37 for (
const auto &Match : Matches)
38 Nodes.insert(Match.getNodeAs<Node>(ID));
45 SmallPtrSet<const DeclRefExpr *, 16>
49 declRefExpr(to(varDecl(equalsNode(&VarDecl)))).bind(
"declRef");
50 auto ConstMethodCallee = callee(cxxMethodDecl(isConst()));
55 findAll(expr(anyOf(cxxMemberCallExpr(ConstMethodCallee, on(DeclRefToVar)),
56 cxxOperatorCallExpr(ConstMethodCallee,
57 hasArgument(0, DeclRefToVar))))),
59 SmallPtrSet<const DeclRefExpr *, 16> DeclRefs;
60 extractNodesByIdTo(Matches,
"declRef", DeclRefs);
61 auto ConstReferenceOrValue =
62 qualType(anyOf(referenceType(pointee(qualType(isConstQualified()))),
63 unless(anyOf(referenceType(), pointerType()))));
64 auto UsedAsConstRefOrValueArg = forEachArgumentWithParam(
65 DeclRefToVar, parmVarDecl(hasType(ConstReferenceOrValue)));
66 Matches = match(findAll(callExpr(UsedAsConstRefOrValueArg)), Stmt, Context);
67 extractNodesByIdTo(Matches,
"declRef", DeclRefs);
69 match(findAll(cxxConstructExpr(UsedAsConstRefOrValueArg)), Stmt, Context);
70 extractNodesByIdTo(Matches,
"declRef", DeclRefs);
83 return isSetDifferenceEmpty(AllDeclRefs, ConstReferenceDeclRefs);
86 SmallPtrSet<const DeclRefExpr *, 16>
89 findAll(declRefExpr(to(varDecl(equalsNode(&VarDecl)))).bind(
"declRef")),
91 SmallPtrSet<const DeclRefExpr *, 16> DeclRefs;
92 extractNodesByIdTo(Matches,
"declRef", DeclRefs);
98 auto UsedAsConstRefArg = forEachArgumentWithParam(
99 declRefExpr(equalsNode(&DeclRef)),
100 parmVarDecl(hasType(matchers::isReferenceToConst())));
101 auto Matches = match(
103 cxxConstructExpr(UsedAsConstRefArg, hasDeclaration(cxxConstructorDecl(
104 isCopyConstructor())))
105 .bind(
"constructExpr"))),
107 return !Matches.empty();
112 auto UsedAsConstRefArg = forEachArgumentWithParam(
113 declRefExpr(equalsNode(&DeclRef)),
114 parmVarDecl(hasType(matchers::isReferenceToConst())));
115 auto Matches = match(
117 cxxOperatorCallExpr(UsedAsConstRefArg, hasOverloadedOperatorName(
"="))
118 .bind(
"operatorCallExpr"))),
120 return !Matches.empty();
SmallPtrSet< const DeclRefExpr *, 16 > allDeclRefExprs(const VarDecl &VarDecl, const Stmt &Stmt, ASTContext &Context)
bool isOnlyUsedAsConst(const VarDecl &Var, const Stmt &Stmt, ASTContext &Context)
Returns true if all DeclRefExpr to the variable within Stmt do not modify it.
bool isCopyAssignmentArgument(const DeclRefExpr &DeclRef, const Stmt &Stmt, ASTContext &Context)
bool isCopyConstructorArgument(const DeclRefExpr &DeclRef, const Stmt &Stmt, ASTContext &Context)
SmallPtrSet< const DeclRefExpr *, 16 > constReferenceDeclRefExprs(const VarDecl &VarDecl, const Stmt &Stmt, ASTContext &Context)
ClangTidyContext & Context