https://github.com/vbvictor updated https://github.com/llvm/llvm-project/pull/148357
>From 82bee931621536e7e59910f1833289510909ce23 Mon Sep 17 00:00:00 2001 From: Victor Baranov <bar.victor.2...@gmail.com> Date: Sat, 12 Jul 2025 14:24:31 +0300 Subject: [PATCH] [clang-tidy] Use lexical anon-ns matcher in llvm-prefer-static-over-anonymous-namespace --- ...referStaticOverAnonymousNamespaceCheck.cpp | 17 +++- ...prefer-static-over-anonymous-namespace.cpp | 89 +++++++++++++++++++ 2 files changed, 103 insertions(+), 3 deletions(-) diff --git a/clang-tools-extra/clang-tidy/llvm/PreferStaticOverAnonymousNamespaceCheck.cpp b/clang-tools-extra/clang-tidy/llvm/PreferStaticOverAnonymousNamespaceCheck.cpp index 592f0986292f2..ea79bfaef8876 100644 --- a/clang-tools-extra/clang-tidy/llvm/PreferStaticOverAnonymousNamespaceCheck.cpp +++ b/clang-tools-extra/clang-tidy/llvm/PreferStaticOverAnonymousNamespaceCheck.cpp @@ -21,6 +21,17 @@ AST_MATCHER(NamedDecl, isInMacro) { AST_MATCHER(VarDecl, isLocalVariable) { return Node.isLocalVarDecl(); } +AST_MATCHER(Decl, isLexicallyInAnonymousNamespace) { + for (const DeclContext *DC = Node.getLexicalDeclContext(); DC != nullptr; + DC = DC->getLexicalParent()) { + if (const auto *ND = dyn_cast<NamespaceDecl>(DC)) + if (ND->isAnonymousNamespace()) + return true; + } + + return false; +} + } // namespace PreferStaticOverAnonymousNamespaceCheck:: @@ -40,9 +51,9 @@ void PreferStaticOverAnonymousNamespaceCheck::storeOptions( void PreferStaticOverAnonymousNamespaceCheck::registerMatchers( MatchFinder *Finder) { - const auto IsDefinitionInAnonymousNamespace = - allOf(unless(isExpansionInSystemHeader()), isInAnonymousNamespace(), - unless(isInMacro()), isDefinition()); + const auto IsDefinitionInAnonymousNamespace = allOf( + unless(isExpansionInSystemHeader()), isLexicallyInAnonymousNamespace(), + unless(isInMacro()), isDefinition()); if (AllowMemberFunctionsInClass) { Finder->addMatcher( diff --git a/clang-tools-extra/test/clang-tidy/checkers/llvm/prefer-static-over-anonymous-namespace.cpp b/clang-tools-extra/test/clang-tidy/checkers/llvm/prefer-static-over-anonymous-namespace.cpp index f0ffafcf18e67..71dce6ea4f01c 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/llvm/prefer-static-over-anonymous-namespace.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/llvm/prefer-static-over-anonymous-namespace.cpp @@ -178,6 +178,95 @@ void OuterClass::NestedClass::nestedMemberFunc() {} } // namespace +namespace { + +class MyClassOutOfAnon { +public: + MyClassOutOfAnon(); + MyClassOutOfAnon(const MyClassOutOfAnon&) {} + // CHECK-MESSAGES-MEM: :[[@LINE-1]]:3: warning: place definition of method 'MyClassOutOfAnon' outside of an anonymous namespace + MyClassOutOfAnon(MyClassOutOfAnon&&) = default; + // CHECK-MESSAGES-MEM: :[[@LINE-1]]:3: warning: place definition of method 'MyClassOutOfAnon' outside of an anonymous namespace + MyClassOutOfAnon& operator=(const MyClassOutOfAnon&); + MyClassOutOfAnon& operator=(MyClassOutOfAnon&&); + bool operator<(const MyClassOutOfAnon&) const; + void memberFunction(); + static void staticMemberFunction(); + void memberDefinedInClass() {} + // CHECK-MESSAGES-MEM: :[[@LINE-1]]:8: warning: place definition of method 'memberDefinedInClass' outside of an anonymous namespace + static void staticMemberDefinedInClass() {} + // CHECK-MESSAGES-MEM: :[[@LINE-1]]:15: warning: place definition of method 'staticMemberDefinedInClass' outside of an anonymous namespace + template <typename T> + void templateFunction(); + template <typename T> + void templateFunctionInClass() {} + // CHECK-MESSAGES-MEM: :[[@LINE-1]]:8: warning: place definition of method 'templateFunctionInClass' outside of an anonymous namespace +}; + +} // namespace + +MyClassOutOfAnon::MyClassOutOfAnon() {} + +MyClassOutOfAnon& MyClassOutOfAnon::operator=(const MyClassOutOfAnon&) { return *this; } + +MyClassOutOfAnon& MyClassOutOfAnon::operator=(MyClassOutOfAnon&&) = default; + +bool MyClassOutOfAnon::operator<(const MyClassOutOfAnon&) const { return true; } + +void MyClassOutOfAnon::memberFunction() {} + +void MyClassOutOfAnon::staticMemberFunction() {} + +template <typename T> +void MyClassOutOfAnon::templateFunction() {} + +namespace { + +template<typename T> +class TemplateClassOutOfAnon { + public: + TemplateClassOutOfAnon(); + TemplateClassOutOfAnon(const TemplateClassOutOfAnon&) {} + // CHECK-MESSAGES-MEM: :[[@LINE-1]]:3: warning: place definition of method 'TemplateClassOutOfAnon<T>' outside of an anonymous namespace + TemplateClassOutOfAnon(TemplateClassOutOfAnon&&) = default; + // CHECK-MESSAGES-MEM: :[[@LINE-1]]:3: warning: place definition of method 'TemplateClassOutOfAnon<T>' outside of an anonymous namespace + TemplateClassOutOfAnon& operator=(const TemplateClassOutOfAnon&); + TemplateClassOutOfAnon& operator=(TemplateClassOutOfAnon&&); + bool operator<(const TemplateClassOutOfAnon&) const; + void memberFunc(); + T getValue() const; + void memberDefinedInClass() {} + // CHECK-MESSAGES-MEM: :[[@LINE-1]]:8: warning: place definition of method 'memberDefinedInClass' outside of an anonymous namespace + static void staticMemberDefinedInClass() {} + // CHECK-MESSAGES-MEM: :[[@LINE-1]]:15: warning: place definition of method 'staticMemberDefinedInClass' outside of an anonymous namespace + template <typename U> + void templateMethodInTemplateClass() {} + // CHECK-MESSAGES-MEM: :[[@LINE-1]]:8: warning: place definition of method 'templateMethodInTemplateClass' outside of an anonymous namespace + private: + T Value; +}; + +} // namespace + +template<typename T> +TemplateClassOutOfAnon<T>::TemplateClassOutOfAnon() {} + +template<typename T> +TemplateClassOutOfAnon<T>& TemplateClassOutOfAnon<T>::operator=(const TemplateClassOutOfAnon&) { return *this; } + +template<typename T> +TemplateClassOutOfAnon<T>& TemplateClassOutOfAnon<T>::operator=(TemplateClassOutOfAnon&&) = default; + +template<typename T> +bool TemplateClassOutOfAnon<T>::operator<(const TemplateClassOutOfAnon&) const { return true; } + +template<typename T> +void TemplateClassOutOfAnon<T>::memberFunc() {} + +template<typename T> +T TemplateClassOutOfAnon<T>::getValue() const { return Value; } + + #define DEFINE_FUNCTION(name) \ namespace { \ void name() {} \ _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits