diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html --- a/clang/docs/LibASTMatchersReference.html +++ b/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.
 
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -262,6 +262,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
 ------------------
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
@@ -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
diff --git a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
--- a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ b/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
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
@@ -172,6 +172,7 @@
   REGISTER_MATCHER(compoundLiteralExpr);
   REGISTER_MATCHER(compoundStmt);
   REGISTER_MATCHER(coawaitExpr);
+  REGISTER_MATCHER(conceptDecl);
   REGISTER_MATCHER(conditionalOperator);
   REGISTER_MATCHER(constantArrayType);
   REGISTER_MATCHER(constantExpr);
diff --git a/clang/unittests/AST/DeclTest.cpp b/clang/unittests/AST/DeclTest.cpp
--- a/clang/unittests/AST/DeclTest.cpp
+++ b/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;