[clang-tools-extra] [clang-tidy] new check misc-use-internal-linkage (PR #90830)
Congcong Cai via cfe-commits
cfe-commits at lists.llvm.org
Mon May 6 09:34:09 PDT 2024
https://github.com/HerrCai0907 updated https://github.com/llvm/llvm-project/pull/90830
>From 24cbbd0c87ab2a06381d210da1dff5f966b72773 Mon Sep 17 00:00:00 2001
From: Congcong Cai <congcongcai0907 at 163.com>
Date: Thu, 2 May 2024 15:44:45 +0800
Subject: [PATCH 1/7] reformat
---
.../clang-tidy/readability/CMakeLists.txt | 1 +
.../readability/ReadabilityTidyModule.cpp | 3 +
.../UnnecessaryExternalLinkageCheck.cpp | 82 +++++++++++++++++++
.../UnnecessaryExternalLinkageCheck.h | 33 ++++++++
clang-tools-extra/docs/ReleaseNotes.rst | 5 ++
.../docs/clang-tidy/checks/list.rst | 1 +
.../unnecessary-external-linkage.rst | 26 ++++++
.../readability/Inputs/mark-static-var/func.h | 3 +
.../readability/Inputs/mark-static-var/var.h | 3 +
.../unnecessary-external-linkage-func.cpp | 30 +++++++
.../unnecessary-external-linkage-var.cpp | 40 +++++++++
11 files changed, 227 insertions(+)
create mode 100644 clang-tools-extra/clang-tidy/readability/UnnecessaryExternalLinkageCheck.cpp
create mode 100644 clang-tools-extra/clang-tidy/readability/UnnecessaryExternalLinkageCheck.h
create mode 100644 clang-tools-extra/docs/clang-tidy/checks/readability/unnecessary-external-linkage.rst
create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/Inputs/mark-static-var/func.h
create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/Inputs/mark-static-var/var.h
create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/unnecessary-external-linkage-func.cpp
create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/unnecessary-external-linkage-var.cpp
diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
index 41065fc8e87859..8f58d9f24ba491 100644
--- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
@@ -23,6 +23,7 @@ add_clang_library(clangTidyReadabilityModule
IdentifierLengthCheck.cpp
IdentifierNamingCheck.cpp
ImplicitBoolConversionCheck.cpp
+ UnnecessaryExternalLinkageCheck.cpp
RedundantInlineSpecifierCheck.cpp
InconsistentDeclarationParameterNameCheck.cpp
IsolateDeclarationCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
index d61c0ba39658e5..d389287e8f4909 100644
--- a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
@@ -58,6 +58,7 @@
#include "StringCompareCheck.h"
#include "SuspiciousCallArgumentCheck.h"
#include "UniqueptrDeleteReleaseCheck.h"
+#include "UnnecessaryExternalLinkageCheck.h"
#include "UppercaseLiteralSuffixCheck.h"
#include "UseAnyOfAllOfCheck.h"
#include "UseStdMinMaxCheck.h"
@@ -106,6 +107,8 @@ class ReadabilityModule : public ClangTidyModule {
"readability-identifier-naming");
CheckFactories.registerCheck<ImplicitBoolConversionCheck>(
"readability-implicit-bool-conversion");
+ CheckFactories.registerCheck<UnnecessaryExternalLinkageCheck>(
+ "readability-unnecessary-external-linkage");
CheckFactories.registerCheck<MathMissingParenthesesCheck>(
"readability-math-missing-parentheses");
CheckFactories.registerCheck<RedundantInlineSpecifierCheck>(
diff --git a/clang-tools-extra/clang-tidy/readability/UnnecessaryExternalLinkageCheck.cpp b/clang-tools-extra/clang-tidy/readability/UnnecessaryExternalLinkageCheck.cpp
new file mode 100644
index 00000000000000..4970d3339ef05d
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/readability/UnnecessaryExternalLinkageCheck.cpp
@@ -0,0 +1,82 @@
+//===--- UnnecessaryExternalLinkageCheck.cpp - clang-tidy
+//---------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "UnnecessaryExternalLinkageCheck.h"
+#include "clang/AST/Decl.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/ASTMatchers/ASTMatchersMacros.h"
+#include "clang/Basic/Specifiers.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+namespace {
+
+AST_POLYMORPHIC_MATCHER(isFirstDecl,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
+ VarDecl)) {
+ return Node.isFirstDecl();
+}
+
+AST_MATCHER(Decl, isInMainFile) {
+ for (const Decl *D : Node.redecls())
+ if (!Finder->getASTContext().getSourceManager().isInMainFile(
+ D->getLocation()))
+ return false;
+ return true;
+}
+
+AST_POLYMORPHIC_MATCHER(isExternStorageClass,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
+ VarDecl)) {
+ return Node.getStorageClass() == SC_Extern;
+}
+
+} // namespace
+
+void UnnecessaryExternalLinkageCheck::registerMatchers(MatchFinder *Finder) {
+ auto Common = allOf(isFirstDecl(), isInMainFile(),
+ unless(anyOf(
+ // 1. internal linkage
+ isStaticStorageClass(), isInAnonymousNamespace(),
+ // 2. explicit external linkage
+ isExternStorageClass(), isExternC(),
+ // 3. template
+ isExplicitTemplateSpecialization(),
+ clang::ast_matchers::isTemplateInstantiation(),
+ // 4. friend
+ hasAncestor(friendDecl()))));
+ Finder->addMatcher(
+ functionDecl(Common, unless(cxxMethodDecl()), unless(isMain()))
+ .bind("fn"),
+ this);
+ Finder->addMatcher(varDecl(Common, hasGlobalStorage()).bind("var"), this);
+}
+
+static constexpr StringRef Message =
+ "%0 %1 can be internal linkage, "
+ "marking as static or using anonymous namespace can avoid external "
+ "linkage.";
+
+void UnnecessaryExternalLinkageCheck::check(
+ const MatchFinder::MatchResult &Result) {
+ if (const auto *FD = Result.Nodes.getNodeAs<FunctionDecl>("fn")) {
+ diag(FD->getLocation(), Message) << "function" << FD;
+ return;
+ }
+ if (const auto *VD = Result.Nodes.getNodeAs<VarDecl>("var")) {
+ diag(VD->getLocation(), Message) << "variable" << VD;
+ return;
+ }
+ llvm_unreachable("");
+}
+
+} // namespace clang::tidy::readability
diff --git a/clang-tools-extra/clang-tidy/readability/UnnecessaryExternalLinkageCheck.h b/clang-tools-extra/clang-tidy/readability/UnnecessaryExternalLinkageCheck.h
new file mode 100644
index 00000000000000..523e271ef20626
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/readability/UnnecessaryExternalLinkageCheck.h
@@ -0,0 +1,33 @@
+//===--- UnnecessaryExternalLinkageCheck.h - clang-tidy ---------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_UNNECESSARYEXTERNALLINKAGECHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_UNNECESSARYEXTERNALLINKAGECHECK_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang::tidy::readability {
+
+/// Detects variable and function can be marked as static.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/readability/unnecessary-external-linkage.html
+class UnnecessaryExternalLinkageCheck : public ClangTidyCheck {
+public:
+ UnnecessaryExternalLinkageCheck(StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context) {}
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+ std::optional<TraversalKind> getCheckTraversalKind() const override {
+ return TK_IgnoreUnlessSpelledInSource;
+ }
+};
+
+} // namespace clang::tidy::readability
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_UNNECESSARYEXTERNALLINKAGECHECK_H
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 5956ccb925485c..6269393eb02b8b 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -151,6 +151,11 @@ New checks
Enforces consistent style for enumerators' initialization, covering three
styles: none, first only, or all initialized explicitly.
+- New :doc:`readability-unnecessary-external-linkage
+ <clang-tidy/checks/readability/unnecessary-external-linkage>` check.
+
+ Detects variable and function can be marked as static.
+
- New :doc:`readability-math-missing-parentheses
<clang-tidy/checks/readability/math-missing-parentheses>` check.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst
index 5cdaf9e35b6acd..c50ed21a07abb9 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -390,6 +390,7 @@ Clang-Tidy Checks
:doc:`readability-string-compare <readability/string-compare>`, "Yes"
:doc:`readability-suspicious-call-argument <readability/suspicious-call-argument>`,
:doc:`readability-uniqueptr-delete-release <readability/uniqueptr-delete-release>`, "Yes"
+ :doc:`readability-unnecessary-external-linkage <readability/unnecessary-external-linkage>`,
:doc:`readability-uppercase-literal-suffix <readability/uppercase-literal-suffix>`, "Yes"
:doc:`readability-use-anyofallof <readability/use-anyofallof>`,
:doc:`readability-use-std-min-max <readability/use-std-min-max>`, "Yes"
diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/unnecessary-external-linkage.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/unnecessary-external-linkage.rst
new file mode 100644
index 00000000000000..f25c7197cd0da1
--- /dev/null
+++ b/clang-tools-extra/docs/clang-tidy/checks/readability/unnecessary-external-linkage.rst
@@ -0,0 +1,26 @@
+.. title:: clang-tidy - readability-unnecessary-external-linkage
+
+readability-unnecessary-external-linkage
+========================================
+
+Detects variable and function can be marked as static.
+
+Static functions and variables are scoped to a single file. Marking functions
+and variables as static helps to better remove dead code. In addition, it gives
+the compiler more information and can help compiler make more aggressive
+optimizations.
+
+Example:
+
+.. code-block:: c++
+ int v1; // can be marked as static
+
+ void fn1(); // can be marked as static
+
+ namespace {
+ // already in anonymous namespace
+ int v2;
+ void fn2();
+ }
+ // already declared as extern
+ extern int v2;
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/Inputs/mark-static-var/func.h b/clang-tools-extra/test/clang-tidy/checkers/readability/Inputs/mark-static-var/func.h
new file mode 100644
index 00000000000000..31c68e9ad0cd92
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/Inputs/mark-static-var/func.h
@@ -0,0 +1,3 @@
+#pragma once
+
+void func_header();
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/Inputs/mark-static-var/var.h b/clang-tools-extra/test/clang-tidy/checkers/readability/Inputs/mark-static-var/var.h
new file mode 100644
index 00000000000000..37e4cfbafff146
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/Inputs/mark-static-var/var.h
@@ -0,0 +1,3 @@
+#pragma once
+
+extern int gloabl_header;
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/unnecessary-external-linkage-func.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/unnecessary-external-linkage-func.cpp
new file mode 100644
index 00000000000000..362def250d68c5
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/unnecessary-external-linkage-func.cpp
@@ -0,0 +1,30 @@
+// RUN: %check_clang_tidy %s readability-unnecessary-external-linkage %t -- -- -I%S/Inputs/mark-static-var
+
+#include "func.h"
+
+void func() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'func'
+
+template<class T>
+void func_template() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'func_template'
+
+struct S {
+ void method();
+};
+void S::method() {}
+
+void func_header();
+extern void func_extern();
+static void func_static();
+namespace {
+void func_anonymous_ns();
+} // namespace
+
+int main(int argc, const char*argv[]) {}
+
+extern "C" {
+void func_extern_c_1() {}
+}
+
+extern "C" void func_extern_c_2() {}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/unnecessary-external-linkage-var.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/unnecessary-external-linkage-var.cpp
new file mode 100644
index 00000000000000..68981e04fa5dc8
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/unnecessary-external-linkage-var.cpp
@@ -0,0 +1,40 @@
+// RUN: %check_clang_tidy %s readability-unnecessary-external-linkage %t -- -- -I%S/Inputs/mark-static-var
+
+#include "var.h"
+
+int global;
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: variable 'global'
+
+template<class T>
+T global_template;
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: variable 'global_template'
+
+int gloabl_header;
+
+extern int global_extern;
+
+static int global_static;
+
+namespace {
+static int global_anonymous_ns;
+namespace NS {
+static int global_anonymous_ns;
+}
+}
+
+static void f(int para) {
+ int local;
+ static int local_static;
+}
+
+struct S {
+ int m1;
+ static int m2;
+};
+int S::m2;
+
+extern "C" {
+int global_in_extern_c_1;
+}
+
+extern "C" int global_in_extern_c_2;
>From fb55ca3b7b15578783253db440e0816351b73a8a Mon Sep 17 00:00:00 2001
From: Congcong Cai <congcongcai0907 at 163.com>
Date: Sat, 4 May 2024 21:59:55 +0800
Subject: [PATCH 2/7] rename to misc-use-internal-linkage
---
.../clang-tidy/misc/CMakeLists.txt | 1 +
.../clang-tidy/misc/MiscTidyModule.cpp | 3 +++
.../UseInternalLinkageCheck.cpp} | 13 ++++++-------
.../UseInternalLinkageCheck.h} | 18 +++++++++---------
.../clang-tidy/readability/CMakeLists.txt | 1 -
.../readability/ReadabilityTidyModule.cpp | 3 ---
clang-tools-extra/docs/ReleaseNotes.rst | 4 ++--
.../docs/clang-tidy/checks/list.rst | 2 +-
.../use-internal-linkage.rst} | 6 +++---
.../Inputs/use-internal-linkage}/func.h | 0
.../Inputs/use-internal-linkage}/var.h | 0
.../use-internal-linkage-func.cpp} | 2 +-
.../use-internal-linkage-var.cpp} | 2 +-
13 files changed, 27 insertions(+), 28 deletions(-)
rename clang-tools-extra/clang-tidy/{readability/UnnecessaryExternalLinkageCheck.cpp => misc/UseInternalLinkageCheck.cpp} (87%)
rename clang-tools-extra/clang-tidy/{readability/UnnecessaryExternalLinkageCheck.h => misc/UseInternalLinkageCheck.h} (54%)
rename clang-tools-extra/docs/clang-tidy/checks/{readability/unnecessary-external-linkage.rst => misc/use-internal-linkage.rst} (78%)
rename clang-tools-extra/test/clang-tidy/checkers/{readability/Inputs/mark-static-var => misc/Inputs/use-internal-linkage}/func.h (100%)
rename clang-tools-extra/test/clang-tidy/checkers/{readability/Inputs/mark-static-var => misc/Inputs/use-internal-linkage}/var.h (100%)
rename clang-tools-extra/test/clang-tidy/checkers/{readability/unnecessary-external-linkage-func.cpp => misc/use-internal-linkage-func.cpp} (82%)
rename clang-tools-extra/test/clang-tidy/checkers/{readability/unnecessary-external-linkage-var.cpp => misc/use-internal-linkage-var.cpp} (84%)
diff --git a/clang-tools-extra/clang-tidy/misc/CMakeLists.txt b/clang-tools-extra/clang-tidy/misc/CMakeLists.txt
index d9ec268650c053..1d4385f661d09c 100644
--- a/clang-tools-extra/clang-tidy/misc/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/misc/CMakeLists.txt
@@ -40,6 +40,7 @@ add_clang_library(clangTidyMiscModule
UnusedParametersCheck.cpp
UnusedUsingDeclsCheck.cpp
UseAnonymousNamespaceCheck.cpp
+ UseInternalLinkageCheck.cpp
LINK_LIBS
clangAnalysis
diff --git a/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp b/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp
index d8a88324ee63e0..54bcebca7e1866 100644
--- a/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp
@@ -31,6 +31,7 @@
#include "UnusedParametersCheck.h"
#include "UnusedUsingDeclsCheck.h"
#include "UseAnonymousNamespaceCheck.h"
+#include "UseInternalLinkageCheck.h"
namespace clang::tidy {
namespace misc {
@@ -78,6 +79,8 @@ class MiscModule : public ClangTidyModule {
"misc-unused-using-decls");
CheckFactories.registerCheck<UseAnonymousNamespaceCheck>(
"misc-use-anonymous-namespace");
+ CheckFactories.registerCheck<UseInternalLinkageCheck>(
+ "misc-use-internal-linkage");
}
};
diff --git a/clang-tools-extra/clang-tidy/readability/UnnecessaryExternalLinkageCheck.cpp b/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp
similarity index 87%
rename from clang-tools-extra/clang-tidy/readability/UnnecessaryExternalLinkageCheck.cpp
rename to clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp
index 4970d3339ef05d..069c680039ec68 100644
--- a/clang-tools-extra/clang-tidy/readability/UnnecessaryExternalLinkageCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp
@@ -1,4 +1,4 @@
-//===--- UnnecessaryExternalLinkageCheck.cpp - clang-tidy
+//===--- UseInternalLinkageCheck.cpp - clang-tidy
//---------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-#include "UnnecessaryExternalLinkageCheck.h"
+#include "UseInternalLinkageCheck.h"
#include "clang/AST/Decl.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
@@ -16,7 +16,7 @@
using namespace clang::ast_matchers;
-namespace clang::tidy::readability {
+namespace clang::tidy::misc {
namespace {
@@ -42,7 +42,7 @@ AST_POLYMORPHIC_MATCHER(isExternStorageClass,
} // namespace
-void UnnecessaryExternalLinkageCheck::registerMatchers(MatchFinder *Finder) {
+void UseInternalLinkageCheck::registerMatchers(MatchFinder *Finder) {
auto Common = allOf(isFirstDecl(), isInMainFile(),
unless(anyOf(
// 1. internal linkage
@@ -66,8 +66,7 @@ static constexpr StringRef Message =
"marking as static or using anonymous namespace can avoid external "
"linkage.";
-void UnnecessaryExternalLinkageCheck::check(
- const MatchFinder::MatchResult &Result) {
+void UseInternalLinkageCheck::check(const MatchFinder::MatchResult &Result) {
if (const auto *FD = Result.Nodes.getNodeAs<FunctionDecl>("fn")) {
diag(FD->getLocation(), Message) << "function" << FD;
return;
@@ -79,4 +78,4 @@ void UnnecessaryExternalLinkageCheck::check(
llvm_unreachable("");
}
-} // namespace clang::tidy::readability
+} // namespace clang::tidy::misc
diff --git a/clang-tools-extra/clang-tidy/readability/UnnecessaryExternalLinkageCheck.h b/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.h
similarity index 54%
rename from clang-tools-extra/clang-tidy/readability/UnnecessaryExternalLinkageCheck.h
rename to clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.h
index 523e271ef20626..dc55bd20bc306a 100644
--- a/clang-tools-extra/clang-tidy/readability/UnnecessaryExternalLinkageCheck.h
+++ b/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.h
@@ -1,4 +1,4 @@
-//===--- UnnecessaryExternalLinkageCheck.h - clang-tidy ---------*- C++ -*-===//
+//===--- UseInternalLinkageCheck.h - clang-tidy -----------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,20 +6,20 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_UNNECESSARYEXTERNALLINKAGECHECK_H
-#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_UNNECESSARYEXTERNALLINKAGECHECK_H
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_USEINTERNALLINKAGECHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_USEINTERNALLINKAGECHECK_H
#include "../ClangTidyCheck.h"
-namespace clang::tidy::readability {
+namespace clang::tidy::misc {
/// Detects variable and function can be marked as static.
///
/// For the user-facing documentation see:
-/// http://clang.llvm.org/extra/clang-tidy/checks/readability/unnecessary-external-linkage.html
-class UnnecessaryExternalLinkageCheck : public ClangTidyCheck {
+/// http://clang.llvm.org/extra/clang-tidy/checks/misc/use-internal-linkage.html
+class UseInternalLinkageCheck : public ClangTidyCheck {
public:
- UnnecessaryExternalLinkageCheck(StringRef Name, ClangTidyContext *Context)
+ UseInternalLinkageCheck(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context) {}
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
@@ -28,6 +28,6 @@ class UnnecessaryExternalLinkageCheck : public ClangTidyCheck {
}
};
-} // namespace clang::tidy::readability
+} // namespace clang::tidy::misc
-#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_UNNECESSARYEXTERNALLINKAGECHECK_H
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_USEINTERNALLINKAGECHECK_H
diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
index 8f58d9f24ba491..41065fc8e87859 100644
--- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
@@ -23,7 +23,6 @@ add_clang_library(clangTidyReadabilityModule
IdentifierLengthCheck.cpp
IdentifierNamingCheck.cpp
ImplicitBoolConversionCheck.cpp
- UnnecessaryExternalLinkageCheck.cpp
RedundantInlineSpecifierCheck.cpp
InconsistentDeclarationParameterNameCheck.cpp
IsolateDeclarationCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
index d389287e8f4909..d61c0ba39658e5 100644
--- a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
@@ -58,7 +58,6 @@
#include "StringCompareCheck.h"
#include "SuspiciousCallArgumentCheck.h"
#include "UniqueptrDeleteReleaseCheck.h"
-#include "UnnecessaryExternalLinkageCheck.h"
#include "UppercaseLiteralSuffixCheck.h"
#include "UseAnyOfAllOfCheck.h"
#include "UseStdMinMaxCheck.h"
@@ -107,8 +106,6 @@ class ReadabilityModule : public ClangTidyModule {
"readability-identifier-naming");
CheckFactories.registerCheck<ImplicitBoolConversionCheck>(
"readability-implicit-bool-conversion");
- CheckFactories.registerCheck<UnnecessaryExternalLinkageCheck>(
- "readability-unnecessary-external-linkage");
CheckFactories.registerCheck<MathMissingParenthesesCheck>(
"readability-math-missing-parentheses");
CheckFactories.registerCheck<RedundantInlineSpecifierCheck>(
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 6269393eb02b8b..ac5613e9395ef4 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -151,8 +151,8 @@ New checks
Enforces consistent style for enumerators' initialization, covering three
styles: none, first only, or all initialized explicitly.
-- New :doc:`readability-unnecessary-external-linkage
- <clang-tidy/checks/readability/unnecessary-external-linkage>` check.
+- New :doc:`misc-use-internal-linkage
+ <clang-tidy/checks/misc/use-internal-linkage>` check.
Detects variable and function can be marked as static.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst
index c50ed21a07abb9..7f7775a3b508fb 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -267,6 +267,7 @@ Clang-Tidy Checks
:doc:`misc-unused-parameters <misc/unused-parameters>`, "Yes"
:doc:`misc-unused-using-decls <misc/unused-using-decls>`, "Yes"
:doc:`misc-use-anonymous-namespace <misc/use-anonymous-namespace>`,
+ :doc:`misc-use-internal-linkage <misc/use-internal-linkage>`,
:doc:`modernize-avoid-bind <modernize/avoid-bind>`, "Yes"
:doc:`modernize-avoid-c-arrays <modernize/avoid-c-arrays>`,
:doc:`modernize-concat-nested-namespaces <modernize/concat-nested-namespaces>`, "Yes"
@@ -390,7 +391,6 @@ Clang-Tidy Checks
:doc:`readability-string-compare <readability/string-compare>`, "Yes"
:doc:`readability-suspicious-call-argument <readability/suspicious-call-argument>`,
:doc:`readability-uniqueptr-delete-release <readability/uniqueptr-delete-release>`, "Yes"
- :doc:`readability-unnecessary-external-linkage <readability/unnecessary-external-linkage>`,
:doc:`readability-uppercase-literal-suffix <readability/uppercase-literal-suffix>`, "Yes"
:doc:`readability-use-anyofallof <readability/use-anyofallof>`,
:doc:`readability-use-std-min-max <readability/use-std-min-max>`, "Yes"
diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/unnecessary-external-linkage.rst b/clang-tools-extra/docs/clang-tidy/checks/misc/use-internal-linkage.rst
similarity index 78%
rename from clang-tools-extra/docs/clang-tidy/checks/readability/unnecessary-external-linkage.rst
rename to clang-tools-extra/docs/clang-tidy/checks/misc/use-internal-linkage.rst
index f25c7197cd0da1..c595f131ed7a3a 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/readability/unnecessary-external-linkage.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/misc/use-internal-linkage.rst
@@ -1,7 +1,7 @@
-.. title:: clang-tidy - readability-unnecessary-external-linkage
+.. title:: clang-tidy - misc-use-internal-linkage
-readability-unnecessary-external-linkage
-========================================
+misc-use-internal-linkage
+=========================
Detects variable and function can be marked as static.
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/Inputs/mark-static-var/func.h b/clang-tools-extra/test/clang-tidy/checkers/misc/Inputs/use-internal-linkage/func.h
similarity index 100%
rename from clang-tools-extra/test/clang-tidy/checkers/readability/Inputs/mark-static-var/func.h
rename to clang-tools-extra/test/clang-tidy/checkers/misc/Inputs/use-internal-linkage/func.h
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/Inputs/mark-static-var/var.h b/clang-tools-extra/test/clang-tidy/checkers/misc/Inputs/use-internal-linkage/var.h
similarity index 100%
rename from clang-tools-extra/test/clang-tidy/checkers/readability/Inputs/mark-static-var/var.h
rename to clang-tools-extra/test/clang-tidy/checkers/misc/Inputs/use-internal-linkage/var.h
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/unnecessary-external-linkage-func.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/use-internal-linkage-func.cpp
similarity index 82%
rename from clang-tools-extra/test/clang-tidy/checkers/readability/unnecessary-external-linkage-func.cpp
rename to clang-tools-extra/test/clang-tidy/checkers/misc/use-internal-linkage-func.cpp
index 362def250d68c5..3b949237a07a6e 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/unnecessary-external-linkage-func.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/use-internal-linkage-func.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy %s readability-unnecessary-external-linkage %t -- -- -I%S/Inputs/mark-static-var
+// RUN: %check_clang_tidy %s misc-use-internal-linkage %t -- -- -I%S/Inputs/use-internal-linkage
#include "func.h"
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/unnecessary-external-linkage-var.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/use-internal-linkage-var.cpp
similarity index 84%
rename from clang-tools-extra/test/clang-tidy/checkers/readability/unnecessary-external-linkage-var.cpp
rename to clang-tools-extra/test/clang-tidy/checkers/misc/use-internal-linkage-var.cpp
index 68981e04fa5dc8..bd5ef5431de6cc 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/unnecessary-external-linkage-var.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/use-internal-linkage-var.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy %s readability-unnecessary-external-linkage %t -- -- -I%S/Inputs/mark-static-var
+// RUN: %check_clang_tidy %s misc-use-internal-linkage %t -- -- -I%S/Inputs/use-internal-linkage
#include "var.h"
>From f8fe43f6f0d590de4634af63ade35e861d2db419 Mon Sep 17 00:00:00 2001
From: Congcong Cai <congcongcai0907 at 163.com>
Date: Sat, 4 May 2024 22:58:30 +0800
Subject: [PATCH 3/7] fix
---
.../misc/UseInternalLinkageCheck.cpp | 18 ++++++++----------
.../clang-tidy/misc/UseInternalLinkageCheck.h | 3 ++-
clang-tools-extra/docs/ReleaseNotes.rst | 11 ++++++-----
.../checks/misc/use-internal-linkage.rst | 6 +++---
4 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp b/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp
index 069c680039ec68..fc328d7f6a010e 100644
--- a/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp
@@ -1,5 +1,4 @@
-//===--- UseInternalLinkageCheck.cpp - clang-tidy
-//---------------------------------===//
+//===--- UseInternalLinkageCheck.cpp - clang-tidy--------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -13,6 +12,7 @@
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/ASTMatchers/ASTMatchersMacros.h"
#include "clang/Basic/Specifiers.h"
+#include "llvm/ADT/STLExtras.h"
using namespace clang::ast_matchers;
@@ -27,11 +27,10 @@ AST_POLYMORPHIC_MATCHER(isFirstDecl,
}
AST_MATCHER(Decl, isInMainFile) {
- for (const Decl *D : Node.redecls())
- if (!Finder->getASTContext().getSourceManager().isInMainFile(
- D->getLocation()))
- return false;
- return true;
+ return llvm::all_of(Node.redecls(), [&](const Decl *D) {
+ return Finder->getASTContext().getSourceManager().isInMainFile(
+ D->getLocation());
+ });
}
AST_POLYMORPHIC_MATCHER(isExternStorageClass,
@@ -62,9 +61,8 @@ void UseInternalLinkageCheck::registerMatchers(MatchFinder *Finder) {
}
static constexpr StringRef Message =
- "%0 %1 can be internal linkage, "
- "marking as static or using anonymous namespace can avoid external "
- "linkage.";
+ "%0 %1 can be can be made static or moved into an anonymous namespace "
+ "to enforce internal linkage.";
void UseInternalLinkageCheck::check(const MatchFinder::MatchResult &Result) {
if (const auto *FD = Result.Nodes.getNodeAs<FunctionDecl>("fn")) {
diff --git a/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.h b/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.h
index dc55bd20bc306a..358ef9ac517362 100644
--- a/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.h
+++ b/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.h
@@ -13,7 +13,8 @@
namespace clang::tidy::misc {
-/// Detects variable and function can be marked as static.
+/// Detects variables and functions that can be marked as static or moved into
+/// an anonymous namespace to enforce internal linkage.
///
/// For the user-facing documentation see:
/// http://clang.llvm.org/extra/clang-tidy/checks/misc/use-internal-linkage.html
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index ac5613e9395ef4..62da9558ada527 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -145,17 +145,18 @@ New checks
Finds initializer lists for aggregate types that could be
written as designated initializers instead.
+- New :doc:`misc-use-internal-linkage
+ <clang-tidy/checks/misc/use-internal-linkage>` check.
+
+ Detects variables and functions that can be marked as static or moved into
+ an anonymous namespace to enforce internal linkage.
+
- New :doc:`readability-enum-initial-value
<clang-tidy/checks/readability/enum-initial-value>` check.
Enforces consistent style for enumerators' initialization, covering three
styles: none, first only, or all initialized explicitly.
-- New :doc:`misc-use-internal-linkage
- <clang-tidy/checks/misc/use-internal-linkage>` check.
-
- Detects variable and function can be marked as static.
-
- New :doc:`readability-math-missing-parentheses
<clang-tidy/checks/readability/math-missing-parentheses>` check.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/misc/use-internal-linkage.rst b/clang-tools-extra/docs/clang-tidy/checks/misc/use-internal-linkage.rst
index c595f131ed7a3a..cd6a23e9378d43 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/misc/use-internal-linkage.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/misc/use-internal-linkage.rst
@@ -3,12 +3,12 @@
misc-use-internal-linkage
=========================
-Detects variable and function can be marked as static.
+Detects variables and functions that can be marked as static or moved into
+an anonymous namespace to enforce internal linkage.
Static functions and variables are scoped to a single file. Marking functions
and variables as static helps to better remove dead code. In addition, it gives
-the compiler more information and can help compiler make more aggressive
-optimizations.
+the compiler more information and allows for more aggressive optimizations.
Example:
>From 91a798fdde59bd9009478a1d3d652e62ed2c8a2e Mon Sep 17 00:00:00 2001
From: Congcong Cai <congcongcai0907 at 163.com>
Date: Sat, 4 May 2024 23:44:25 +0800
Subject: [PATCH 4/7] Update
clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Danny Mösch <danny.moesch at icloud.com>
---
clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp b/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp
index fc328d7f6a010e..ccb681b89fbf73 100644
--- a/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp
@@ -61,8 +61,8 @@ void UseInternalLinkageCheck::registerMatchers(MatchFinder *Finder) {
}
static constexpr StringRef Message =
- "%0 %1 can be can be made static or moved into an anonymous namespace "
- "to enforce internal linkage.";
+ "%0 %1 can be made static or moved into an anonymous namespace "
+ "to enforce internal linkage";
void UseInternalLinkageCheck::check(const MatchFinder::MatchResult &Result) {
if (const auto *FD = Result.Nodes.getNodeAs<FunctionDecl>("fn")) {
>From 3b3dda36ab44afa982db7678b00b819bc182ad4d Mon Sep 17 00:00:00 2001
From: Congcong Cai <congcongcai0907 at 163.com>
Date: Sun, 5 May 2024 10:51:48 +0800
Subject: [PATCH 5/7] fix doc
---
.../docs/clang-tidy/checks/misc/use-internal-linkage.rst | 1 +
1 file changed, 1 insertion(+)
diff --git a/clang-tools-extra/docs/clang-tidy/checks/misc/use-internal-linkage.rst b/clang-tools-extra/docs/clang-tidy/checks/misc/use-internal-linkage.rst
index cd6a23e9378d43..e8e43a1fb3d632 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/misc/use-internal-linkage.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/misc/use-internal-linkage.rst
@@ -13,6 +13,7 @@ the compiler more information and allows for more aggressive optimizations.
Example:
.. code-block:: c++
+
int v1; // can be marked as static
void fn1(); // can be marked as static
>From eda2fadab5cef0a69023fa28f94d6cf26a39055c Mon Sep 17 00:00:00 2001
From: Congcong Cai <congcongcai0907 at 163.com>
Date: Tue, 7 May 2024 00:04:28 +0800
Subject: [PATCH 6/7] fix comments
---
.../clang-tidy/misc/UseInternalLinkageCheck.cpp | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp b/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp
index ccb681b89fbf73..43ef272af65c6d 100644
--- a/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp
@@ -20,11 +20,7 @@ namespace clang::tidy::misc {
namespace {
-AST_POLYMORPHIC_MATCHER(isFirstDecl,
- AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
- VarDecl)) {
- return Node.isFirstDecl();
-}
+AST_MATCHER(Decl, isFirstDecl) { return Node.isFirstDecl(); }
AST_MATCHER(Decl, isInMainFile) {
return llvm::all_of(Node.redecls(), [&](const Decl *D) {
@@ -50,7 +46,6 @@ void UseInternalLinkageCheck::registerMatchers(MatchFinder *Finder) {
isExternStorageClass(), isExternC(),
// 3. template
isExplicitTemplateSpecialization(),
- clang::ast_matchers::isTemplateInstantiation(),
// 4. friend
hasAncestor(friendDecl()))));
Finder->addMatcher(
>From a67b60287dea65c53e58e00e36ab3f04004145b2 Mon Sep 17 00:00:00 2001
From: Congcong Cai <congcongcai0907 at 163.com>
Date: Tue, 7 May 2024 00:33:49 +0800
Subject: [PATCH 7/7] fix
---
.../clang-tidy/misc/UseInternalLinkageCheck.cpp | 12 ++++++++----
.../clang-tidy/misc/UseInternalLinkageCheck.h | 6 +++++-
2 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp b/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp
index 43ef272af65c6d..d03deea7def610 100644
--- a/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp
@@ -7,10 +7,12 @@
//===----------------------------------------------------------------------===//
#include "UseInternalLinkageCheck.h"
+#include "../utils/FileExtensionsUtils.h"
#include "clang/AST/Decl.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/ASTMatchers/ASTMatchersMacros.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
#include "llvm/ADT/STLExtras.h"
@@ -22,10 +24,12 @@ namespace {
AST_MATCHER(Decl, isFirstDecl) { return Node.isFirstDecl(); }
-AST_MATCHER(Decl, isInMainFile) {
+AST_MATCHER_P(Decl, isInMainFile, FileExtensionsSet, HeaderFileExtensions) {
return llvm::all_of(Node.redecls(), [&](const Decl *D) {
- return Finder->getASTContext().getSourceManager().isInMainFile(
- D->getLocation());
+ SourceManager &SM = Finder->getASTContext().getSourceManager();
+ const SourceLocation L = D->getLocation();
+ return SM.isInMainFile(L) &&
+ !utils::isSpellingLocInHeaderFile(L, SM, HeaderFileExtensions);
});
}
@@ -38,7 +42,7 @@ AST_POLYMORPHIC_MATCHER(isExternStorageClass,
} // namespace
void UseInternalLinkageCheck::registerMatchers(MatchFinder *Finder) {
- auto Common = allOf(isFirstDecl(), isInMainFile(),
+ auto Common = allOf(isFirstDecl(), isInMainFile(HeaderFileExtensions),
unless(anyOf(
// 1. internal linkage
isStaticStorageClass(), isInAnonymousNamespace(),
diff --git a/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.h b/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.h
index 358ef9ac517362..a3c1c339659036 100644
--- a/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.h
+++ b/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.h
@@ -21,12 +21,16 @@ namespace clang::tidy::misc {
class UseInternalLinkageCheck : public ClangTidyCheck {
public:
UseInternalLinkageCheck(StringRef Name, ClangTidyContext *Context)
- : ClangTidyCheck(Name, Context) {}
+ : ClangTidyCheck(Name, Context),
+ HeaderFileExtensions(Context->getHeaderFileExtensions()) {}
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
std::optional<TraversalKind> getCheckTraversalKind() const override {
return TK_IgnoreUnlessSpelledInSource;
}
+
+private:
+ FileExtensionsSet HeaderFileExtensions;
};
} // namespace clang::tidy::misc
More information about the cfe-commits
mailing list