[clang-tools-extra] [clang-tidy] Update llvmlibc-implementation-in-namespace to new rules (PR #66504)

Guillaume Chatelet via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 21 06:47:08 PDT 2023


https://github.com/gchatelet updated https://github.com/llvm/llvm-project/pull/66504

>From f1427a81c4a3425c1a574316fc26d2c74297b34b Mon Sep 17 00:00:00 2001
From: Guillaume Chatelet <gchatelet at google.com>
Date: Fri, 15 Sep 2023 12:34:17 +0000
Subject: [PATCH 1/6] [clang-tidy] Update llvmlibc-implementation-in-namespace
 to new rules

This is the implementation of step 3 of
https://discourse.llvm.org/t/rfc-customizable-namespace-to-allow-testing-the-libc-when-the-system-libc-is-also-llvms-libc/73079.
---
 .../ImplementationInNamespaceCheck.cpp        | 21 ++++++++-----
 .../llvmlibc/implementation-in-namespace.rst  | 23 +++++++++-----
 .../llvmlibc/implementation-in-namespace.cpp  | 31 +++++++++++++------
 3 files changed, 50 insertions(+), 25 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.cpp b/clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.cpp
index d05310f09ef773a..69a385f5be9807f 100644
--- a/clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.cpp
+++ b/clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.cpp
@@ -14,7 +14,9 @@ using namespace clang::ast_matchers;
 
 namespace clang::tidy::llvm_libc {
 
-const static StringRef RequiredNamespace = "__llvm_libc";
+const static StringRef RequiredNamespaceStart = "__llvm_libc";
+const static StringRef RequiredNamespaceMacroName = "LIBC_NAMESPACE";
+
 void ImplementationInNamespaceCheck::registerMatchers(MatchFinder *Finder) {
   Finder->addMatcher(
       decl(hasParent(translationUnitDecl()), unless(linkageSpecDecl()))
@@ -29,16 +31,19 @@ void ImplementationInNamespaceCheck::check(
   if (!Result.SourceManager->isInMainFile(MatchedDecl->getLocation()))
     return;
 
-  if (const auto *NS = dyn_cast<NamespaceDecl>(MatchedDecl)) {
-    if (NS->getName() != RequiredNamespace) {
-      diag(NS->getLocation(), "'%0' needs to be the outermost namespace")
-          << RequiredNamespace;
-    }
+  if (auto *NS = dyn_cast<NamespaceDecl>(MatchedDecl)) {
+    if (!Result.SourceManager->isMacroBodyExpansion(NS->getLocation()))
+      diag(NS->getLocation(),
+           "the outermost namespace should be the '%0' macro")
+          << RequiredNamespaceMacroName;
+    else if (!NS->getName().starts_with(RequiredNamespaceStart))
+      diag(NS->getLocation(), "the outermost namespace should start with '%0'")
+          << RequiredNamespaceStart;
     return;
   }
   diag(MatchedDecl->getLocation(),
-       "declaration must be declared within the '%0' namespace")
-      << RequiredNamespace;
+       "declaration must be declared within a namespace starting with '%0'")
+      << RequiredNamespaceStart;
 }
 
 } // namespace clang::tidy::llvm_libc
diff --git a/clang-tools-extra/docs/clang-tidy/checks/llvmlibc/implementation-in-namespace.rst b/clang-tools-extra/docs/clang-tidy/checks/llvmlibc/implementation-in-namespace.rst
index 33d6dc8ff125c84..47ea2b866a93404 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/llvmlibc/implementation-in-namespace.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/llvmlibc/implementation-in-namespace.rst
@@ -8,21 +8,30 @@ correct namespace.
 
 .. code-block:: c++
 
-    // Correct: implementation inside the correct namespace.
-    namespace __llvm_libc {
+    // Implementation inside the LIBC_NAMESPACE namespace.
+    // Correct if:
+    // - LIBC_NAMESPACE is a macro
+    // - LIBC_NAMESPACE expansion starts with `__llvm_libc`
+    namespace LIBC_NAMESPACE {
         void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {}
-        // Namespaces within __llvm_libc namespace are allowed.
-        namespace inner{
+        // Namespaces within LIBC_NAMESPACE namespace are allowed.
+        namespace inner {
             int localVar = 0;
         }
         // Functions with C linkage are allowed.
-        extern "C" void str_fuzz(){}
+        extern "C" void str_fuzz() {}
     }
 
-    // Incorrect: implementation not in a namespace.
+    // Incorrect: implementation not in the LIBC_NAMESPACE namespace.
     void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {}
 
-    // Incorrect: outer most namespace is not correct.
+    // Incorrect: outer most namespace is not the LIBC_NAMESPACE macro.
     namespace something_else {
         void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {}
     }
+
+    // Incorrect: outer most namespace expansion does not start with `__llvm_libc`.
+    #define LIBC_NAMESPACE custom_namespace
+    namespace LIBC_NAMESPACE {
+        void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {}
+    }
diff --git a/clang-tools-extra/test/clang-tidy/checkers/llvmlibc/implementation-in-namespace.cpp b/clang-tools-extra/test/clang-tidy/checkers/llvmlibc/implementation-in-namespace.cpp
index e75556a623b655c..16c5f9ca1067ec5 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/llvmlibc/implementation-in-namespace.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/llvmlibc/implementation-in-namespace.cpp
@@ -3,18 +3,18 @@
 #define MACRO_A "defining macros outside namespace is valid"
 
 class ClassB;
-// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration must be declared within the '__llvm_libc' namespace
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration must be declared within a namespace starting with '__llvm_libc'
 struct StructC {};
-// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: declaration must be declared within the '__llvm_libc' namespace
+// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: declaration must be declared within a namespace starting with '__llvm_libc'
 char *VarD = MACRO_A;
-// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration must be declared within the '__llvm_libc' namespace
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration must be declared within a namespace starting with '__llvm_libc'
 typedef int typeE;
-// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: declaration must be declared within the '__llvm_libc' namespace
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: declaration must be declared within a namespace starting with '__llvm_libc'
 void funcF() {}
-// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: declaration must be declared within the '__llvm_libc' namespace
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: declaration must be declared within a namespace starting with '__llvm_libc'
 
 namespace namespaceG {
-// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: '__llvm_libc' needs to be the outermost namespace
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: the outermost namespace should be the 'LIBC_NAMESPACE' macro
 namespace __llvm_libc{
 namespace namespaceH {
 class ClassB;
@@ -26,9 +26,20 @@ typedef int typeE;
 void funcF() {}
 } // namespace namespaceG
 
-// Wrapped in correct namespace.
-namespace __llvm_libc {
-// Namespaces within __llvim_libc namespace allowed.
+// Wrapped in macro namespace but with an incorrect name
+#define LIBC_NAMESPACE custom_namespace
+namespace LIBC_NAMESPACE {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: the outermost namespace should start with '__llvm_libc'
+namespace namespaceH {
+class ClassB;
+} // namespace namespaceH
+} // namespace LIBC_NAMESPACE
+
+
+// Wrapped in macro namespace with a valid name, LIBC_NAMESPACE starts with '__llvm_libc'
+#undef LIBC_NAMESPACE
+#define LIBC_NAMESPACE __llvm_libc_xyz
+namespace LIBC_NAMESPACE {
 namespace namespaceI {
 class ClassB;
 } // namespace namespaceI
@@ -37,4 +48,4 @@ char *VarD = MACRO_A;
 typedef int typeE;
 void funcF() {}
 extern "C" void extern_funcJ() {}
-} // namespace __llvm_libc
+} // namespace LIBC_NAMESPACE

>From bae9be668c284678818e957272a2906fe12c0808 Mon Sep 17 00:00:00 2001
From: Guillaume Chatelet <gchatelet at google.com>
Date: Mon, 18 Sep 2023 07:40:49 +0000
Subject: [PATCH 2/6] Address comment

---
 .../clang-tidy/llvmlibc/ImplementationInNamespaceCheck.cpp      | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.cpp b/clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.cpp
index 69a385f5be9807f..7ac483571b0de6c 100644
--- a/clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.cpp
+++ b/clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.cpp
@@ -31,7 +31,7 @@ void ImplementationInNamespaceCheck::check(
   if (!Result.SourceManager->isInMainFile(MatchedDecl->getLocation()))
     return;
 
-  if (auto *NS = dyn_cast<NamespaceDecl>(MatchedDecl)) {
+  if (const auto *NS = dyn_cast<NamespaceDecl>(MatchedDecl)) {
     if (!Result.SourceManager->isMacroBodyExpansion(NS->getLocation()))
       diag(NS->getLocation(),
            "the outermost namespace should be the '%0' macro")

>From 1de5e614826c136b4b107f0835ca37564aee7270 Mon Sep 17 00:00:00 2001
From: Guillaume Chatelet <gchatelet at google.com>
Date: Mon, 18 Sep 2023 15:03:05 +0000
Subject: [PATCH 3/6] Add entry in release notes

---
 clang-tools-extra/docs/ReleaseNotes.rst | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 19c977977f9044c..c541e17ef076a2b 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -300,6 +300,11 @@ Changes in existing checks
   <clang-tidy/checks/readability/static-accessed-through-instance>` check to
   identify calls to static member functions with out-of-class inline definitions.
 
+- Updated :doc:`llvmlibc-implementation-in-namespace
+  <clang-tidy/checks/llvmlibc/implementation-in-namespace>` to support
+  customizable namespace. This further allows for testing the libc when the
+  system-libc is also LLVM's libc.
+
 Removed checks
 ^^^^^^^^^^^^^^
 

>From d0466e640002c9e371c8c258867c8287d431f8cb Mon Sep 17 00:00:00 2001
From: Guillaume Chatelet <gchatelet at google.com>
Date: Thu, 21 Sep 2023 09:12:22 +0000
Subject: [PATCH 4/6] Address comments

---
 .../ImplementationInNamespaceCheck.cpp         | 18 +++++++++---------
 clang-tools-extra/docs/ReleaseNotes.rst        | 10 +++++-----
 .../llvmlibc/implementation-in-namespace.cpp   | 17 +++++++++++------
 3 files changed, 25 insertions(+), 20 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.cpp b/clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.cpp
index 7ac483571b0de6c..a953ff626a51ea9 100644
--- a/clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.cpp
+++ b/clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.cpp
@@ -18,32 +18,32 @@ const static StringRef RequiredNamespaceStart = "__llvm_libc";
 const static StringRef RequiredNamespaceMacroName = "LIBC_NAMESPACE";
 
 void ImplementationInNamespaceCheck::registerMatchers(MatchFinder *Finder) {
-  Finder->addMatcher(
-      decl(hasParent(translationUnitDecl()), unless(linkageSpecDecl()))
-          .bind("child_of_translation_unit"),
-      this);
+  Finder->addMatcher(decl(isExpansionInMainFile(),
+                          hasDeclContext(translationUnitDecl()),
+                          unless(linkageSpecDecl()))
+                         .bind("child_of_translation_unit"),
+                     this);
 }
 
 void ImplementationInNamespaceCheck::check(
     const MatchFinder::MatchResult &Result) {
   const auto *MatchedDecl =
       Result.Nodes.getNodeAs<Decl>("child_of_translation_unit");
-  if (!Result.SourceManager->isInMainFile(MatchedDecl->getLocation()))
-    return;
 
   if (const auto *NS = dyn_cast<NamespaceDecl>(MatchedDecl)) {
     if (!Result.SourceManager->isMacroBodyExpansion(NS->getLocation()))
       diag(NS->getLocation(),
            "the outermost namespace should be the '%0' macro")
           << RequiredNamespaceMacroName;
-    else if (!NS->getName().starts_with(RequiredNamespaceStart))
+    else if (NS->isAnonymousNamespace() ||
+             NS->getName().starts_with(RequiredNamespaceStart) == false)
       diag(NS->getLocation(), "the outermost namespace should start with '%0'")
           << RequiredNamespaceStart;
     return;
   }
   diag(MatchedDecl->getLocation(),
-       "declaration must be declared within a namespace starting with '%0'")
-      << RequiredNamespaceStart;
+       "declaration must be declared within the '%0' namespace")
+      << RequiredNamespaceMacroName;
 }
 
 } // namespace clang::tidy::llvm_libc
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index c541e17ef076a2b..4793728bc56c6d4 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -231,6 +231,11 @@ Changes in existing checks
   <clang-tidy/checks/llvm/namespace-comment>` check to provide fixes for
   ``inline`` namespaces in the same format as :program:`clang-format`.
 
+- Improved :doc:`llvmlibc-implementation-in-namespace
+  <clang-tidy/checks/llvmlibc/implementation-in-namespace>` to support
+  customizable namespace. This further allows for testing the libc when the
+  system-libc is also LLVM's libc.
+
 - Improved :doc:`misc-include-cleaner
   <clang-tidy/checks/misc/include-cleaner>` check by adding option
   `DeduplicateFindings` to output one finding per symbol occurrence.
@@ -300,11 +305,6 @@ Changes in existing checks
   <clang-tidy/checks/readability/static-accessed-through-instance>` check to
   identify calls to static member functions with out-of-class inline definitions.
 
-- Updated :doc:`llvmlibc-implementation-in-namespace
-  <clang-tidy/checks/llvmlibc/implementation-in-namespace>` to support
-  customizable namespace. This further allows for testing the libc when the
-  system-libc is also LLVM's libc.
-
 Removed checks
 ^^^^^^^^^^^^^^
 
diff --git a/clang-tools-extra/test/clang-tidy/checkers/llvmlibc/implementation-in-namespace.cpp b/clang-tools-extra/test/clang-tidy/checkers/llvmlibc/implementation-in-namespace.cpp
index 16c5f9ca1067ec5..3f5000f9cc5bbd1 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/llvmlibc/implementation-in-namespace.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/llvmlibc/implementation-in-namespace.cpp
@@ -3,19 +3,24 @@
 #define MACRO_A "defining macros outside namespace is valid"
 
 class ClassB;
-// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration must be declared within a namespace starting with '__llvm_libc'
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration must be declared within the 'LIBC_NAMESPACE' namespace
 struct StructC {};
-// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: declaration must be declared within a namespace starting with '__llvm_libc'
+// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: declaration must be declared within the 'LIBC_NAMESPACE' namespace
 char *VarD = MACRO_A;
-// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration must be declared within a namespace starting with '__llvm_libc'
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration must be declared within the 'LIBC_NAMESPACE' namespace
 typedef int typeE;
-// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: declaration must be declared within a namespace starting with '__llvm_libc'
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: declaration must be declared within the 'LIBC_NAMESPACE' namespace
 void funcF() {}
-// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: declaration must be declared within a namespace starting with '__llvm_libc'
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: declaration must be declared within the 'LIBC_NAMESPACE' namespace
+
+namespace outer_most {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: the outermost namespace should be the 'LIBC_NAMESPACE' macro
+ class A {};
+}
 
 namespace namespaceG {
 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: the outermost namespace should be the 'LIBC_NAMESPACE' macro
-namespace __llvm_libc{
+namespace __llvm_libc {
 namespace namespaceH {
 class ClassB;
 } // namespace namespaceH

>From 8cfc5ad2868b6c0af78b544945a8ef2fd96f6a45 Mon Sep 17 00:00:00 2001
From: Guillaume Chatelet <gchatelet at google.com>
Date: Thu, 21 Sep 2023 12:34:35 +0000
Subject: [PATCH 5/6] Restructure code and match anonymous namespaces

---
 .../ImplementationInNamespaceCheck.cpp        | 33 +++++++++++--------
 .../llvmlibc/implementation-in-namespace.cpp  | 18 ++++++----
 2 files changed, 31 insertions(+), 20 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.cpp b/clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.cpp
index a953ff626a51ea9..9dd7e1926be59b8 100644
--- a/clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.cpp
+++ b/clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.cpp
@@ -20,7 +20,9 @@ const static StringRef RequiredNamespaceMacroName = "LIBC_NAMESPACE";
 void ImplementationInNamespaceCheck::registerMatchers(MatchFinder *Finder) {
   Finder->addMatcher(decl(isExpansionInMainFile(),
                           hasDeclContext(translationUnitDecl()),
-                          unless(linkageSpecDecl()))
+                          unless(linkageSpecDecl()),
+                          // anonymous namespaces generate usingDirective
+                          unless(usingDirectiveDecl(isImplicit())))
                          .bind("child_of_translation_unit"),
                      this);
 }
@@ -29,21 +31,24 @@ void ImplementationInNamespaceCheck::check(
     const MatchFinder::MatchResult &Result) {
   const auto *MatchedDecl =
       Result.Nodes.getNodeAs<Decl>("child_of_translation_unit");
-
-  if (const auto *NS = dyn_cast<NamespaceDecl>(MatchedDecl)) {
-    if (!Result.SourceManager->isMacroBodyExpansion(NS->getLocation()))
-      diag(NS->getLocation(),
-           "the outermost namespace should be the '%0' macro")
-          << RequiredNamespaceMacroName;
-    else if (NS->isAnonymousNamespace() ||
-             NS->getName().starts_with(RequiredNamespaceStart) == false)
-      diag(NS->getLocation(), "the outermost namespace should start with '%0'")
-          << RequiredNamespaceStart;
+  MatchedDecl->dump();
+  const auto *NS = dyn_cast<NamespaceDecl>(MatchedDecl);
+  if (NS == nullptr || NS->isAnonymousNamespace()) {
+    diag(MatchedDecl->getLocation(),
+         "declaration must be enclosed within the '%0' namespace")
+        << RequiredNamespaceMacroName;
+    return;
+  }
+  if (Result.SourceManager->isMacroBodyExpansion(NS->getLocation()) == false) {
+    diag(NS->getLocation(), "the outermost namespace should be the '%0' macro")
+        << RequiredNamespaceMacroName;
+    return;
+  }
+  if (NS->getName().starts_with(RequiredNamespaceStart) == false) {
+    diag(NS->getLocation(), "the '%0' macro should start with '%1'")
+        << RequiredNamespaceMacroName << RequiredNamespaceStart;
     return;
   }
-  diag(MatchedDecl->getLocation(),
-       "declaration must be declared within the '%0' namespace")
-      << RequiredNamespaceMacroName;
 }
 
 } // namespace clang::tidy::llvm_libc
diff --git a/clang-tools-extra/test/clang-tidy/checkers/llvmlibc/implementation-in-namespace.cpp b/clang-tools-extra/test/clang-tidy/checkers/llvmlibc/implementation-in-namespace.cpp
index 3f5000f9cc5bbd1..2246a430dd1f573 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/llvmlibc/implementation-in-namespace.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/llvmlibc/implementation-in-namespace.cpp
@@ -3,21 +3,27 @@
 #define MACRO_A "defining macros outside namespace is valid"
 
 class ClassB;
-// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration must be declared within the 'LIBC_NAMESPACE' namespace
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration must be enclosed within the 'LIBC_NAMESPACE' namespace
 struct StructC {};
-// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: declaration must be declared within the 'LIBC_NAMESPACE' namespace
+// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: declaration must be enclosed within the 'LIBC_NAMESPACE' namespace
 char *VarD = MACRO_A;
-// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration must be declared within the 'LIBC_NAMESPACE' namespace
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration must be enclosed within the 'LIBC_NAMESPACE' namespace
 typedef int typeE;
-// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: declaration must be declared within the 'LIBC_NAMESPACE' namespace
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: declaration must be enclosed within the 'LIBC_NAMESPACE' namespace
 void funcF() {}
-// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: declaration must be declared within the 'LIBC_NAMESPACE' namespace
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: declaration must be enclosed within the 'LIBC_NAMESPACE' namespace
 
 namespace outer_most {
 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: the outermost namespace should be the 'LIBC_NAMESPACE' macro
  class A {};
 }
 
+// Wrapped in anonymous namespace.
+namespace {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: declaration must be enclosed within the 'LIBC_NAMESPACE' namespace
+ class A {};
+}
+
 namespace namespaceG {
 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: the outermost namespace should be the 'LIBC_NAMESPACE' macro
 namespace __llvm_libc {
@@ -34,7 +40,7 @@ void funcF() {}
 // Wrapped in macro namespace but with an incorrect name
 #define LIBC_NAMESPACE custom_namespace
 namespace LIBC_NAMESPACE {
-// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: the outermost namespace should start with '__llvm_libc'
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: the 'LIBC_NAMESPACE' macro should start with '__llvm_libc'
 namespace namespaceH {
 class ClassB;
 } // namespace namespaceH

>From 86c4de00b92ce0b8a0421bc48058c1ae21f8e64a Mon Sep 17 00:00:00 2001
From: Guillaume Chatelet <gchatelet at google.com>
Date: Thu, 21 Sep 2023 13:46:52 +0000
Subject: [PATCH 6/6] use more efficient matching

---
 .../llvmlibc/ImplementationInNamespaceCheck.cpp    | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.cpp b/clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.cpp
index 9dd7e1926be59b8..4489179c4423419 100644
--- a/clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.cpp
+++ b/clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.cpp
@@ -18,13 +18,13 @@ const static StringRef RequiredNamespaceStart = "__llvm_libc";
 const static StringRef RequiredNamespaceMacroName = "LIBC_NAMESPACE";
 
 void ImplementationInNamespaceCheck::registerMatchers(MatchFinder *Finder) {
-  Finder->addMatcher(decl(isExpansionInMainFile(),
-                          hasDeclContext(translationUnitDecl()),
-                          unless(linkageSpecDecl()),
-                          // anonymous namespaces generate usingDirective
-                          unless(usingDirectiveDecl(isImplicit())))
-                         .bind("child_of_translation_unit"),
-                     this);
+  Finder->addMatcher(
+      translationUnitDecl(
+          forEach(decl(isExpansionInMainFile(), unless(linkageSpecDecl()),
+                       // anonymous namespaces generate usingDirective
+                       unless(usingDirectiveDecl(isImplicit())))
+                      .bind("child_of_translation_unit"))),
+      this);
 }
 
 void ImplementationInNamespaceCheck::check(



More information about the cfe-commits mailing list