[PATCH] Add TemplateSpecializationType polymorphism for hasTemplateArgument and hasAnyTemplateArgument, and (out of necessity) a refersToExpr matcher.

Richard Smith richard at metafoo.co.uk
Wed Feb 19 13:14:37 PST 2014

  `hasAnyTemplateArgument` still seems to miss some cases of explicitly-written template arguments.

Comment at: include/clang/AST/TemplateBase.h:63-66
@@ -62,4 +62,6 @@
-    /// 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*.
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).

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 {
This list is still incomplete. Maybe just "Represents a template argument."?

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();
+    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,
What about the template argument list in a DeclRefExpr (for either a function template specialization or a variable template specialization)?

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.
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?


More information about the cfe-commits mailing list