diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html --- a/clang/docs/LibASTMatchersReference.html +++ b/clang/docs/LibASTMatchersReference.html @@ -5446,6 +5446,20 @@ +Matcher<VarDecl>isDirectInit +
Matches a variable initializer that is a direct-initializer.
+
+Example matches i2 and i2, but not i1 or i4
+(matcher = varDecl(isStaticLocal()))
+void f() {
+  int i1 = 3;
+  int i2(3);
+  int i3{3};
+  int i4;
+}
+
+ + Matcher<VarDecl>isExceptionVariable
Matches a variable declaration that is an exception variable from
 a C++ catch block, or an Objective-C statement.
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -156,7 +156,8 @@
 AST Matchers
 ------------
 
-- ...
+- `isDirectInit` matches variables that are direct-initialized (`int i2(3);`,
+  but not `int i1 = 3;`).
 
 clang-format
 ------------
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -4114,6 +4114,22 @@
           InnerMatcher.matches(*Initializer, Finder, Builder));
 }
 
+/// \brief Matches a variable initializer that is a direct-initializer.
+///
+/// Example matches i2 and i2, but not i1 or i4
+/// (matcher = varDecl(isStaticLocal()))
+/// \code
+/// void f() {
+///   int i1 = 3;
+///   int i2(3);
+///   int i3{3};
+///   int i4;
+/// }
+/// \endcode
+AST_MATCHER(VarDecl, isDirectInit) {
+  return Node.isDirectInit();
+}
+
 /// \brief Matches a static variable with local scope.
 ///
 /// Example matches y (matcher = varDecl(isStaticLocal()))
diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp
--- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -391,6 +391,7 @@
   REGISTER_MATCHER(isDefinition);
   REGISTER_MATCHER(isDelegatingConstructor);
   REGISTER_MATCHER(isDeleted);
+  REGISTER_MATCHER(isDirectInit);
   REGISTER_MATCHER(isEnum);
   REGISTER_MATCHER(isExceptionVariable);
   REGISTER_MATCHER(isExpandedFromMacro);
diff --git a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
--- a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -1439,6 +1439,20 @@
   EXPECT_TRUE(notMatches("int X;", M));
 }
 
+TEST_P(ASTMatchersTest, IsDirectInit) {
+  auto M = varDecl(isDirectInit());
+  EXPECT_TRUE(notMatches("int i1 = 3;", M));
+  if (!GetParam().isCXX()) {
+    return;
+  }
+  EXPECT_TRUE(matches("int i2(3);", M));
+  if (!GetParam().isCXX11OrLater()) {
+    return;
+  }
+  EXPECT_TRUE(matches("int i3{3};", M));
+  EXPECT_TRUE(notMatches("int i4;", M));
+}
+
 TEST_P(ASTMatchersTest, StorageDuration) {
   StringRef T =
       "void f() { int x; static int y; } int a;static int b;extern int c;";