Skip to content

Commit 4e94f90

Browse files
committed
merge main into amd-staging
2 parents abb39ea + 4326f68 commit 4e94f90

File tree

105 files changed

+5475
-1697
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

105 files changed

+5475
-1697
lines changed

clang-tools-extra/clang-tidy/llvm/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ add_clang_library(clangTidyLLVMModule STATIC
99
LLVMTidyModule.cpp
1010
PreferIsaOrDynCastInConditionalsCheck.cpp
1111
PreferRegisterOverUnsignedCheck.cpp
12+
PreferStaticOverAnonymousNamespaceCheck.cpp
1213
TwineLocalCheck.cpp
1314

1415
LINK_LIBS

clang-tools-extra/clang-tidy/llvm/LLVMTidyModule.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "IncludeOrderCheck.h"
1717
#include "PreferIsaOrDynCastInConditionalsCheck.h"
1818
#include "PreferRegisterOverUnsignedCheck.h"
19+
#include "PreferStaticOverAnonymousNamespaceCheck.h"
1920
#include "TwineLocalCheck.h"
2021

2122
namespace clang::tidy {
@@ -34,6 +35,8 @@ class LLVMModule : public ClangTidyModule {
3435
"llvm-prefer-isa-or-dyn-cast-in-conditionals");
3536
CheckFactories.registerCheck<PreferRegisterOverUnsignedCheck>(
3637
"llvm-prefer-register-over-unsigned");
38+
CheckFactories.registerCheck<PreferStaticOverAnonymousNamespaceCheck>(
39+
"llvm-prefer-static-over-anonymous-namespace");
3740
CheckFactories.registerCheck<readability::QualifiedAutoCheck>(
3841
"llvm-qualified-auto");
3942
CheckFactories.registerCheck<TwineLocalCheck>("llvm-twine-local");
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
//===--- PreferStaticOverAnonymousNamespaceCheck.cpp - clang-tidy ---------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "PreferStaticOverAnonymousNamespaceCheck.h"
10+
#include "clang/ASTMatchers/ASTMatchFinder.h"
11+
12+
using namespace clang::ast_matchers;
13+
14+
namespace clang::tidy::llvm_check {
15+
16+
namespace {
17+
18+
AST_MATCHER(NamedDecl, isInMacro) {
19+
return Node.getBeginLoc().isMacroID() || Node.getEndLoc().isMacroID();
20+
}
21+
22+
AST_MATCHER(VarDecl, isLocalVariable) { return Node.isLocalVarDecl(); }
23+
24+
} // namespace
25+
26+
PreferStaticOverAnonymousNamespaceCheck::
27+
PreferStaticOverAnonymousNamespaceCheck(StringRef Name,
28+
ClangTidyContext *Context)
29+
: ClangTidyCheck(Name, Context),
30+
AllowVariableDeclarations(Options.get("AllowVariableDeclarations", true)),
31+
AllowMemberFunctionsInClass(
32+
Options.get("AllowMemberFunctionsInClass", true)) {}
33+
34+
void PreferStaticOverAnonymousNamespaceCheck::storeOptions(
35+
ClangTidyOptions::OptionMap &Opts) {
36+
Options.store(Opts, "AllowVariableDeclarations", AllowVariableDeclarations);
37+
Options.store(Opts, "AllowMemberFunctionsInClass",
38+
AllowMemberFunctionsInClass);
39+
}
40+
41+
void PreferStaticOverAnonymousNamespaceCheck::registerMatchers(
42+
MatchFinder *Finder) {
43+
const auto IsDefinitionInAnonymousNamespace =
44+
allOf(unless(isExpansionInSystemHeader()), isInAnonymousNamespace(),
45+
unless(isInMacro()), isDefinition());
46+
47+
if (AllowMemberFunctionsInClass) {
48+
Finder->addMatcher(
49+
functionDecl(IsDefinitionInAnonymousNamespace,
50+
unless(anyOf(hasParent(cxxRecordDecl()),
51+
hasParent(functionTemplateDecl(
52+
hasParent(cxxRecordDecl()))))))
53+
.bind("function"),
54+
this);
55+
} else {
56+
Finder->addMatcher(
57+
functionDecl(IsDefinitionInAnonymousNamespace).bind("function"), this);
58+
}
59+
60+
if (!AllowVariableDeclarations)
61+
Finder->addMatcher(varDecl(IsDefinitionInAnonymousNamespace,
62+
unless(isLocalVariable()), unless(parmVarDecl()))
63+
.bind("var"),
64+
this);
65+
}
66+
67+
void PreferStaticOverAnonymousNamespaceCheck::check(
68+
const MatchFinder::MatchResult &Result) {
69+
70+
if (const auto *Func = Result.Nodes.getNodeAs<FunctionDecl>("function")) {
71+
if (Func->isCXXClassMember())
72+
diag(Func->getLocation(),
73+
"place definition of method %0 outside of an anonymous namespace")
74+
<< Func;
75+
else if (Func->isStatic())
76+
diag(Func->getLocation(),
77+
"place static function %0 outside of an anonymous namespace")
78+
<< Func;
79+
else
80+
diag(Func->getLocation(),
81+
"function %0 is declared in an anonymous namespace; "
82+
"prefer using 'static' for restricting visibility")
83+
<< Func;
84+
return;
85+
}
86+
87+
if (const auto *Var = Result.Nodes.getNodeAs<VarDecl>("var")) {
88+
if (Var->getStorageClass() == SC_Static)
89+
diag(Var->getLocation(),
90+
"place static variable %0 outside of an anonymous namespace")
91+
<< Var;
92+
else
93+
diag(Var->getLocation(),
94+
"variable %0 is declared in an anonymous namespace; "
95+
"prefer using 'static' for restricting visibility")
96+
<< Var;
97+
}
98+
}
99+
100+
} // namespace clang::tidy::llvm_check
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
//===--- PreferStaticOverAnonymousNamespaceCheck.h - clang-tidy -*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LLVM_PREFERSTATICOVERANONYMOUSNAMESPACECHECK_H
10+
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LLVM_PREFERSTATICOVERANONYMOUSNAMESPACECHECK_H
11+
12+
#include "../ClangTidyCheck.h"
13+
14+
namespace clang::tidy::llvm_check {
15+
16+
/// Finds function and variable declarations inside anonymous namespace and
17+
/// suggests replacing them with ``static`` declarations.
18+
///
19+
/// For the user-facing documentation see:
20+
/// http://clang.llvm.org/extra/clang-tidy/checks/llvm/prefer-static-over-anonymous-namespace.html
21+
class PreferStaticOverAnonymousNamespaceCheck : public ClangTidyCheck {
22+
public:
23+
PreferStaticOverAnonymousNamespaceCheck(StringRef Name,
24+
ClangTidyContext *Context);
25+
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
26+
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
27+
void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
28+
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
29+
return LangOpts.CPlusPlus;
30+
}
31+
std::optional<TraversalKind> getCheckTraversalKind() const override {
32+
return TK_IgnoreUnlessSpelledInSource;
33+
}
34+
35+
private:
36+
const bool AllowVariableDeclarations;
37+
const bool AllowMemberFunctionsInClass;
38+
};
39+
40+
} // namespace clang::tidy::llvm_check
41+
42+
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LLVM_PREFERSTATICOVERANONYMOUSNAMESPACECHECK_H

clang-tools-extra/clang-tidy/utils/Matchers.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ class MatchesAnyListedNameMatcher
145145
// qualified name will be used for matching, otherwise its name will be used.
146146
inline ::clang::ast_matchers::internal::Matcher<NamedDecl>
147147
matchesAnyListedName(llvm::ArrayRef<StringRef> NameList) {
148-
return ::clang::ast_matchers::internal::makeMatcher(
148+
return ::clang::ast_matchers::internal::Matcher(
149149
new MatchesAnyListedNameMatcher(NameList));
150150
}
151151

@@ -188,7 +188,7 @@ class MatchesAnyListedTypeNameMatcher
188188
inline ::clang::ast_matchers::internal::Matcher<QualType>
189189
matchesAnyListedTypeName(llvm::ArrayRef<StringRef> NameList,
190190
bool CanonicalTypes) {
191-
return ::clang::ast_matchers::internal::makeMatcher(
191+
return ::clang::ast_matchers::internal::Matcher(
192192
new MatchesAnyListedTypeNameMatcher(NameList, CanonicalTypes));
193193
}
194194
inline ::clang::ast_matchers::internal::Matcher<QualType>

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,12 @@ New checks
142142
Finds unscoped (non-class) ``enum`` declarations and suggests using
143143
``enum class`` instead.
144144

145+
- New :doc:`llvm-prefer-static-over-anonymous-namespace
146+
<clang-tidy/checks/llvm/prefer-static-over-anonymous-namespace>` check.
147+
148+
Finds function and variable declarations inside anonymous namespace and
149+
suggests replacing them with ``static`` declarations.
150+
145151
- New :doc:`modernize-use-scoped-lock
146152
<clang-tidy/checks/modernize/use-scoped-lock>` check.
147153

clang-tools-extra/docs/clang-tidy/checks/list.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ Clang-Tidy Checks
250250
:doc:`llvm-namespace-comment <llvm/namespace-comment>`,
251251
:doc:`llvm-prefer-isa-or-dyn-cast-in-conditionals <llvm/prefer-isa-or-dyn-cast-in-conditionals>`, "Yes"
252252
:doc:`llvm-prefer-register-over-unsigned <llvm/prefer-register-over-unsigned>`, "Yes"
253+
:doc:`llvm-prefer-static-over-anonymous-namespace <llvm/prefer-static-over-anonymous-namespace>`,
253254
:doc:`llvm-twine-local <llvm/twine-local>`, "Yes"
254255
:doc:`llvmlibc-callee-namespace <llvmlibc/callee-namespace>`,
255256
:doc:`llvmlibc-implementation-in-namespace <llvmlibc/implementation-in-namespace>`,
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
.. title:: clang-tidy - llvm-prefer-static-over-anonymous-namespace
2+
3+
llvm-prefer-static-over-anonymous-namespace
4+
===========================================
5+
6+
Finds function and variable declarations inside anonymous namespace and
7+
suggests replacing them with ``static`` declarations.
8+
9+
The `LLVM Coding Standards <https://llvm.org/docs/CodingStandards.html#restrict-visibility>`_
10+
recommend keeping anonymous namespaces as small as possible and only use them
11+
for class declarations. For functions and variables the ``static`` specifier
12+
should be preferred for restricting visibility.
13+
14+
For example non-compliant code:
15+
16+
.. code-block:: c++
17+
18+
namespace {
19+
20+
class StringSort {
21+
public:
22+
StringSort(...)
23+
bool operator<(const char *RHS) const;
24+
};
25+
26+
// warning: place method definition outside of an anonymous namespace
27+
bool StringSort::operator<(const char *RHS) const {}
28+
29+
// warning: prefer using 'static' for restricting visibility
30+
void runHelper() {}
31+
32+
// warning: prefer using 'static' for restricting visibility
33+
int myVariable = 42;
34+
35+
}
36+
37+
Should become:
38+
39+
.. code-block:: c++
40+
41+
// Small anonymous namespace for class declaration
42+
namespace {
43+
44+
class StringSort {
45+
public:
46+
StringSort(...)
47+
bool operator<(const char *RHS) const;
48+
};
49+
50+
}
51+
52+
// placed method definition outside of the anonymous namespace
53+
bool StringSort::operator<(const char *RHS) const {}
54+
55+
// used 'static' instead of an anonymous namespace
56+
static void runHelper() {}
57+
58+
// used 'static' instead of an anonymous namespace
59+
static int myVariable = 42;
60+
61+
62+
Options
63+
-------
64+
65+
.. option:: AllowVariableDeclarations
66+
67+
When `true`, allow variable declarations to be in anonymous namespace.
68+
Default value is `true`.
69+
70+
.. option:: AllowMemberFunctionsInClass
71+
72+
When `true`, only methods defined in anonymous namespace outside of the
73+
corresponding class will be warned. Default value is `true`.

0 commit comments

Comments
 (0)