[PATCH] Add TemplateSpecializationType polymorphism for hasTemplateArgument and hasAnyTemplateArgument, and (out of necessity) a refersToExpr matcher.
Peter Collingbourne
peter at pcc.me.uk
Wed Feb 19 17:41:29 PST 2014
================
Comment at: include/clang/ASTMatchers/ASTMatchers.h:338-345
@@ -325,7 +337,10 @@
/// matches the specialization \c A<int>
-AST_MATCHER_P(ClassTemplateSpecializationDecl, hasAnyTemplateArgument,
- internal::Matcher<TemplateArgument>, InnerMatcher) {
- llvm::ArrayRef<TemplateArgument> List = Node.getTemplateArgs().asArray();
+AST_POLYMORPHIC_MATCHER_P(
+ hasAnyTemplateArgument,
+ AST_POLYMORPHIC_SUPPORTED_TYPES_2(ClassTemplateSpecializationDecl,
+ TemplateSpecializationType),
+ internal::Matcher<TemplateArgument>, InnerMatcher) {
+ llvm::ArrayRef<TemplateArgument> List = getTemplateSpecializationArgs(Node);
return matchesFirstInRange(InnerMatcher, List.begin(), List.end(), Finder,
Builder);
}
----------------
Richard Smith wrote:
> What about the template argument list in a DeclRefExpr (for either a function template specialization or a variable template specialization)?
Yes, these should probably be accessible via this matcher, eventually. (It seems a little tricky to do right now because they store arrays of TemplateArgumentLocs rather than TemplateArguments. We might want to expose TemplateArgumentLoc to matcher clients when we do this.)
================
Comment at: include/clang/AST/TemplateBase.h:37-38
@@ -36,4 +36,4 @@
/// \brief Represents a template argument within a class template
-/// specialization.
+/// specialization or a template specialization type.
class TemplateArgument {
----------------
Richard Smith wrote:
> This list is still incomplete. Maybe just "Represents a template argument."?
Done.
================
Comment at: include/clang/AST/TemplateBase.h:63-66
@@ -62,4 +62,6 @@
TemplateExpansion,
- /// The template argument is a value- or type-dependent expression or a
- /// non-dependent __uuidof expression stored in an Expr*.
+ /// If owned by a template specialization type, the template argument is any
+ /// expression. Otherwise, the template argument is a value- or
+ /// type-dependent expression or a non-dependent __uuidof expression stored
+ /// in an Expr*.
Expression,
----------------
Richard Smith wrote:
> I'd prefer for us to say something a bit more general here:
>
> The template argument is an expression, and we've not resolved it
> to one of the above forms yet, either because it's dependent or
> because we're representing a non-canonical template argument
> (for instance, in a TemplateSpecializationType). Also used to
> represent a non-dependent __uuidof expression (a Microsoft extension).
Done. Substituted "other" for "above" since I guess it could also be a pack expansion, right?
================
Comment at: include/clang/ASTMatchers/ASTMatchers.h:326-327
@@ -314,3 +325,4 @@
+
/// \brief Matches classTemplateSpecializations that have at least one
/// TemplateArgument matching the given InnerMatcher.
///
----------------
Richard Smith wrote:
> What about default arguments? For `hasAnyTemplateArgument(isInt)`:
>
> template<typename T = int> // match here? (I assume yes)
> struct S {};
>
> S<> s; // match here? (I assume no)
>
> What about deduced arguments:
>
> template<typename T> void f(T);
> f<int>(); // match here? (yes?)
> f<>(0); // match here? (no?)
> f(0); // match here? (no?)
>
> In the above case, do we match the implicit instantiations of the function template?
My intuition is that a separate set of matchers should be provided for default template arguments (maybe something with "default" in the name) if only for the sake of readability.
As for deduced arguments, I don't think we need to provide them as properties of the expression. They can be retrieved from the declaration easily enough by following the reference if needed.
http://llvm-reviews.chandlerc.com/D2810
More information about the cfe-commits
mailing list