lukasza updated the summary for this revision.
lukasza updated this revision to Diff 70483.
lukasza added a comment.

Addressing CR feedbackfrom rsmith@.


https://reviews.llvm.org/D24268

Files:
  include/clang/AST/RecursiveASTVisitor.h
  unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Index: unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===================================================================
--- unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -641,6 +641,89 @@
     functionDecl(hasAnyTemplateArgument(templateArgument()))));
 }
 
+TEST(TemplateTypeParmDecl, CXXMethodDecl) {
+  const char input[] =
+      "template<typename T>\n"
+      "class Class {\n"
+      "  void method();\n"
+      "};\n"
+      "template<typename U>\n"
+      "void Class<U>::method() {}\n";
+  EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T"))));
+  EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U"))));
+}
+
+TEST(TemplateTypeParmDecl, VarDecl) {
+  const char input[] =
+      "template<typename T>\n"
+      "class Class {\n"
+      "  static T pi;\n"
+      "};\n"
+      "template<typename U>\n"
+      "U Class<U>::pi = U(3.1415926535897932385);\n";
+  EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T"))));
+  EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U"))));
+}
+
+TEST(TemplateTypeParmDecl, VarTemplatePartialSpecializationDecl) {
+  const char input[] =
+      "template<typename T>\n"
+      "struct Struct {\n"
+      "  template<typename T2> static int field;\n"
+      "};\n"
+      "template<typename U>\n"
+      "template<typename U2>\n"
+      "int Struct<U>::field<char> = 123;\n";
+  EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T"))));
+  EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T2"))));
+  EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U"))));
+  EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U2"))));
+}
+
+TEST(TemplateTypeParmDecl, ClassTemplatePartialSpecializationDecl) {
+  const char input[] =
+      "template<typename T>\n"
+      "class Class {\n"
+      "  template<typename T2> struct Struct;\n"
+      "};\n"
+      "template<typename U>\n"
+      "template<typename U2>\n"
+      "struct Class<U>::Struct<int> {};\n";
+  EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T"))));
+  EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T2"))));
+  EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U"))));
+  EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U2"))));
+}
+
+TEST(TemplateTypeParmDecl, EnumDecl) {
+  const char input[] =
+      "template<typename T>\n"
+      "struct Struct {\n"
+      "  enum class Enum : T;\n"
+      "};\n"
+      "template<typename U>\n"
+      "enum class Struct<U>::Enum : U {\n"
+      "  e1,\n"
+      "  e2\n"
+      "};\n";
+  EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T"))));
+  EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U"))));
+}
+
+TEST(TemplateTypeParmDecl, RecordDecl) {
+  const char input[] =
+      "template<typename T>\n"
+      "class Class {\n"
+      "  struct Struct;\n"
+      "};\n"
+      "template<typename U>\n"
+      "struct Class<U>::Struct {\n"
+      "  U field;\n"
+      "};\n";
+  EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T"))));
+  EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U"))));
+}
+
 TEST(RefersToIntegralType, Matches) {
   EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",
                       classTemplateSpecializationDecl(
Index: include/clang/AST/RecursiveASTVisitor.h
===================================================================
--- include/clang/AST/RecursiveASTVisitor.h
+++ include/clang/AST/RecursiveASTVisitor.h
@@ -482,6 +482,11 @@
 private:
   // These are helper methods used by more than one Traverse* method.
   bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL);
+
+  // Traverses template parameter lists of either a DeclaratorDecl or TagDecl.
+  template <typename T>
+  bool TraverseDeclTemplateParameterLists(T *D);
+
 #define DEF_TRAVERSE_TMPL_INST(TMPLDECLKIND)                                   \
   bool TraverseTemplateInstantiations(TMPLDECLKIND##TemplateDecl *D);
   DEF_TRAVERSE_TMPL_INST(Class)
@@ -1532,6 +1537,16 @@
 }
 
 template <typename Derived>
+template <typename T>
+bool RecursiveASTVisitor<Derived>::TraverseDeclTemplateParameterLists(T *D) {
+  for (unsigned i = 0; i < D->getNumTemplateParameterLists(); i++) {
+    TemplateParameterList *TPL = D->getTemplateParameterList(i);
+    TraverseTemplateParameterListHelper(TPL);
+  }
+  return true;
+}
+
+template <typename Derived>
 bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
     ClassTemplateDecl *D) {
   for (auto *SD : D->specializations()) {
@@ -1692,6 +1707,8 @@
 })
 
 DEF_TRAVERSE_DECL(EnumDecl, {
+  TRY_TO(TraverseDeclTemplateParameterLists(D));
+
   if (D->getTypeForDecl())
     TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
 
@@ -1706,6 +1723,7 @@
   // We shouldn't traverse D->getTypeForDecl(); it's a result of
   // declaring the type, not something that was written in the source.
 
+  TRY_TO(TraverseDeclTemplateParameterLists(D));
   TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
   return true;
 }
@@ -1800,6 +1818,7 @@
 
 template <typename Derived>
 bool RecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) {
+  TRY_TO(TraverseDeclTemplateParameterLists(D));
   TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
   if (D->getTypeSourceInfo())
     TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
@@ -1846,6 +1865,7 @@
 
 template <typename Derived>
 bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
+  TRY_TO(TraverseDeclTemplateParameterLists(D));
   TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
   TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to