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

via cfe-commits cfe-commits at lists.llvm.org
Fri Sep 15 05:40:20 PDT 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-tidy
            
<details>
<summary>Changes</summary>
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.

--
Full diff: https://github.com/llvm/llvm-project/pull/66504.diff

3 Files Affected:

- (modified) clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.cpp (+13-8) 
- (modified) clang-tools-extra/docs/clang-tidy/checks/llvmlibc/implementation-in-namespace.rst (+16-7) 
- (modified) clang-tools-extra/test/clang-tidy/checkers/llvmlibc/implementation-in-namespace.cpp (+21-10) 


<pre>
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 = &quot;__llvm_libc&quot;;
+const static StringRef RequiredNamespaceStart = &quot;__llvm_libc&quot;;
+const static StringRef RequiredNamespaceMacroName = &quot;LIBC_NAMESPACE&quot;;
+
 void ImplementationInNamespaceCheck::registerMatchers(MatchFinder *Finder) {
   Finder-&gt;addMatcher(
       decl(hasParent(translationUnitDecl()), unless(linkageSpecDecl()))
@@ -29,16 +31,19 @@ void ImplementationInNamespaceCheck::check(
   if (!Result.SourceManager-&gt;isInMainFile(MatchedDecl-&gt;getLocation()))
     return;
 
-  if (const auto *NS = dyn_cast&lt;NamespaceDecl&gt;(MatchedDecl)) {
-    if (NS-&gt;getName() != RequiredNamespace) {
-      diag(NS-&gt;getLocation(), &quot;&#x27;%0&#x27; needs to be the outermost namespace&quot;)
-          &lt;&lt; RequiredNamespace;
-    }
+  if (auto *NS = dyn_cast&lt;NamespaceDecl&gt;(MatchedDecl)) {
+    if (!Result.SourceManager-&gt;isMacroBodyExpansion(NS-&gt;getLocation()))
+      diag(NS-&gt;getLocation(),
+           &quot;the outermost namespace should be the &#x27;%0&#x27; macro&quot;)
+          &lt;&lt; RequiredNamespaceMacroName;
+    else if (!NS-&gt;getName().starts_with(RequiredNamespaceStart))
+      diag(NS-&gt;getLocation(), &quot;the outermost namespace should start with &#x27;%0&#x27;&quot;)
+          &lt;&lt; RequiredNamespaceStart;
     return;
   }
   diag(MatchedDecl-&gt;getLocation(),
-       &quot;declaration must be declared within the &#x27;%0&#x27; namespace&quot;)
-      &lt;&lt; RequiredNamespace;
+       &quot;declaration must be declared within a namespace starting with &#x27;%0&#x27;&quot;)
+      &lt;&lt; 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 &quot;C&quot; void str_fuzz(){}
+        extern &quot;C&quot; 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 &quot;defining macros outside namespace is valid&quot;
 
 class ClassB;
-// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration must be declared within the &#x27;__llvm_libc&#x27; namespace
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration must be declared within a namespace starting with &#x27;__llvm_libc&#x27;
 struct StructC {};
-// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: declaration must be declared within the &#x27;__llvm_libc&#x27; namespace
+// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: declaration must be declared within a namespace starting with &#x27;__llvm_libc&#x27;
 char *VarD = MACRO_A;
-// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration must be declared within the &#x27;__llvm_libc&#x27; namespace
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration must be declared within a namespace starting with &#x27;__llvm_libc&#x27;
 typedef int typeE;
-// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: declaration must be declared within the &#x27;__llvm_libc&#x27; namespace
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: declaration must be declared within a namespace starting with &#x27;__llvm_libc&#x27;
 void funcF() {}
-// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: declaration must be declared within the &#x27;__llvm_libc&#x27; namespace
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: declaration must be declared within a namespace starting with &#x27;__llvm_libc&#x27;
 
 namespace namespaceG {
-// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: &#x27;__llvm_libc&#x27; needs to be the outermost namespace
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: the outermost namespace should be the &#x27;LIBC_NAMESPACE&#x27; 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 &#x27;__llvm_libc&#x27;
+namespace namespaceH {
+class ClassB;
+} // namespace namespaceH
+} // namespace LIBC_NAMESPACE
+
+
+// Wrapped in macro namespace with a valid name, LIBC_NAMESPACE starts with &#x27;__llvm_libc&#x27;
+#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 &quot;C&quot; void extern_funcJ() {}
-} // namespace __llvm_libc
+} // namespace LIBC_NAMESPACE
</pre>
</details>


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


More information about the cfe-commits mailing list