carlosgalvezp updated this revision to Diff 481257.
carlosgalvezp added a comment.

Rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139113/new/

https://reviews.llvm.org/D139113

Files:
  clang-tools-extra/clang-tidy/misc/UseAnonymousNamespaceCheck.cpp
  clang-tools-extra/clang-tidy/misc/UseAnonymousNamespaceCheck.h
  clang-tools-extra/docs/clang-tidy/checks/misc/use-anonymous-namespace.rst
  
clang-tools-extra/test/clang-tidy/checkers/misc/Inputs/use-anonymous-namespace.h
  clang-tools-extra/test/clang-tidy/checkers/misc/use-anonymous-namespace.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/misc/use-anonymous-namespace.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/misc/use-anonymous-namespace.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/misc/use-anonymous-namespace.cpp
@@ -1,4 +1,5 @@
-// RUN: %check_clang_tidy %s misc-use-anonymous-namespace %t
+// RUN: %check_clang_tidy %s misc-use-anonymous-namespace %t -- -header-filter=.* -- -I%S/Inputs
+#include "use-anonymous-namespace.h"
 
 static void f1();
 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: function 'f1' declared 'static', move to anonymous namespace instead [misc-use-anonymous-namespace]
@@ -41,3 +42,7 @@
 {
   static int x;
 }
+
+// OK
+static const int v8{123};
+static constexpr int v9{123};
Index: clang-tools-extra/test/clang-tidy/checkers/misc/Inputs/use-anonymous-namespace.h
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/misc/Inputs/use-anonymous-namespace.h
@@ -0,0 +1,3 @@
+// Should not warn here, do not require anonymous namespaces in headers
+static int gv{123};
+static void gf(){}
Index: clang-tools-extra/docs/clang-tidy/checks/misc/use-anonymous-namespace.rst
===================================================================
--- clang-tools-extra/docs/clang-tidy/checks/misc/use-anonymous-namespace.rst
+++ clang-tools-extra/docs/clang-tidy/checks/misc/use-anonymous-namespace.rst
@@ -11,6 +11,14 @@
 keep C compatibility [1]. ``static`` is an overloaded term with different meanings in
 different contexts, so it can create confusion.
 
+The following uses of ``static`` will *not* be diagnosed:
+
+* Functions or variables in header files, since anonymous namespaces in headers
+  is considered an antipattern. Allowed header file extensions can be configured
+  via the `HeaderFileExtensions` option (see below).
+* ``const`` or ``constexpr`` variables, since they already have implicit internal
+  linkage in C++.
+
 Examples:
 
 .. code-block:: c++
@@ -25,4 +33,14 @@
     int x;
   } // namespace
 
+Options
+-------
+
+.. option:: HeaderFileExtensions
+
+   A semicolon-separated list of filename extensions of header files (the filename
+   extensions should not include "." prefix). Default is ";h;hh;hpp;hxx".
+   For extension-less header files, using an empty string or leaving an
+   empty string between ";" if there are other filename extensions.
+
 [1] `Undeprecating static <https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1012>`_
Index: clang-tools-extra/clang-tidy/misc/UseAnonymousNamespaceCheck.h
===================================================================
--- clang-tools-extra/clang-tidy/misc/UseAnonymousNamespaceCheck.h
+++ clang-tools-extra/clang-tidy/misc/UseAnonymousNamespaceCheck.h
@@ -10,6 +10,7 @@
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_USEANONYMOUSNAMESPACECHECK_H
 
 #include "../ClangTidyCheck.h"
+#include "../utils/FileExtensionsUtils.h"
 
 namespace clang {
 namespace tidy {
@@ -18,19 +19,29 @@
 /// Warns when using 'static' functions or variables at global scope, and
 /// suggests moving them to an anonymous namespace.
 ///
+/// The check supports these options:
+///   - `HeaderFileExtensions`: a semicolon-separated list of filename
+///     extensions of header files (The filename extension should not contain
+///     "." prefix). ";h;hh;hpp;hxx" by default.
+///
+///     For extension-less header files, using an empty string or leaving an
+///     empty string between ";" if there are other filename extensions.
+///
 /// For the user-facing documentation see:
 /// http://clang.llvm.org/extra/clang-tidy/checks/modernize/use-anonymous-namespace.html
 class UseAnonymousNamespaceCheck : public ClangTidyCheck {
 public:
-  UseAnonymousNamespaceCheck(StringRef Name, ClangTidyContext *Context)
-      : ClangTidyCheck(Name, Context) {}
+  UseAnonymousNamespaceCheck(StringRef Name, ClangTidyContext *Context);
   bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
     return LangOpts.CPlusPlus;
   }
+  void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
 
 private:
+  const StringRef RawStringHeaderFileExtensions;
+  utils::FileExtensionsSet HeaderFileExtensions;
   template <typename T> void processMatch(const T *MatchedDecl);
 };
 
Index: clang-tools-extra/clang-tidy/misc/UseAnonymousNamespaceCheck.cpp
===================================================================
--- clang-tools-extra/clang-tidy/misc/UseAnonymousNamespaceCheck.cpp
+++ clang-tools-extra/clang-tidy/misc/UseAnonymousNamespaceCheck.cpp
@@ -21,6 +21,15 @@
   return Node.getStorageClass() == SC_Static;
 }
 
+AST_POLYMORPHIC_MATCHER_P(isInHeaderFile,
+                          AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
+                                                          VarDecl),
+                          utils::FileExtensionsSet, HeaderFileExtensions) {
+  return utils::isExpansionLocInHeaderFile(
+      Node.getBeginLoc(), Finder->getASTContext().getSourceManager(),
+      HeaderFileExtensions);
+}
+
 AST_MATCHER(FunctionDecl, isMemberFunction) {
   return llvm::isa<CXXMethodDecl>(&Node);
 }
@@ -31,6 +40,24 @@
 }
 } // namespace
 
+UseAnonymousNamespaceCheck::UseAnonymousNamespaceCheck(
+    StringRef Name, ClangTidyContext *Context)
+    : ClangTidyCheck(Name, Context),
+      RawStringHeaderFileExtensions(Options.getLocalOrGlobal(
+          "HeaderFileExtensions", utils::defaultHeaderFileExtensions())) {
+  if (!utils::parseFileExtensions(RawStringHeaderFileExtensions,
+                                  HeaderFileExtensions,
+                                  utils::defaultFileExtensionDelimiters())) {
+    this->configurationDiag("Invalid header file extension: '%0'")
+        << RawStringHeaderFileExtensions;
+  }
+}
+
+void UseAnonymousNamespaceCheck::storeOptions(
+    ClangTidyOptions::OptionMap &Opts) {
+  Options.store(Opts, "HeaderFileExtensions", RawStringHeaderFileExtensions);
+}
+
 template <typename T>
 void UseAnonymousNamespaceCheck::processMatch(const T *MatchedDecl) {
   StringRef Type = llvm::isa<VarDecl>(MatchedDecl) ? "variable" : "function";
@@ -42,12 +69,15 @@
 void UseAnonymousNamespaceCheck::registerMatchers(MatchFinder *Finder) {
   Finder->addMatcher(
       functionDecl(isStatic(),
-                   unless(anyOf(isInAnonymousNamespace(), isMemberFunction())))
+                   unless(anyOf(isInHeaderFile(HeaderFileExtensions),
+                                isInAnonymousNamespace(), isMemberFunction())))
           .bind("func"),
       this);
   Finder->addMatcher(
-      varDecl(isStatic(), unless(anyOf(isInAnonymousNamespace(),
-                                       isStaticLocal(), isStaticDataMember())))
+      varDecl(isStatic(),
+              unless(anyOf(isInHeaderFile(HeaderFileExtensions),
+                           isInAnonymousNamespace(), isStaticLocal(),
+                           isStaticDataMember(), hasType(isConstQualified()))))
           .bind("var"),
       this);
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to