Add hasInClassInitializer matcher

Julian Bangert via cfe-commits cfe-commits at lists.llvm.org
Wed Mar 2 13:14:09 PST 2016


Here is a patch to SVN with the requested changes (documentation, renamed
and added to registry):

Index: docs/LibASTMatchersReference.html
===================================================================
--- docs/LibASTMatchersReference.html (revision 262512)
+++ docs/LibASTMatchersReference.html (working copy)
@@ -2412,7 +2412,7 @@
 </pre></td></tr>


-<tr><td>Matcher<<a href="
http://clang.llvm.org/doxygen/classclang_1_1NamedDecl.html">NamedDecl</a>></td><td
class="name" onclick="toggle('hasName0')"><a
name="hasName0Anchor">hasName</a></td><td>std::string Name</td></tr>
+<tr><td>Matcher<<a href="
http://clang.llvm.org/doxygen/classclang_1_1NamedDecl.html">NamedDecl</a>></td><td
class="name" onclick="toggle('hasName0')"><a
name="hasName0Anchor">hasName</a></td><td>std::string  Name</td></tr>
 <tr><td colspan="4" class="doc" id="hasName0"><pre>Matches NamedDecl nodes
that have the specified name.

 Supports specifying enclosing namespaces or classes by prefixing the name
@@ -3107,7 +3107,7 @@

 This matcher is only provided as a performance optimization of hasName.
     hasAnyName(a, b, c)
- is equivalent but faster than
+ is equivalent to, but faster than
     anyOf(hasName(a), hasName(b), hasName(c))
 </pre></td></tr>

@@ -4180,6 +4180,16 @@
 </pre></td></tr>


+<tr><td>Matcher<<a href="
http://clang.llvm.org/doxygen/classclang_1_1FieldDecl.html">FieldDecl</a>></td><td
class="name" onclick="toggle('hasDefaultMemberInitializer0')"><a
name="hasDefaultMemberInitializer0Anchor">hasDefaultMemberInitializer</a></td><td>Matcher<<a
href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>>
InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc"
id="hasDefaultMemberInitializer0"><pre>Matches a C++ default member
initializer matching the given matcher
+
+Given:
+  class A { int x = 1; };
+
+hasDefaultMemberInitializer(integerLiteral()) matches int x = 1
+</pre></td></tr>
+
+
 <tr><td>Matcher<<a href="
http://clang.llvm.org/doxygen/classclang_1_1ForStmt.html">ForStmt</a>></td><td
class="name" onclick="toggle('hasBody1')"><a
name="hasBody1Anchor">hasBody</a></td><td>Matcher<<a href="
http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>>
InnerMatcher</td></tr>
 <tr><td colspan="4" class="doc" id="hasBody1"><pre>Matches a 'for',
'while', 'do while' statement or a function
 definition that has a given body.
Index: include/clang/ASTMatchers/ASTMatchers.h
===================================================================
--- include/clang/ASTMatchers/ASTMatchers.h (revision 262512)
+++ include/clang/ASTMatchers/ASTMatchers.h (working copy)
@@ -2848,6 +2848,20 @@
   return Node.isMemberInitializer();
 }

+/// \brief Matches a C++ default member initializer matching the given
matcher
+///
+/// Given:
+/// \code
+///   class A { int x = 1; };
+/// \endcode
+///
+/// \c hasDefaultMemberInitializer(integerLiteral()) matches int x = 1
+AST_MATCHER_P(FieldDecl, hasDefaultMemberInitializer,
+              internal::Matcher<Expr>, InnerMatcher) {
+  return Node.hasInClassInitializer()
+      && InnerMatcher.matches(*Node.getInClassInitializer(), Finder,
Builder);
+}
+
 /// \brief Matches any argument of a call expression or a constructor call
 /// expression.
 ///
Index: lib/ASTMatchers/Dynamic/Registry.cpp
===================================================================
--- lib/ASTMatchers/Dynamic/Registry.cpp (revision 262512)
+++ lib/ASTMatchers/Dynamic/Registry.cpp (working copy)
@@ -210,6 +210,7 @@
   REGISTER_MATCHER(hasDeclaration);
   REGISTER_MATCHER(hasDeclContext);
   REGISTER_MATCHER(hasDeducedType);
+  REGISTER_MATCHER(hasDefaultMemberInitializer);
   REGISTER_MATCHER(hasDescendant);
   REGISTER_MATCHER(hasDestinationType);
   REGISTER_MATCHER(hasEitherOperand);
Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===================================================================
--- unittests/ASTMatchers/ASTMatchersTest.cpp (revision 262512)
+++ unittests/ASTMatchers/ASTMatchersTest.cpp (working copy)
@@ -2402,6 +2402,13 @@
     hasName("E")))));
 }

+TEST(Matcher, inDefaultMemberInitializer) {
+  EXPECT_TRUE(matches("class A{ int x = 1; };",
+
 fieldDecl(hasDefaultMemberInitializer(integerLiteral()))));
+  EXPECT_TRUE(notMatches("class A{ int x; void b() { x = 1; } };",
+
fieldDecl(hasDefaultMemberInitializer(integerLiteral()))));
+}
+
 TEST(Matcher, NewExpression) {
   StatementMatcher New = cxxNewExpr();



On Wed, Mar 2, 2016 at 12:23 PM Richard Smith <richard at metafoo.co.uk> wrote:

> On Wed, Mar 2, 2016 at 12:06 PM, Aaron Ballman via cfe-commits
> <cfe-commits at lists.llvm.org> wrote:
> > On Wed, Mar 2, 2016 at 2:01 PM, Julian Bangert via cfe-commits
> > <cfe-commits at lists.llvm.org> wrote:
> >> This adds a matcher for C++ in Class initializers.
> >>
> >> ---
> >>  include/clang/ASTMatchers/ASTMatchers.h   | 14 ++++++++++++++
> >>  unittests/ASTMatchers/ASTMatchersTest.cpp |  7 +++++++
> >>  2 files changed, 21 insertions(+)
> >>
> >> diff --git a/include/clang/ASTMatchers/ASTMatchers.h
> >> b/include/clang/ASTMatchers/ASTMatchers.h
> >
> > Please also generate the AST matcher documentation by running
> > dump-ast-matchers.py and register the function in Registry.cpp. Also,
> > if you can provide an svn patch instead of a git patch, it would be
> > appreciated (especially if you need someone to commit on your behalf).
>
> Please also name this "hasDefaultMemberInitializer" to match the C++
> standard's (fairly new) name for this feature. We'll rename Clang's
> internals to match at some point soon.
>
> >> index 21a4969..6b0a5d6 100644
> >> --- a/include/clang/ASTMatchers/ASTMatchers.h
> >> +++ b/include/clang/ASTMatchers/ASTMatchers.h
> >> @@ -2848,6 +2848,20 @@ AST_MATCHER(CXXCtorInitializer,
> isMemberInitializer)
> >> {
> >>    return Node.isMemberInitializer();
> >>  }
> >>
> >> +/// \brief Matches a C++ inClassInitializer matching the given matcher
> >> +///
> >> +/// Given:
> >> +/// \code
> >> +///   class A { int x = 1; };
> >> +/// \endcode
> >> +///
> >> +/// \c hasInClassInitializer(integerLiteral()) matches int x = 1
> >> +AST_MATCHER_P(FieldDecl, hasInClassInitializer,
> >> +              internal::Matcher<Expr>, InnerMatcher) {
> >> +  return Node.hasInClassInitializer()
> >> +      && InnerMatcher.matches(*Node.getInClassInitializer(), Finder,
> >> Builder);
> >> +}
> >> +
> >>  /// \brief Matches any argument of a call expression or a constructor
> call
> >>  /// expression.
> >>  ///
> >> diff --git a/unittests/ASTMatchers/ASTMatchersTest.cpp
> >> b/unittests/ASTMatchers/ASTMatchersTest.cpp
> >> index 133dc70..15776d7 100644
> >> --- a/unittests/ASTMatchers/ASTMatchersTest.cpp
> >> +++ b/unittests/ASTMatchers/ASTMatchersTest.cpp
> >> @@ -2402,6 +2402,13 @@ TEST(HasAnyConstructorInitializer,
> IsBaseInitializer)
> >> {
> >>      hasName("E")))));
> >>  }
> >>
> >> +TEST(Matcher, inClassInitializer) {
> >> +  EXPECT_TRUE(matches("class A{ int x = 1; };",
> >> +
> fieldDecl(hasInClassInitializer(integerLiteral()))));
> >> +  EXPECT_FALSE(matches("class A{ int x; void b() { x = 1; } };",
> >
> > This should use EXPECT_TRUE and notMatches.
> >
> > ~Aaron
> >
> >> +
> >> fieldDecl(hasInClassInitializer(integerLiteral()))));
> >> +}
> >> +
> >>  TEST(Matcher, NewExpression) {
> >>    StatementMatcher New = cxxNewExpr();
> >>
> >>
> >> _______________________________________________
> >> cfe-commits mailing list
> >> cfe-commits at lists.llvm.org
> >> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
> >>
> > _______________________________________________
> > cfe-commits mailing list
> > cfe-commits at lists.llvm.org
> > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160302/0a480cfa/attachment-0001.html>


More information about the cfe-commits mailing list