[PATCH] D24361: hasDeclaration(qualType(...)) matcher should unwrap ElaboratedType and TemplateSpecializationType
Ćukasz Anforowicz via cfe-commits
cfe-commits at lists.llvm.org
Fri Sep 16 17:34:08 PDT 2016
lukasza added a comment.
Richard, could you please take a look?
================
Comment at: include/clang/ASTMatchers/ASTMatchersInternal.h:750
@@ +749,3 @@
+ else if (auto *ET = Node->getAs<ElaboratedType>())
+ return matchesSpecialized(ET->getNamedType(), Finder, Builder);
+ else if (auto *TST = Node->getAs<TemplateSpecializationType>())
----------------
There is also a question whether I should not only start supporting not only qualType(hasDeclaration(...)) when qualType wraps an ElaboratedType node, but also start supporting elaboratedType(hasDeclaration(...)).
Snippets of a patch that could achieve this (but then again - I am not sure if this is desirable and/or necessary):
+++ include/clang/ASTMatchers/ASTMatchersInternal.h (working copy)
...
+ /// \brief Gets the QualType from ElaboratedType
+ /// and returns whether the inner matches on it.
+ bool matchesSpecialized(const ElaboratedType &Node,
+ ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const {
+ return matchesSpecialized(Node.getNamedType(), Finder, Builder);
+ }
+
...
/// \brief All types that are supported by HasDeclarationMatcher above.
-typedef TypeList<CallExpr, CXXConstructExpr, DeclRefExpr, EnumType,
- InjectedClassNameType, LabelStmt, AddrLabelExpr, MemberExpr,
- QualType, RecordType, TagType, TemplateSpecializationType,
- TemplateTypeParmType, TypedefType,
+typedef TypeList<AutoType, CallExpr, CXXConstructExpr, DeclRefExpr, ElaboratedType,
+ EnumType, InjectedClassNameType, LabelStmt, AddrLabelExpr,
+ MemberExpr, QualType, RecordType, TagType,
+ TemplateSpecializationType, TemplateTypeParmType, TypedefType,
UnresolvedUsingType> HasDeclarationSupportedTypes;
================
Comment at: include/clang/ASTMatchers/ASTMatchersInternal.h:753
@@ -749,2 +752,3 @@
+ return matchesSpecialized(*TST, Finder, Builder);
else if (auto *TT = Node->getAs<TypedefType>())
return matchesDecl(TT->getDecl(), Finder, Builder);
----------------
I do notice that there are quite a few similar Node->getAs<T> if statements here. They could be replaced with something "clever" (and probably unreadable):
+++ include/clang/ASTMatchers/ASTMatchersInternal.h (working copy)
...
+ /// \brief Terminating case for recursion over template parameters
+ /// performed by matchesQualTypeAsAnyOf template.
+ template <typename U>
+ bool matchesQualTypeAsAnyOf(const QualType &Node, ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const {
+ return false;
+ }
+
+ /// \brief Returns true if Node->getAs<U> is not null and matches inner
+ /// matcher for any type U listed in template parameters.
+ template <typename U, typename... UTail,
+ typename std::enable_if<!std::is_void<U>::value, int>::type = 0>
+ bool matchesQualTypeAsAnyOf(const QualType &Node, ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const {
+ if (const U *u = Node->getAs<U>())
+ return matchesSpecialized(*u, Finder, Builder);
+
+ return matchesQualTypeAsAnyOf<UTail...>(Node, 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;
+ else if (auto *TD = Node->getAsTagDecl())
+ return matchesDecl(TD, Finder, Builder);
+
+ return matchesQualTypeAsAnyOf<
+ ArrayType, InjectedClassNameType, ObjCInterfaceType, TemplateSpecializationType,
+ TypedefType, UnresolvedUsingType, void>(
+ Node, Finder, Builder);
================
Comment at: unittests/ASTMatchers/ASTMatchersTraversalTest.cpp:2124
@@ +2123,3 @@
+ // hasDeclaration should see through:
+ // 1. from ElaboratedType (Namespace::MyTemplate<U>) to
+ // TemplateSpecializationType (MyTemplate<U>)
----------------
FWIW, I couldn't repro a similar issue (i.e. VarDecl or ParmVarDecl of a type with user-provided declaration, but where hasDeclaration doesn't match *anything*) for other types (i.e. AutoType or ArrayType) - only for ElaboratedType and TemplateSpecializationType.
https://reviews.llvm.org/D24361
More information about the cfe-commits
mailing list