From d5dfd1350efb80f9674db322999dd883fb36a6ad Mon Sep 17 00:00:00 2001 From: Karasev Nikita Date: Wed, 29 Jan 2020 07:57:27 -0500 Subject: [PATCH] Add TagDecl AST matcher --- clang/docs/LibASTMatchersReference.html | 88 ++++++++++++++-------- clang/include/clang/ASTMatchers/ASTMatchers.h | 48 +++++++++--- clang/lib/ASTMatchers/ASTMatchersInternal.cpp | 1 + clang/lib/ASTMatchers/Dynamic/Registry.cpp | 1 + .../ASTMatchers/ASTMatchersNarrowingTest.cpp | 7 ++ .../unittests/ASTMatchers/ASTMatchersNodeTest.cpp | 7 ++ 6 files changed, 113 insertions(+), 39 deletions(-) diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html index 837f74e..907353d 100644 --- a/clang/docs/LibASTMatchersReference.html +++ b/clang/docs/LibASTMatchersReference.html @@ -502,6 +502,20 @@ in +Matcher<Decl>tagDeclMatcher<TagDecl>... +
Matches tag declarations.
+
+Example matches X, Z, U, S, E
+  class X;
+  template<class T> class Z {};
+  struct S {};
+  union U {};
+  enum E {
+    A, B, C
+  };
+
+ + Matcher<Decl>templateTypeParmDeclMatcher<TemplateTypeParmDecl>...
Matches template type parameter declarations.
 
@@ -3957,36 +3971,6 @@ functionDecl(hasAnyParameter(hasType(isVolatileQualified())))
 
-Matcher<RecordDecl>isClass -
Matches RecordDecl object that are spelled with "class."
-
-Example matches C, but not S or U.
-  struct S {};
-  class C {};
-  union U {};
-
- - -Matcher<RecordDecl>isStruct -
Matches RecordDecl object that are spelled with "struct."
-
-Example matches S, but not C or U.
-  struct S {};
-  class C {};
-  union U {};
-
- - -Matcher<RecordDecl>isUnion -
Matches RecordDecl object that are spelled with "union."
-
-Example matches U, but not C or S.
-  struct S {};
-  class C {};
-  union U {};
-
- - Matcher<Stmt>equalsBoundNodestd::string ID
Matches if a node equals a previously bound node.
 
@@ -4090,6 +4074,17 @@ stringLiteral(hasSize(4))
 
+Matcher<TagDecl>isClass +
Matches TagDecl object that are spelled with "class."
+
+Example matches C, but not S, U or E.
+  struct S {};
+  class C {};
+  union U {};
+  enum E {};
+
+ + Matcher<TagDecl>isDefinition
Matches if a declaration has a body attached.
 
@@ -4112,6 +4107,39 @@ Usable as: Matcher<TagDecl>isEnum
+
Matches TagDecl object that are spelled with "enum."
+
+Example matches E, but not C, S or U.
+  struct S {};
+  class C {};
+  union U {};
+  enum E {};
+
+ + +Matcher<TagDecl>isStruct +
Matches TagDecl object that are spelled with "struct."
+
+Example matches S, but not C, U or E.
+  struct S {};
+  class C {};
+  union U {};
+  enum E {};
+
+ + +Matcher<TagDecl>isUnion +
Matches TagDecl object that are spelled with "union."
+
+Example matches U, but not C, S or E.
+  struct S {};
+  class C {};
+  union U {};
+  enum E {};
+
+ + Matcher<TemplateArgument>equalsIntegralValuestd::string Value
Matches a TemplateArgument of integral type with a given value.
 
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h
index ac6ce07..f105586 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -1195,6 +1195,20 @@ extern const internal::VariadicDynCastAllOfMatcher enumDecl;
 extern const internal::VariadicDynCastAllOfMatcher
     enumConstantDecl;
 
+/// Matches tag declarations.
+///
+/// Example matches X, Z, U, S, E
+/// \code
+///   class X;
+///   template class Z {};
+///   struct S {};
+///   union U {};
+///   enum E {
+///     A, B, C
+///   };
+/// \endcode
+extern const internal::VariadicDynCastAllOfMatcher tagDecl;
+
 /// Matches method declarations.
 ///
 /// Example matches y
@@ -4863,42 +4877,58 @@ AST_MATCHER_P(ImplicitCastExpr, hasImplicitDestinationType,
   return InnerMatcher.matches(Node.getType(), Finder, Builder);
 }
 
-/// Matches RecordDecl object that are spelled with "struct."
+/// Matches TagDecl object that are spelled with "struct."
 ///
-/// Example matches S, but not C or U.
+/// Example matches S, but not C, U or E.
 /// \code
 ///   struct S {};
 ///   class C {};
 ///   union U {};
+///   enum E {};
 /// \endcode
-AST_MATCHER(RecordDecl, isStruct) {
+AST_MATCHER(TagDecl, isStruct) {
   return Node.isStruct();
 }
 
-/// Matches RecordDecl object that are spelled with "union."
+/// Matches TagDecl object that are spelled with "union."
 ///
-/// Example matches U, but not C or S.
+/// Example matches U, but not C, S or E.
 /// \code
 ///   struct S {};
 ///   class C {};
 ///   union U {};
+///   enum E {};
 /// \endcode
-AST_MATCHER(RecordDecl, isUnion) {
+AST_MATCHER(TagDecl, isUnion) {
   return Node.isUnion();
 }
 
-/// Matches RecordDecl object that are spelled with "class."
+/// Matches TagDecl object that are spelled with "class."
 ///
-/// Example matches C, but not S or U.
+/// Example matches C, but not S, U or E.
 /// \code
 ///   struct S {};
 ///   class C {};
 ///   union U {};
+///   enum E {};
 /// \endcode
-AST_MATCHER(RecordDecl, isClass) {
+AST_MATCHER(TagDecl, isClass) {
   return Node.isClass();
 }
 
+/// Matches TagDecl object that are spelled with "enum."
+///
+/// Example matches E, but not C, S or U.
+/// \code
+///   struct S {};
+///   class C {};
+///   union U {};
+///   enum E {};
+/// \endcode
+AST_MATCHER(TagDecl, isEnum) {
+  return Node.isEnum();
+}
+
 /// Matches the true branch expression of a conditional operator.
 ///
 /// Example 1 (conditional ternary operator): matches a
diff --git a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
index 3631922..b09ab75 100644
--- a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -650,6 +650,7 @@ const internal::VariadicDynCastAllOfMatcher
 const internal::VariadicDynCastAllOfMatcher enumDecl;
 const internal::VariadicDynCastAllOfMatcher
     enumConstantDecl;
+const internal::VariadicDynCastAllOfMatcher tagDecl;
 const internal::VariadicDynCastAllOfMatcher cxxMethodDecl;
 const internal::VariadicDynCastAllOfMatcher
     cxxConversionDecl;
diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp
index cd3f346..4fd5abf 100644
--- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -493,6 +493,7 @@ RegistryMaps::RegistryMaps() {
   REGISTER_MATCHER(substTemplateTypeParmType);
   REGISTER_MATCHER(switchCase);
   REGISTER_MATCHER(switchStmt);
+  REGISTER_MATCHER(tagDecl);
   REGISTER_MATCHER(tagType);
   REGISTER_MATCHER(templateArgument);
   REGISTER_MATCHER(templateArgumentCountIs);
diff --git a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
index 92678a3..4796809 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -2504,6 +2504,13 @@ TEST(IsScopedEnum, MatchesScopedEnum) {
   EXPECT_TRUE(notMatches("enum X {};", enumDecl(isScoped())));
 }
 
+TEST(TagDeclKind, MatchesTagDeclKind) {
+  EXPECT_TRUE(matches("struct X {};", tagDecl(isStruct())));
+  EXPECT_TRUE(matches("class C {};", tagDecl(isClass())));
+  EXPECT_TRUE(matches("union U {};", tagDecl(isUnion())));
+  EXPECT_TRUE(matches("enum E {};", tagDecl(isEnum())));
+}
+
 TEST(HasTrailingReturn, MatchesTrailingReturn) {
   EXPECT_TRUE(matches("auto Y() -> int { return 0; }",
                       functionDecl(hasTrailingReturn())));
diff --git a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
index b37ec27..1fdaf66 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
@@ -184,6 +184,13 @@ TEST(EnumConstant, Matches) {
   EXPECT_TRUE(notMatches("enum X {};", Matcher));
 }
 
+TEST(TagDecl, MatchesTagDecls) {
+  EXPECT_TRUE(matches("struct X {};", tagDecl(hasName("X"))));
+  EXPECT_TRUE(matches("class C {};", tagDecl(hasName("C"))));
+  EXPECT_TRUE(matches("union U {};", tagDecl(hasName("U"))));
+  EXPECT_TRUE(matches("enum E {};", tagDecl(hasName("E"))));
+}
+
 TEST(Matcher, UnresolvedLookupExpr) {
   // FIXME: The test is known to be broken on Windows with delayed template
   // parsing.
-- 
2.7.4