12 #include "clang/AST/ASTContext.h" 13 #include "clang/AST/DeclCXX.h" 14 #include "clang/ASTMatchers/ASTMatchFinder.h" 19 namespace decl_ref_expr {
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>
47 ASTContext &Context) {
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);
76 SmallPtrSet<const DeclRefExpr *, 16>
78 ASTContext &Context) {
80 declRefExpr(to(varDecl(equalsNode(&VarDecl)))).bind(
"declRef");
81 auto ConstMethodCallee = callee(cxxMethodDecl(isConst()));
86 match(decl(forEachDescendant(expr(
87 anyOf(cxxMemberCallExpr(ConstMethodCallee, on(DeclRefToVar)),
88 cxxOperatorCallExpr(ConstMethodCallee,
89 hasArgument(0, DeclRefToVar)))))),
91 SmallPtrSet<const DeclRefExpr *, 16> DeclRefs;
92 extractNodesByIdTo(Matches,
"declRef", DeclRefs);
93 auto ConstReferenceOrValue =
94 qualType(anyOf(referenceType(pointee(qualType(isConstQualified()))),
95 unless(anyOf(referenceType(), pointerType()))));
96 auto UsedAsConstRefOrValueArg = forEachArgumentWithParam(
97 DeclRefToVar, parmVarDecl(hasType(ConstReferenceOrValue)));
98 Matches = match(decl(forEachDescendant(callExpr(UsedAsConstRefOrValueArg))),
100 extractNodesByIdTo(Matches,
"declRef", DeclRefs);
102 match(decl(forEachDescendant(cxxConstructExpr(UsedAsConstRefOrValueArg))),
104 extractNodesByIdTo(Matches,
"declRef", DeclRefs);
109 ASTContext &Context) {
117 return isSetDifferenceEmpty(AllDeclRefs, ConstReferenceDeclRefs);
120 SmallPtrSet<const DeclRefExpr *, 16>
122 auto Matches = match(
123 findAll(declRefExpr(to(varDecl(equalsNode(&VarDecl)))).bind(
"declRef")),
125 SmallPtrSet<const DeclRefExpr *, 16> DeclRefs;
126 extractNodesByIdTo(Matches,
"declRef", DeclRefs);
130 SmallPtrSet<const DeclRefExpr *, 16>
132 auto Matches = match(
133 decl(forEachDescendant(
134 declRefExpr(to(varDecl(equalsNode(&VarDecl)))).bind(
"declRef"))),
136 SmallPtrSet<const DeclRefExpr *, 16> DeclRefs;
137 extractNodesByIdTo(Matches,
"declRef", DeclRefs);
142 ASTContext &Context) {
143 auto UsedAsConstRefArg = forEachArgumentWithParam(
144 declRefExpr(equalsNode(&DeclRef)),
145 parmVarDecl(hasType(matchers::isReferenceToConst())));
146 auto Matches = match(
148 cxxConstructExpr(UsedAsConstRefArg, hasDeclaration(cxxConstructorDecl(
149 isCopyConstructor())))
150 .bind(
"constructExpr"))),
152 return !Matches.empty();
156 ASTContext &Context) {
157 auto UsedAsConstRefArg = forEachArgumentWithParam(
158 declRefExpr(equalsNode(&DeclRef)),
159 parmVarDecl(hasType(matchers::isReferenceToConst())));
160 auto Matches = match(
162 cxxOperatorCallExpr(UsedAsConstRefArg, hasOverloadedOperatorName(
"="),
163 callee(cxxMethodDecl(isCopyAssignmentOperator())))
164 .bind(
"operatorCallExpr"))),
166 return !Matches.empty();
SmallPtrSet< const DeclRefExpr *, 16 > allDeclRefExprs(const VarDecl &VarDecl, const Stmt &Stmt, ASTContext &Context)
Returns set of all DeclRefExprs to VarDecl within Stmt.
bool isCopyConstructorArgument(const DeclRefExpr &DeclRef, const Decl &Decl, ASTContext &Context)
Returns true if DeclRefExpr is the argument of a copy-constructor call expression within Decl...
bool isOnlyUsedAsConst(const VarDecl &Var, const Stmt &Stmt, ASTContext &Context)
Returns true if all DeclRefExpr to the variable within Stmt do not modify it.
SmallPtrSet< const DeclRefExpr *, 16 > constReferenceDeclRefExprs(const VarDecl &VarDecl, const Stmt &Stmt, ASTContext &Context)
Returns set of all DeclRefExprs to VarDecl within Stmt where VarDecl is guaranteed to be accessed in ...
bool isCopyAssignmentArgument(const DeclRefExpr &DeclRef, const Decl &Decl, ASTContext &Context)
Returns true if DeclRefExpr is the argument of a copy-assignment operator CallExpr within Decl...
const DeclRefExpr * DeclRef