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
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
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits