Commit d5dfd135 authored by Karasev Nikita's avatar Karasev Nikita Committed by Aaron Ballman
Browse files

Add TagDecl AST matcher

parent e6b55cbc
Loading
Loading
Loading
Loading
+58 −30
Original line number Diff line number Diff line
@@ -502,6 +502,20 @@ in
</pre></td></tr>


<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('tagDecl0')"><a name="tagDecl0Anchor">tagDecl</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1TagDecl.html">TagDecl</a>&gt;...</td></tr>
<tr><td colspan="4" class="doc" id="tagDecl0"><pre>Matches tag declarations.

Example matches X, Z, U, S, E
  class X;
  template&lt;class T&gt; class Z {};
  struct S {};
  union U {};
  enum E {
    A, B, C
  };
</pre></td></tr>


<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('templateTypeParmDecl0')"><a name="templateTypeParmDecl0Anchor">templateTypeParmDecl</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmDecl.html">TemplateTypeParmDecl</a>&gt;...</td></tr>
<tr><td colspan="4" class="doc" id="templateTypeParmDecl0"><pre>Matches template type parameter declarations.

@@ -3957,36 +3971,6 @@ functionDecl(hasAnyParameter(hasType(isVolatileQualified())))
</pre></td></tr>


<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1RecordDecl.html">RecordDecl</a>&gt;</td><td class="name" onclick="toggle('isClass0')"><a name="isClass0Anchor">isClass</a></td><td></td></tr>
<tr><td colspan="4" class="doc" id="isClass0"><pre>Matches RecordDecl object that are spelled with "class."

Example matches C, but not S or U.
  struct S {};
  class C {};
  union U {};
</pre></td></tr>


<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1RecordDecl.html">RecordDecl</a>&gt;</td><td class="name" onclick="toggle('isStruct0')"><a name="isStruct0Anchor">isStruct</a></td><td></td></tr>
<tr><td colspan="4" class="doc" id="isStruct0"><pre>Matches RecordDecl object that are spelled with "struct."

Example matches S, but not C or U.
  struct S {};
  class C {};
  union U {};
</pre></td></tr>


<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1RecordDecl.html">RecordDecl</a>&gt;</td><td class="name" onclick="toggle('isUnion0')"><a name="isUnion0Anchor">isUnion</a></td><td></td></tr>
<tr><td colspan="4" class="doc" id="isUnion0"><pre>Matches RecordDecl object that are spelled with "union."

Example matches U, but not C or S.
  struct S {};
  class C {};
  union U {};
</pre></td></tr>


<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('equalsBoundNode0')"><a name="equalsBoundNode0Anchor">equalsBoundNode</a></td><td>std::string ID</td></tr>
<tr><td colspan="4" class="doc" id="equalsBoundNode0"><pre>Matches if a node equals a previously bound node.

@@ -4090,6 +4074,17 @@ stringLiteral(hasSize(4))
</pre></td></tr>


<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1TagDecl.html">TagDecl</a>&gt;</td><td class="name" onclick="toggle('isClass0')"><a name="isClass0Anchor">isClass</a></td><td></td></tr>
<tr><td colspan="4" class="doc" id="isClass0"><pre>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 {};
</pre></td></tr>


<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1TagDecl.html">TagDecl</a>&gt;</td><td class="name" onclick="toggle('isDefinition0')"><a name="isDefinition0Anchor">isDefinition</a></td><td></td></tr>
<tr><td colspan="4" class="doc" id="isDefinition0"><pre>Matches if a declaration has a body attached.

@@ -4112,6 +4107,39 @@ Usable as: Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1TagD
</pre></td></tr>


<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1TagDecl.html">TagDecl</a>&gt;</td><td class="name" onclick="toggle('isEnum0')"><a name="isEnum0Anchor">isEnum</a></td><td></td></tr>
<tr><td colspan="4" class="doc" id="isEnum0"><pre>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 {};
</pre></td></tr>


<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1TagDecl.html">TagDecl</a>&gt;</td><td class="name" onclick="toggle('isStruct0')"><a name="isStruct0Anchor">isStruct</a></td><td></td></tr>
<tr><td colspan="4" class="doc" id="isStruct0"><pre>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 {};
</pre></td></tr>


<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1TagDecl.html">TagDecl</a>&gt;</td><td class="name" onclick="toggle('isUnion0')"><a name="isUnion0Anchor">isUnion</a></td><td></td></tr>
<tr><td colspan="4" class="doc" id="isUnion0"><pre>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 {};
</pre></td></tr>


<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>&gt;</td><td class="name" onclick="toggle('equalsIntegralValue0')"><a name="equalsIntegralValue0Anchor">equalsIntegralValue</a></td><td>std::string Value</td></tr>
<tr><td colspan="4" class="doc" id="equalsIntegralValue0"><pre>Matches a TemplateArgument of integral type with a given value.

+39 −9
Original line number Diff line number Diff line
@@ -1195,6 +1195,20 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, EnumDecl> enumDecl;
extern const internal::VariadicDynCastAllOfMatcher<Decl, EnumConstantDecl>
    enumConstantDecl;

/// Matches tag declarations.
///
/// Example matches X, Z, U, S, E
/// \code
///   class X;
///   template<class T> class Z {};
///   struct S {};
///   union U {};
///   enum E {
///     A, B, C
///   };
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Decl, TagDecl> 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
+1 −0
Original line number Diff line number Diff line
@@ -650,6 +650,7 @@ const internal::VariadicDynCastAllOfMatcher<Decl, CXXDestructorDecl>
const internal::VariadicDynCastAllOfMatcher<Decl, EnumDecl> enumDecl;
const internal::VariadicDynCastAllOfMatcher<Decl, EnumConstantDecl>
    enumConstantDecl;
const internal::VariadicDynCastAllOfMatcher<Decl, TagDecl> tagDecl;
const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl> cxxMethodDecl;
const internal::VariadicDynCastAllOfMatcher<Decl, CXXConversionDecl>
    cxxConversionDecl;
+1 −0
Original line number Diff line number Diff line
@@ -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);
+7 −0
Original line number Diff line number Diff line
@@ -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())));
Loading