Fix use of invalidated iterator bug in AST match finder.

Pulled out the cache clearing in the case of descendant matching, too,
for consistency, also it is not technically needed there.

FIXME: Make cache size configurable and add unit test.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@185820 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/ASTMatchers/ASTMatchFinder.cpp b/lib/ASTMatchers/ASTMatchFinder.cpp
index a68c7fd..e1e5f44 100644
--- a/lib/ASTMatchers/ASTMatchFinder.cpp
+++ b/lib/ASTMatchers/ASTMatchFinder.cpp
@@ -384,8 +384,6 @@
       return matchesRecursively(Node, Matcher, Builder, MaxDepth, Traversal,
                                 Bind);
 
-    if (ResultCache.size() > MaxMemoizationEntries)
-      ResultCache.clear();
     std::pair<MemoizationMap::iterator, bool> InsertResult =
         ResultCache.insert(std::make_pair(Key, MemoizedMatchResult()));
     if (InsertResult.second) {
@@ -426,6 +424,8 @@
                                    const DynTypedMatcher &Matcher,
                                    BoundNodesTreeBuilder *Builder,
                                    BindKind Bind) {
+    if (ResultCache.size() > MaxMemoizationEntries)
+      ResultCache.clear();
     return memoizedMatchesRecursively(Node, Matcher, Builder, INT_MAX,
                                       TK_AsIs, Bind);
   }
@@ -434,6 +434,10 @@
                                  const DynTypedMatcher &Matcher,
                                  BoundNodesTreeBuilder *Builder,
                                  AncestorMatchMode MatchMode) {
+    // Reset the cache outside of the recursive call to make sure we
+    // don't invalidate any iterators.
+    if (ResultCache.size() > MaxMemoizationEntries)
+      ResultCache.clear();
     return memoizedMatchesAncestorOfRecursively(Node, Matcher, Builder,
                                                 MatchMode);
   }
@@ -498,8 +502,6 @@
     Key.MatcherID = Matcher.getID();
     Key.Node = Node;
     Key.BoundNodes = *Builder;
-    if (ResultCache.size() > MaxMemoizationEntries)
-      ResultCache.clear();
     std::pair<MemoizationMap::iterator, bool> InsertResult =
         ResultCache.insert(std::make_pair(Key, MemoizedMatchResult()));
     if (InsertResult.second) {