diff options
author | Samuel Benzaquen <sbenza@google.com> | 2016-04-19 15:52:56 +0000 |
---|---|---|
committer | Samuel Benzaquen <sbenza@google.com> | 2016-04-19 15:52:56 +0000 |
commit | d6b44aad313c3d3dbb1f0749301eb79e8a9ba32c (patch) | |
tree | c1481677f4c89f8b7199ad0a9ca78723cdd13040 /clang/lib | |
parent | bbfd5566401962352bd26085b73f1e445e68a0d8 (diff) | |
download | bcm5719-llvm-d6b44aad313c3d3dbb1f0749301eb79e8a9ba32c.tar.gz bcm5719-llvm-d6b44aad313c3d3dbb1f0749301eb79e8a9ba32c.zip |
[ASTMatchers] Do not try to memoize nodes we can't compare.
Summary:
Prevent hasAncestor from comparing nodes that are not supported.
hasDescendant was fixed some time ago to avoid this problem.
I'm applying the same fix to hasAncestor: if any object in the Builder map is
not comparable, skip the cache.
Reviewers: alexfh
Subscribers: klimek, cfe-commits
Differential Revision: http://reviews.llvm.org/D19231
llvm-svn: 266748
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/ASTMatchers/ASTMatchFinder.cpp | 49 |
1 files changed, 30 insertions, 19 deletions
diff --git a/clang/lib/ASTMatchers/ASTMatchFinder.cpp b/clang/lib/ASTMatchers/ASTMatchFinder.cpp index e13985bca84..eed1a182b2a 100644 --- a/clang/lib/ASTMatchers/ASTMatchFinder.cpp +++ b/clang/lib/ASTMatchers/ASTMatchFinder.cpp @@ -616,6 +616,10 @@ private: ActiveASTContext->getTranslationUnitDecl()) return false; + // For AST-nodes that don't have an identity, we can't memoize. + if (!Builder->isComparable()) + return matchesAncestorOfRecursively(Node, Matcher, Builder, MatchMode); + MatchKey Key; Key.MatcherID = Matcher.getID(); Key.Node = Node; @@ -630,22 +634,34 @@ private: } MemoizedMatchResult Result; - Result.ResultOfMatch = false; Result.Nodes = *Builder; + Result.ResultOfMatch = + matchesAncestorOfRecursively(Node, Matcher, &Result.Nodes, MatchMode); + + MemoizedMatchResult &CachedResult = ResultCache[Key]; + CachedResult = std::move(Result); + + *Builder = CachedResult.Nodes; + return CachedResult.ResultOfMatch; + } + bool matchesAncestorOfRecursively(const ast_type_traits::DynTypedNode &Node, + const DynTypedMatcher &Matcher, + BoundNodesTreeBuilder *Builder, + AncestorMatchMode MatchMode) { const auto &Parents = ActiveASTContext->getParents(Node); assert(!Parents.empty() && "Found node that is not in the parent map."); if (Parents.size() == 1) { // Only one parent - do recursive memoization. const ast_type_traits::DynTypedNode Parent = Parents[0]; - if (Matcher.matches(Parent, this, &Result.Nodes)) { - Result.ResultOfMatch = true; - } else if (MatchMode != ASTMatchFinder::AMM_ParentOnly) { - // Reset the results to not include the bound nodes from the failed - // match above. - Result.Nodes = *Builder; - Result.ResultOfMatch = memoizedMatchesAncestorOfRecursively( - Parent, Matcher, &Result.Nodes, MatchMode); + BoundNodesTreeBuilder BuilderCopy = *Builder; + if (Matcher.matches(Parent, this, &BuilderCopy)) { + *Builder = std::move(BuilderCopy); + return true; + } + if (MatchMode != ASTMatchFinder::AMM_ParentOnly) { + return memoizedMatchesAncestorOfRecursively(Parent, Matcher, Builder, + MatchMode); // Once we get back from the recursive call, the result will be the // same as the parent's result. } @@ -655,10 +671,10 @@ private: std::deque<ast_type_traits::DynTypedNode> Queue(Parents.begin(), Parents.end()); while (!Queue.empty()) { - Result.Nodes = *Builder; - if (Matcher.matches(Queue.front(), this, &Result.Nodes)) { - Result.ResultOfMatch = true; - break; + BoundNodesTreeBuilder BuilderCopy = *Builder; + if (Matcher.matches(Queue.front(), this, &BuilderCopy)) { + *Builder = std::move(BuilderCopy); + return true; } if (MatchMode != ASTMatchFinder::AMM_ParentOnly) { for (const auto &Parent : @@ -673,12 +689,7 @@ private: Queue.pop_front(); } } - - MemoizedMatchResult &CachedResult = ResultCache[Key]; - CachedResult = std::move(Result); - - *Builder = CachedResult.Nodes; - return CachedResult.ResultOfMatch; + return false; } // Implements a BoundNodesTree::Visitor that calls a MatchCallback with |