]> granicus.if.org Git - clang/commitdiff
[clang] Add AST matcher for initializer list members
authorHyrum Wright <hwright@google.com>
Mon, 7 Jan 2019 14:14:36 +0000 (14:14 +0000)
committerHyrum Wright <hwright@google.com>
Mon, 7 Jan 2019 14:14:36 +0000 (14:14 +0000)
Summary:
Much like hasArg for various call expressions, this allows LibTooling users to
match against a member of an initializer list.

This is currently being used as part of the abseil-duration-scale clang-tidy
check.

Differential Revision: https://reviews.llvm.org/D56090

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350523 91177308-0d34-0410-b5e6-96231b3b80d8

docs/LibASTMatchersReference.html
include/clang/ASTMatchers/ASTMatchers.h
lib/ASTMatchers/Dynamic/Registry.cpp
unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp

index 27cb00b6bdfc2f2ac6d5f67cac765939a3dca090..2af0a7c9e33dd48325b186dfcac664c2dc322e19 100644 (file)
@@ -718,7 +718,7 @@ Example matches a || b
 
 
 <tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('blockExpr0')"><a name="blockExpr0Anchor">blockExpr</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1BlockExpr.html">BlockExpr</a>&gt;...</td></tr>
-<tr><td colspan="4" class="doc" id="blockExpr0"><pre>MAtches a reference to a block.
+<tr><td colspan="4" class="doc" id="blockExpr0"><pre>Matches a reference to a block.
 
 Example: matches "^{}":
   void f() { ^{}(); }
@@ -5866,6 +5866,15 @@ FIXME: Unit test this matcher
 </pre></td></tr>
 
 
+<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1InitListExpr.html">InitListExpr</a>&gt;</td><td class="name" onclick="toggle('hasInit0')"><a name="hasInit0Anchor">hasInit</a></td><td>unsigned N, ast_matchers::Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasInit0"><pre>Matches the n'th item of an initializer list expression.
+
+Example matches y.
+    (matcher = initListExpr(hasInit(0, expr())))
+  int x{y}.
+</pre></td></tr>
+
+
 <tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1InitListExpr.html">InitListExpr</a>&gt;</td><td class="name" onclick="toggle('hasSyntacticForm0')"><a name="hasSyntacticForm0Anchor">hasSyntacticForm</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
 <tr><td colspan="4" class="doc" id="hasSyntacticForm0"><pre>Matches the syntactic form of init list expressions
 (if expression have it).
index 7e35f0667aae16312bd84b06717e25c8df533083..5cdb964a92c29a755a1fffa4821f4ea7a8fd0432 100644 (file)
@@ -3514,6 +3514,19 @@ AST_POLYMORPHIC_MATCHER_P2(hasArgument,
               *Node.getArg(N)->IgnoreParenImpCasts(), Finder, Builder));
 }
 
+/// Matches the n'th item of an initializer list expression.
+///
+/// Example matches y.
+///     (matcher = initListExpr(hasInit(0, expr())))
+/// \code
+///   int x{y}.
+/// \endcode
+AST_MATCHER_P2(InitListExpr, hasInit, unsigned, N,
+               ast_matchers::internal::Matcher<Expr>, InnerMatcher) {
+  return N < Node.getNumInits() &&
+          InnerMatcher.matches(*Node.getInit(N), Finder, Builder);
+}
+
 /// Matches declaration statements that contain a specific number of
 /// declarations.
 ///
index 0bef326ca5e5b08ff7078cc765de4bbaacaaba3b..e6e48467967e19c5f56800e329bbb25c1e392685 100644 (file)
@@ -273,6 +273,7 @@ RegistryMaps::RegistryMaps() {
   REGISTER_MATCHER(hasInClassInitializer);
   REGISTER_MATCHER(hasIncrement);
   REGISTER_MATCHER(hasIndex);
+  REGISTER_MATCHER(hasInit);
   REGISTER_MATCHER(hasInitializer);
   REGISTER_MATCHER(hasKeywordSelector);
   REGISTER_MATCHER(hasLHS);
index d1f9495432218445b0f61a1a8094e205bd330893..fb17d100c518acbac4f09aff4e7415cbc332c038 100644 (file)
@@ -2255,6 +2255,18 @@ TEST(IsAssignmentOperator, Basic) {
       notMatches("void x() { int a; if(a == 0) return; }", BinAsgmtOperator));
 }
 
+TEST(HasInit, Basic) {
+  EXPECT_TRUE(
+    matches("int x{0};",
+            initListExpr(hasInit(0, expr()))));
+  EXPECT_FALSE(
+    matches("int x{0};",
+            initListExpr(hasInit(1, expr()))));
+  EXPECT_FALSE(
+    matches("int x;",
+            initListExpr(hasInit(0, expr()))));
+}
+
 TEST(Matcher, isMain) {
   EXPECT_TRUE(
     matches("int main() {}", functionDecl(isMain())));