Implement descendant matchers for NestedNamespecifiers

This implements has(), hasDescendant(), forEach() and
forEachDescendant() for NestedNameSpecifier and NestedNameSpecifierLoc
matchers.

Review: http://llvm-reviews.chandlerc.com/D86

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@167017 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/ASTMatchers/ASTMatchFinder.cpp b/lib/ASTMatchers/ASTMatchFinder.cpp
index 38df2a1..b081f54 100644
--- a/lib/ASTMatchers/ASTMatchFinder.cpp
+++ b/lib/ASTMatchers/ASTMatchFinder.cpp
@@ -147,6 +147,12 @@
       traverse(*D);
     else if (const Stmt *S = DynNode.get<Stmt>())
       traverse(*S);
+    else if (const NestedNameSpecifier *NNS =
+             DynNode.get<NestedNameSpecifier>())
+      traverse(*NNS);
+    else if (const NestedNameSpecifierLoc *NNSLoc =
+             DynNode.get<NestedNameSpecifierLoc>())
+      traverse(*NNSLoc);
     else if (const QualType *Q = DynNode.get<QualType>())
       traverse(*Q);
     else if (const TypeLoc *T = DynNode.get<TypeLoc>())
@@ -197,6 +203,16 @@
     // The TypeLoc is matched inside traverse.
     return traverse(TypeLocNode);
   }
+  bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS) {
+    ScopedIncrement ScopedDepth(&CurrentDepth);
+    return (NNS == NULL) || traverse(*NNS);
+  }
+  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
+    ScopedIncrement ScopedDepth(&CurrentDepth);
+    if (!match(*NNS.getNestedNameSpecifier()))
+      return false;
+    return !NNS || traverse(NNS);
+  }
 
   bool shouldVisitTemplateInstantiations() const { return true; }
   bool shouldVisitImplicitCode() const { return true; }
@@ -231,6 +247,13 @@
   bool baseTraverse(TypeLoc TypeLocNode) {
     return VisitorBase::TraverseTypeLoc(TypeLocNode);
   }
+  bool baseTraverse(const NestedNameSpecifier &NNS) {
+    return VisitorBase::TraverseNestedNameSpecifier(
+        const_cast<NestedNameSpecifier*>(&NNS));
+  }
+  bool baseTraverse(NestedNameSpecifierLoc NNS) {
+    return VisitorBase::TraverseNestedNameSpecifierLoc(NNS);
+  }
 
   // Sets 'Matched' to true if 'Matcher' matches 'Node' and:
   //   0 < CurrentDepth <= MaxDepth.