diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html --- a/clang/docs/LibASTMatchersReference.html +++ b/clang/docs/LibASTMatchersReference.html @@ -3962,6 +3962,25 @@ cxxRecordDecl(hasName("vector"), isInStdNamespace()) will match only #1. +Matcher<Decl>isInAnonymousNamespace +
Matches declarations in an anonymous namespace.
+
+Given
+  class vector {};
+  namespace foo {
+    class vector {};
+    namespace {
+      class vector {}; // #1
+    }
+  }
+  namespace {
+    class vector {}; // #2
+    namespace foo {
+      class vector{}; // #3
+    }
+  }
+cxxRecordDecl(hasName("vector"), isInAnonymousNamespace()) will match #1, #2 and #3.
+
Matcher<Decl>isInstantiated
Matches declarations that are template instantiations or are inside
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -859,6 +859,7 @@
 
 AST Matchers
 ------------
+- Add ``isInAnoymousNamespace`` matcher to match declarations in an anonymous namespace.
 
 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
@@ -7813,6 +7813,30 @@
 /// cxxRecordDecl(hasName("vector"), isInStdNamespace()) will match only #1.
 AST_MATCHER(Decl, isInStdNamespace) { return Node.isInStdNamespace(); }
 
+/// Matches declarations in an anonymous namespace.
+///
+/// Given
+/// \code
+///   class vector {};
+///   namespace foo {
+///     class vector {};
+///     namespace {
+///       class vector {}; // #1
+///     }
+///   }
+///   namespace {
+///     class vector {}; // #2
+///     namespace foo {
+///       class vector{}; // #3
+///     }
+///   }
+/// \endcode
+/// cxxRecordDecl(hasName("vector"), isInAnonymousNamespace()) will match
+/// #1, #2 and #3.
+AST_MATCHER(Decl, isInAnonymousNamespace) {
+  return Node.isInAnonymousNamespace();
+}
+
 /// If the given case statement does not use the GNU case range
 /// extension, matches the constant given in the statement.
 ///
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
@@ -3550,6 +3550,41 @@
                       cxxRecordDecl(hasName("vector"), isInStdNamespace())));
 }
 
+TEST_P(ASTMatchersTest, InAnonymousNamespace) {
+  if (!GetParam().isCXX()) {
+    return;
+  }
+
+  EXPECT_TRUE(
+      notMatches("class vector {};"
+                 "namespace foo {"
+                 "  class vector {};"
+                 "}",
+                 cxxRecordDecl(hasName("vector"), isInAnonymousNamespace())));
+
+  EXPECT_TRUE(
+      matches("namespace {"
+              "  class vector {};"
+              "}",
+              cxxRecordDecl(hasName("vector"), isInAnonymousNamespace())));
+
+  EXPECT_TRUE(
+      matches("namespace foo {"
+              "  namespace {"
+              "    class vector {};"
+              "  }"
+              "}",
+              cxxRecordDecl(hasName("vector"), isInAnonymousNamespace())));
+
+  EXPECT_TRUE(
+      matches("namespace {"
+              "  namespace foo {"
+              "    class vector {};"
+              "  }"
+              "}",
+              cxxRecordDecl(hasName("vector"), isInAnonymousNamespace())));
+}
+
 TEST_P(ASTMatchersTest, InStdNamespace_CXX11) {
   if (!GetParam().isCXX11OrLater()) {
     return;