diff options
| author | Shuai Wang <shuaiwang@google.com> | 2018-09-16 21:09:50 +0000 |
|---|---|---|
| committer | Shuai Wang <shuaiwang@google.com> | 2018-09-16 21:09:50 +0000 |
| commit | aaaa310de21650e1234f6ef991b676616c2a36da (patch) | |
| tree | bc42865844c07031849f64e990d6cf5d07c4cc0b /clang/lib/Analysis | |
| parent | cffa206423ffd3ce2ef797bab468ec97521c1cde (diff) | |
| download | bcm5719-llvm-aaaa310de21650e1234f6ef991b676616c2a36da.tar.gz bcm5719-llvm-aaaa310de21650e1234f6ef991b676616c2a36da.zip | |
[NFC] Minor refactoring to setup the stage for supporting pointers in ExprMutationAnalyzer
llvm-svn: 342353
Diffstat (limited to 'clang/lib/Analysis')
| -rw-r--r-- | clang/lib/Analysis/ExprMutationAnalyzer.cpp | 129 |
1 files changed, 86 insertions, 43 deletions
diff --git a/clang/lib/Analysis/ExprMutationAnalyzer.cpp b/clang/lib/Analysis/ExprMutationAnalyzer.cpp index f8ede47bda8..50d4d0b8890 100644 --- a/clang/lib/Analysis/ExprMutationAnalyzer.cpp +++ b/clang/lib/Analysis/ExprMutationAnalyzer.cpp @@ -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; - - for (const auto &Finder : {&ExprMutationAnalyzer::findDirectMutation, - &ExprMutationAnalyzer::findMemberMutation, - &ExprMutationAnalyzer::findArrayElementMutation, - &ExprMutationAnalyzer::findCastMutation, - &ExprMutationAnalyzer::findRangeLoopMutation, - &ExprMutationAnalyzer::findReferenceMutation, - &ExprMutationAnalyzer::findFunctionArgMutation}) { + return MemoizedResults[Exp] = nullptr; + + 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; |

