[NFC] Minor refactoring to setup the stage for supporting pointers in ExprMutationAnalyzer

llvm-svn: 342353
This commit is contained in:
Shuai Wang 2018-09-16 21:09:50 +00:00
parent cffa206423
commit aaaa310de2
2 changed files with 105 additions and 42 deletions

View File

@ -31,13 +31,32 @@ public:
const Stmt *findMutation(const Expr *Exp);
const Stmt *findMutation(const Decl *Dec);
bool isPointeeMutated(const Expr *Exp) {
return findPointeeMutation(Exp) != nullptr;
}
bool isPointeeMutated(const Decl *Dec) {
return findPointeeMutation(Dec) != nullptr;
}
const Stmt *findPointeeMutation(const Expr *Exp);
const Stmt *findPointeeMutation(const Decl *Dec);
private:
using MutationFinder = const Stmt *(ExprMutationAnalyzer::*)(const Expr *);
using ResultMap = llvm::DenseMap<const Expr *, const Stmt *>;
const Stmt *findMutationMemoized(const Expr *Exp,
llvm::ArrayRef<MutationFinder> Finders,
ResultMap &MemoizedResults);
const Stmt *tryEachDeclRef(const Decl *Dec, MutationFinder Finder);
bool isUnevaluated(const Expr *Exp);
const Stmt *findExprMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
const Stmt *findDeclMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
const Stmt *
findExprPointeeMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
const Stmt *
findDeclPointeeMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
const Stmt *findDirectMutation(const Expr *Exp);
const Stmt *findMemberMutation(const Expr *Exp);
@ -53,6 +72,7 @@ private:
std::unique_ptr<FunctionParmMutationAnalyzer>>
FuncParmAnalyzer;
ResultMap Results;
ResultMap PointeeResults;
};
// A convenient wrapper around ExprMutationAnalyzer for analyzing function

View File

@ -64,33 +64,83 @@ const auto isMoveOnly = [] {
unless(isDeleted()))))));
};
template <class T> struct NodeID;
template <> struct NodeID<Expr> { static const std::string value; };
template <> struct NodeID<Decl> { static const std::string value; };
const std::string NodeID<Expr>::value = "expr";
const std::string NodeID<Decl>::value = "decl";
template <class T, class F = const Stmt *(ExprMutationAnalyzer::*)(const T *)>
const Stmt *tryEachMatch(ArrayRef<ast_matchers::BoundNodes> Matches,
ExprMutationAnalyzer *Analyzer, F Finder) {
const StringRef ID = NodeID<T>::value;
for (const auto &Nodes : Matches) {
if (const Stmt *S = (Analyzer->*Finder)(Nodes.getNodeAs<T>(ID)))
return S;
}
return nullptr;
}
} // namespace
const Stmt *ExprMutationAnalyzer::findMutation(const Expr *Exp) {
const auto Memoized = Results.find(Exp);
if (Memoized != Results.end())
return findMutationMemoized(Exp,
{&ExprMutationAnalyzer::findDirectMutation,
&ExprMutationAnalyzer::findMemberMutation,
&ExprMutationAnalyzer::findArrayElementMutation,
&ExprMutationAnalyzer::findCastMutation,
&ExprMutationAnalyzer::findRangeLoopMutation,
&ExprMutationAnalyzer::findReferenceMutation,
&ExprMutationAnalyzer::findFunctionArgMutation},
Results);
}
const Stmt *ExprMutationAnalyzer::findMutation(const Decl *Dec) {
return tryEachDeclRef(Dec, &ExprMutationAnalyzer::findMutation);
}
const Stmt *ExprMutationAnalyzer::findPointeeMutation(const Expr *Exp) {
return findMutationMemoized(Exp, {/*TODO*/}, PointeeResults);
}
const Stmt *ExprMutationAnalyzer::findPointeeMutation(const Decl *Dec) {
return tryEachDeclRef(Dec, &ExprMutationAnalyzer::findPointeeMutation);
}
const Stmt *ExprMutationAnalyzer::findMutationMemoized(
const Expr *Exp, llvm::ArrayRef<MutationFinder> Finders,
ResultMap &MemoizedResults) {
const auto Memoized = MemoizedResults.find(Exp);
if (Memoized != MemoizedResults.end())
return Memoized->second;
if (isUnevaluated(Exp))
return Results[Exp] = nullptr;
return MemoizedResults[Exp] = nullptr;
for (const auto &Finder : {&ExprMutationAnalyzer::findDirectMutation,
&ExprMutationAnalyzer::findMemberMutation,
&ExprMutationAnalyzer::findArrayElementMutation,
&ExprMutationAnalyzer::findCastMutation,
&ExprMutationAnalyzer::findRangeLoopMutation,
&ExprMutationAnalyzer::findReferenceMutation,
&ExprMutationAnalyzer::findFunctionArgMutation}) {
for (const auto &Finder : Finders) {
if (const Stmt *S = (this->*Finder)(Exp))
return Results[Exp] = S;
return MemoizedResults[Exp] = S;
}
return Results[Exp] = nullptr;
return MemoizedResults[Exp] = nullptr;
}
const Stmt *ExprMutationAnalyzer::tryEachDeclRef(const Decl *Dec,
MutationFinder Finder) {
const auto Refs =
match(findAll(declRefExpr(to(equalsNode(Dec))).bind(NodeID<Expr>::value)),
Stm, Context);
for (const auto &RefNodes : Refs) {
const auto *E = RefNodes.getNodeAs<Expr>(NodeID<Expr>::value);
if ((this->*Finder)(E))
return E;
}
return nullptr;
}
bool ExprMutationAnalyzer::isUnevaluated(const Expr *Exp) {
return selectFirst<Expr>(
"expr",
NodeID<Expr>::value,
match(
findAll(
expr(equalsNode(Exp),
@ -115,37 +165,30 @@ bool ExprMutationAnalyzer::isUnevaluated(const Expr *Exp) {
genericSelectionExpr(hasControllingExpr(
hasDescendant(equalsNode(Exp)))),
cxxNoexceptExpr())))))
.bind("expr")),
.bind(NodeID<Expr>::value)),
Stm, Context)) != nullptr;
}
const Stmt *
ExprMutationAnalyzer::findExprMutation(ArrayRef<BoundNodes> Matches) {
for (const auto &Nodes : Matches) {
if (const Stmt *S = findMutation(Nodes.getNodeAs<Expr>("expr")))
return S;
}
return nullptr;
return tryEachMatch<Expr>(Matches, this, &ExprMutationAnalyzer::findMutation);
}
const Stmt *
ExprMutationAnalyzer::findDeclMutation(ArrayRef<BoundNodes> Matches) {
for (const auto &DeclNodes : Matches) {
if (const Stmt *S = findMutation(DeclNodes.getNodeAs<Decl>("decl")))
return S;
}
return nullptr;
return tryEachMatch<Decl>(Matches, this, &ExprMutationAnalyzer::findMutation);
}
const Stmt *ExprMutationAnalyzer::findMutation(const Decl *Dec) {
const auto Refs = match(
findAll(declRefExpr(to(equalsNode(Dec))).bind("expr")), Stm, Context);
for (const auto &RefNodes : Refs) {
const auto *E = RefNodes.getNodeAs<Expr>("expr");
if (findMutation(E))
return E;
}
return nullptr;
const Stmt *ExprMutationAnalyzer::findExprPointeeMutation(
ArrayRef<ast_matchers::BoundNodes> Matches) {
return tryEachMatch<Expr>(Matches, this,
&ExprMutationAnalyzer::findPointeeMutation);
}
const Stmt *ExprMutationAnalyzer::findDeclPointeeMutation(
ArrayRef<ast_matchers::BoundNodes> Matches) {
return tryEachMatch<Decl>(Matches, this,
&ExprMutationAnalyzer::findPointeeMutation);
}
const Stmt *ExprMutationAnalyzer::findDirectMutation(const Expr *Exp) {
@ -237,7 +280,7 @@ const Stmt *ExprMutationAnalyzer::findMemberMutation(const Expr *Exp) {
match(findAll(expr(anyOf(memberExpr(hasObjectExpression(equalsNode(Exp))),
cxxDependentScopeMemberExpr(
hasObjectExpression(equalsNode(Exp)))))
.bind("expr")),
.bind(NodeID<Expr>::value)),
Stm, Context);
return findExprMutation(MemberExprs);
}
@ -246,7 +289,7 @@ const Stmt *ExprMutationAnalyzer::findArrayElementMutation(const Expr *Exp) {
// Check whether any element of an array is mutated.
const auto SubscriptExprs = match(
findAll(arraySubscriptExpr(hasBase(ignoringImpCasts(equalsNode(Exp))))
.bind("expr")),
.bind(NodeID<Expr>::value)),
Stm, Context);
return findExprMutation(SubscriptExprs);
}
@ -259,7 +302,7 @@ const Stmt *ExprMutationAnalyzer::findCastMutation(const Expr *Exp) {
nonConstReferenceType())),
implicitCastExpr(hasImplicitDestinationType(
nonConstReferenceType()))))
.bind("expr")),
.bind(NodeID<Expr>::value)),
Stm, Context);
return findExprMutation(Casts);
}
@ -269,8 +312,8 @@ const Stmt *ExprMutationAnalyzer::findRangeLoopMutation(const Expr *Exp) {
// check all declRefExpr of the loop variable.
const auto LoopVars =
match(findAll(cxxForRangeStmt(
hasLoopVariable(
varDecl(hasType(nonConstReferenceType())).bind("decl")),
hasLoopVariable(varDecl(hasType(nonConstReferenceType()))
.bind(NodeID<Decl>::value)),
hasRangeInit(equalsNode(Exp)))),
Stm, Context);
return findDeclMutation(LoopVars);
@ -286,7 +329,7 @@ const Stmt *ExprMutationAnalyzer::findReferenceMutation(const Expr *Exp) {
callee(cxxMethodDecl(ofClass(isMoveOnly()),
returns(nonConstReferenceType()))),
argumentCountIs(1), hasArgument(0, equalsNode(Exp)))
.bind("expr")),
.bind(NodeID<Expr>::value)),
Stm, Context);
if (const Stmt *S = findExprMutation(Ref))
return S;
@ -305,7 +348,7 @@ const Stmt *ExprMutationAnalyzer::findReferenceMutation(const Expr *Exp) {
// that separately.
unless(hasParent(declStmt(hasParent(
cxxForRangeStmt(hasRangeStmt(equalsBoundNode("stmt"))))))))
.bind("decl"))),
.bind(NodeID<Decl>::value))),
Stm, Context);
return findDeclMutation(Refs);
}
@ -320,10 +363,10 @@ const Stmt *ExprMutationAnalyzer::findFunctionArgMutation(const Expr *Exp) {
findAll(expr(anyOf(callExpr(NonConstRefParam, IsInstantiated, FuncDecl),
cxxConstructExpr(NonConstRefParam, IsInstantiated,
FuncDecl)))
.bind("expr")),
.bind(NodeID<Expr>::value)),
Stm, Context);
for (const auto &Nodes : Matches) {
const auto *Exp = Nodes.getNodeAs<Expr>("expr");
const auto *Exp = Nodes.getNodeAs<Expr>(NodeID<Expr>::value);
const auto *Func = Nodes.getNodeAs<FunctionDecl>("func");
if (!Func->getBody())
return Exp;