diff --git a/clang-tools-extra/clang-tidy/misc/UseAnonymousNamespaceCheck.h b/clang-tools-extra/clang-tidy/misc/UseAnonymousNamespaceCheck.h --- a/clang-tools-extra/clang-tidy/misc/UseAnonymousNamespaceCheck.h +++ b/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 { @@ -23,8 +24,7 @@ /// 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; } @@ -32,6 +32,7 @@ void check(const ast_matchers::MatchFinder::MatchResult &Result) override; private: + utils::FileExtensionsSet HeaderFileExtensions; template void processMatch(const T *MatchedDecl); }; diff --git a/clang-tools-extra/clang-tidy/misc/UseAnonymousNamespaceCheck.cpp b/clang-tools-extra/clang-tidy/misc/UseAnonymousNamespaceCheck.cpp --- a/clang-tools-extra/clang-tidy/misc/UseAnonymousNamespaceCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/UseAnonymousNamespaceCheck.cpp @@ -37,16 +37,32 @@ return false; } +UseAnonymousNamespaceCheck::UseAnonymousNamespaceCheck( + StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) { + if (!utils::parseFileExtensions(utils::defaultHeaderFileExtensions(), + HeaderFileExtensions, + utils::defaultFileExtensionDelimiters())) { + this->configurationDiag("Invalid header file extension: '%0'") + << utils::defaultHeaderFileExtensions(); + } +} + template void UseAnonymousNamespaceCheck::processMatch(const T *MatchedDecl) { + // Enforce anonymous namespaces only in source files, not headers + SourceLocation Loc = MatchedDecl->getLocation(); + SourceManager &SM = MatchedDecl->getASTContext().getSourceManager(); + if (utils::isSpellingLocInHeaderFile(Loc, SM, HeaderFileExtensions)) + return; + StringRef Type = llvm::isa(MatchedDecl) ? "variable" : "function"; if (isInAnonymousNamespace(MatchedDecl)) - diag(MatchedDecl->getLocation(), "%0 %1 declared 'static' in " - "anonymous namespace, remove 'static'") + diag(Loc, "%0 %1 declared 'static' in " + "anonymous namespace, remove 'static'") << Type << MatchedDecl; else - diag(MatchedDecl->getLocation(), - "%0 %1 declared 'static', move to anonymous namespace instead") + diag(Loc, "%0 %1 declared 'static', move to anonymous namespace instead") << Type << MatchedDecl; } @@ -54,7 +70,8 @@ Finder->addMatcher( functionDecl(isStatic(), unless(isMemberFunction())).bind("func"), this); Finder->addMatcher( - varDecl(isStatic(), unless(anyOf(isStaticLocal(), isStaticDataMember()))) + varDecl(isStatic(), unless(anyOf(isStaticLocal(), isStaticDataMember(), + hasType(isConstQualified())))) .bind("var"), this); } diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/Inputs/use-anonymous-namespace.h b/clang-tools-extra/test/clang-tidy/checkers/misc/Inputs/use-anonymous-namespace.h new file mode 100644 --- /dev/null +++ b/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(){} diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/use-anonymous-namespace.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/use-anonymous-namespace.cpp --- a/clang-tools-extra/test/clang-tidy/checkers/misc/use-anonymous-namespace.cpp +++ b/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] @@ -57,3 +58,7 @@ { static int x; } + +// OK +static const int v8{123}; +static constexpr int v9{123};