Index: clang/docs/LibASTMatchersReference.html =================================================================== --- clang/docs/LibASTMatchersReference.html +++ clang/docs/LibASTMatchersReference.html @@ -682,6 +682,15 @@ +Matcher<Decl>conceptDeclMatcher<ConceptDecl>... +
Matches concept declarations.
+
+Example matches integral
+  template<typename T>
+  concept integral = std::is_integral_v<T>;
+
+ + Matcher<Decl>cxxConstructorDeclMatcher<CXXConstructorDecl>...
Matches C++ constructor declarations.
 
@@ -1455,6 +1464,16 @@
 
+Matcher<Stmt>coroutineBodyStmtMatcher<CoroutineBodyStmt>... +
Matches coroutine body statements.
+
+coroutineBodyStmt() matches the coroutine below
+  generator<int> gen() {
+    co_return;
+  }
+
+ + Matcher<Stmt>coyieldExprMatcher<CoyieldExpr>...
Matches co_yield expressions.
 
@@ -3037,10 +3056,11 @@
 
 
 Matcher<CXXConstructExpr>argumentCountAtLeastunsigned N
-
Checks that a call expression or a constructor call expression has
-at least the specified number of arguments (including absent default arguments).
+
Checks that a call expression or a constructor call expression has at least
+the specified number of arguments (including absent default arguments).
 
-Example matches f(0, 0) and g(0, 0, 0) (matcher = callExpr(argumentCountAtLeast(2)))
+Example matches f(0, 0) and g(0, 0, 0)
+(matcher = callExpr(argumentCountAtLeast(2)))
   void f(int x, int y);
   void g(int x, int y, int z);
   f(0, 0);
@@ -3706,10 +3726,11 @@
 
 
 Matcher<CXXUnresolvedConstructExpr>argumentCountAtLeastunsigned N
-
Checks that a call expression or a constructor call expression has
-at least the specified number of arguments (including absent default arguments).
+
Checks that a call expression or a constructor call expression has at least
+the specified number of arguments (including absent default arguments).
 
-Example matches f(0, 0) and g(0, 0, 0) (matcher = callExpr(argumentCountAtLeast(2)))
+Example matches f(0, 0) and g(0, 0, 0)
+(matcher = callExpr(argumentCountAtLeast(2)))
   void f(int x, int y);
   void g(int x, int y, int z);
   f(0, 0);
@@ -3728,10 +3749,11 @@
 
 
 Matcher<CallExpr>argumentCountAtLeastunsigned N
-
Checks that a call expression or a constructor call expression has
-at least the specified number of arguments (including absent default arguments).
+
Checks that a call expression or a constructor call expression has at least
+the specified number of arguments (including absent default arguments).
 
-Example matches f(0, 0) and g(0, 0, 0) (matcher = callExpr(argumentCountAtLeast(2)))
+Example matches f(0, 0) and g(0, 0, 0)
+(matcher = callExpr(argumentCountAtLeast(2)))
   void f(int x, int y);
   void g(int x, int y, int z);
   f(0, 0);
@@ -4897,10 +4919,11 @@
 
 
 Matcher<ObjCMessageExpr>argumentCountAtLeastunsigned N
-
Checks that a call expression or a constructor call expression has
-at least the specified number of arguments (including absent default arguments).
+
Checks that a call expression or a constructor call expression has at least
+the specified number of arguments (including absent default arguments).
 
-Example matches f(0, 0) and g(0, 0, 0) (matcher = callExpr(argumentCountAtLeast(2)))
+Example matches f(0, 0) and g(0, 0, 0)
+(matcher = callExpr(argumentCountAtLeast(2)))
   void f(int x, int y);
   void g(int x, int y, int z);
   f(0, 0);
@@ -6795,9 +6818,10 @@
 
 
 Matcher<CXXForRangeStmt>hasBodyMatcher<Stmt> InnerMatcher
-
Matches a 'for', 'while', 'do' statement or a function definition that has
-a given body. Note that in case of functions this matcher only matches the
-definition itself and not the other declarations of the same function.
+
Matches a 'for', 'while', 'while' statement or a function or coroutine
+definition that has a given body. Note that in case of functions or
+coroutines this matcher only matches the definition itself and not the
+other declarations of the same function or coroutine.
 
 Given
   for (;;) {}
@@ -7682,6 +7706,30 @@
 
+Matcher<CoroutineBodyStmt>hasBodyMatcher<Stmt> InnerMatcher +
Matches a 'for', 'while', 'while' statement or a function or coroutine
+definition that has a given body. Note that in case of functions or
+coroutines this matcher only matches the definition itself and not the
+other declarations of the same function or coroutine.
+
+Given
+  for (;;) {}
+forStmt(hasBody(compoundStmt()))
+  matches 'for (;;) {}'
+with compoundStmt()
+  matching '{}'
+
+Given
+  void f();
+  void f() {}
+functionDecl(hasBody(compoundStmt()))
+  matches 'void f() {}'
+with compoundStmt()
+  matching '{}'
+  but does not match 'void f();'
+
+ + Matcher<DecayedType>hasDecayedTypeMatcher<QualType> InnerType
Matches the decayed type, whoes decayed type matches InnerMatcher
 
@@ -7890,9 +7938,10 @@ Matcher<DoStmt>hasBodyMatcher<Stmt> InnerMatcher -
Matches a 'for', 'while', 'do' statement or a function definition that has
-a given body. Note that in case of functions this matcher only matches the
-definition itself and not the other declarations of the same function.
+
Matches a 'for', 'while', 'while' statement or a function or coroutine
+definition that has a given body. Note that in case of functions or
+coroutines this matcher only matches the definition itself and not the
+other declarations of the same function or coroutine.
 
 Given
   for (;;) {}
@@ -8226,9 +8275,10 @@
 
 
 Matcher<ForStmt>hasBodyMatcher<Stmt> InnerMatcher
-
Matches a 'for', 'while', 'do' statement or a function definition that has
-a given body. Note that in case of functions this matcher only matches the
-definition itself and not the other declarations of the same function.
+
Matches a 'for', 'while', 'while' statement or a function or coroutine
+definition that has a given body. Note that in case of functions or
+coroutines this matcher only matches the definition itself and not the
+other declarations of the same function or coroutine.
 
 Given
   for (;;) {}
@@ -8420,9 +8470,10 @@
 
 
 Matcher<FunctionDecl>hasBodyMatcher<Stmt> InnerMatcher
-
Matches a 'for', 'while', 'do' statement or a function definition that has
-a given body. Note that in case of functions this matcher only matches the
-definition itself and not the other declarations of the same function.
+
Matches a 'for', 'while', 'while' statement or a function or coroutine
+definition that has a given body. Note that in case of functions or
+coroutines this matcher only matches the definition itself and not the
+other declarations of the same function or coroutine.
 
 Given
   for (;;) {}
@@ -10082,9 +10133,10 @@
 
 
 Matcher<WhileStmt>hasBodyMatcher<Stmt> InnerMatcher
-
Matches a 'for', 'while', 'do' statement or a function definition that has
-a given body. Note that in case of functions this matcher only matches the
-definition itself and not the other declarations of the same function.
+
Matches a 'for', 'while', 'while' statement or a function or coroutine
+definition that has a given body. Note that in case of functions or
+coroutines this matcher only matches the definition itself and not the
+other declarations of the same function or coroutine.
 
 Given
   for (;;) {}
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -245,6 +245,7 @@
 - Added ``__builtin_elementwise_nearbyint`` for floating point
   types. This allows access to ``llvm.nearbyint`` for arbitrary
   floating-point and vector of floating-point types.
+- Clang AST matcher now matches concept declarations with `conceptDecl`.
 
 New Compiler Flags
 ------------------
Index: clang/include/clang/ASTMatchers/ASTMatchers.h
===================================================================
--- clang/include/clang/ASTMatchers/ASTMatchers.h
+++ clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -1334,6 +1334,16 @@
 extern const internal::VariadicDynCastAllOfMatcher
     cxxDeductionGuideDecl;
 
+/// Matches concept declarations.
+///
+/// Example matches integral
+/// \code
+///   template
+///   concept integral = std::is_integral_v;
+/// \endcode
+extern const internal::VariadicDynCastAllOfMatcher
+    conceptDecl;
+
 /// Matches variable declarations.
 ///
 /// Note: this does not match declarations of member variables, which are
Index: clang/lib/ASTMatchers/ASTMatchersInternal.cpp
===================================================================
--- clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -800,6 +800,7 @@
 const internal::VariadicDynCastAllOfMatcher cxxMethodDecl;
 const internal::VariadicDynCastAllOfMatcher
     cxxConversionDecl;
+const internal::VariadicDynCastAllOfMatcher conceptDecl;
 const internal::VariadicDynCastAllOfMatcher varDecl;
 const internal::VariadicDynCastAllOfMatcher fieldDecl;
 const internal::VariadicDynCastAllOfMatcher
Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp
===================================================================
--- clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -170,6 +170,7 @@
   REGISTER_MATCHER(compoundLiteralExpr);
   REGISTER_MATCHER(compoundStmt);
   REGISTER_MATCHER(coawaitExpr);
+  REGISTER_MATCHER(conceptDecl);
   REGISTER_MATCHER(conditionalOperator);
   REGISTER_MATCHER(constantArrayType);
   REGISTER_MATCHER(constantExpr);
Index: clang/unittests/AST/DeclTest.cpp
===================================================================
--- clang/unittests/AST/DeclTest.cpp
+++ clang/unittests/AST/DeclTest.cpp
@@ -12,9 +12,11 @@
 
 #include "clang/AST/Decl.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Mangle.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Lex/Lexer.h"
@@ -140,6 +142,22 @@
   ASSERT_TRUE(0 == MangleB.compare("_ZTSAT0__T_"));
 }
 
+TEST(Decl, ConceptDecl) {
+  llvm::StringRef Code(R"(
+    template
+    concept integral = __is_integral(T);
+  )");
+
+  auto AST = tooling::buildASTFromCodeWithArgs(Code, {"-std=c++20"});
+  ASTContext &Ctx = AST->getASTContext();
+  SourceManager &SM = Ctx.getSourceManager();
+
+  const auto *Decl =
+      selectFirst("decl", match(conceptDecl().bind("decl"), Ctx));
+  ASSERT_TRUE(Decl != nullptr);
+  EXPECT_EQ(Decl->getName(), "integral");
+}
+
 TEST(Decl, EnumDeclRange) {
   llvm::Annotations Code(R"(
     typedef int Foo;