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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits