[PATCH] D12736: [PATCH] AST traversal from types to decls

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 9 09:21:51 PDT 2015


aaron.ballman created this revision.
aaron.ballman added a reviewer: klimek.
aaron.ballman added a subscriber: cfe-commits.
Herald added a subscriber: klimek.

The AST matching code that traverses from types to decls misses a lot of possible conversions. This patch adds all of the conversions I could find. However, not all of the type->decl conversions can be used from the AST matchers yet. For instance, we do not have matcher support for ObjCInterfaceDecl. I've added a test case for the one conversion we currently support. I feel it's reasonable to have reduced test coverage for the other types at this point compared to the difficulty of tracking down why simple matchers were failing.

This now allows us to write a matcher like:

varDecl(hasType(namedDecl(hasName("Foo"))))

that matches code like:

typedef int Foo;
Foo f; // matches f

Previously, the hasType(namedDecl()) matcher would only properly match if the type queried was a TagType. Now it can support any type which is traversable to a decl.

http://reviews.llvm.org/D12736

Files:
  include/clang/ASTMatchers/ASTMatchersInternal.h
  unittests/ASTMatchers/ASTMatchersTest.cpp

Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===================================================================
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -924,6 +924,15 @@
                        varDecl(hasType(namedDecl(hasName("S"))))));
 }
 
+TEST(TypeMatcher, MatchesDeclTypes) {
+  EXPECT_TRUE(matches("typedef int I; void f(I i);",
+                      parmVarDecl(hasType(namedDecl(hasName("I"))))));
+
+  // FIXME: when we support ObjCInterfaceDecl, and TemplateTypeParmDecl, add
+  // testing code here. Explore whether we should add testing code for
+  // UnresolvedUsingType and InjectedClassNameType.
+}
+
 TEST(Matcher, BindMatchedNodes) {
   DeclarationMatcher ClassX = has(recordDecl(hasName("::X")).bind("x"));
 
Index: include/clang/ASTMatchers/ASTMatchersInternal.h
===================================================================
--- include/clang/ASTMatchers/ASTMatchersInternal.h
+++ include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -672,10 +672,22 @@
   /// matcher matches on it.
   bool matchesSpecialized(const QualType &Node, ASTMatchFinder *Finder,
                           BoundNodesTreeBuilder *Builder) const {
-    /// FIXME: Add other ways to convert...
     if (Node.isNull())
       return false;
-    return matchesDecl(Node->getAsTagDecl(), Finder, Builder);
+
+    if (auto *TD = Node->getAsTagDecl())
+      return matchesDecl(TD, Finder, Builder);
+    else if (auto *TT = Node->getAs<TypedefType>())
+      return matchesDecl(TT->getDecl(), Finder, Builder);
+    else if (auto *TTP = Node->getAs<TemplateTypeParmType>())
+      return matchesDecl(TTP->getDecl(), Finder, Builder);
+    else if (auto *OCIT = Node->getAs<ObjCInterfaceType>())
+      return matchesDecl(OCIT->getDecl(), Finder, Builder);
+    else if (auto *UUT = Node->getAs<UnresolvedUsingType>())
+      return matchesDecl(UUT->getDecl(), Finder, Builder);
+    else if (auto *ICNT = Node->getAs<InjectedClassNameType>())
+      return matchesDecl(ICNT->getDecl(), Finder, Builder);
+    return false;
   }
 
   /// \brief Gets the TemplateDecl from a TemplateSpecializationType


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D12736.34345.patch
Type: text/x-patch
Size: 2156 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150909/0f810bf8/attachment.bin>


More information about the cfe-commits mailing list