aboutsummaryrefslogtreecommitdiff
path: root/clang-tools-extra/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.cpp
diff options
context:
space:
mode:
authorHaojian Wu <hokein@google.com>2016-04-05 11:42:08 +0000
committerHaojian Wu <hokein@google.com>2016-04-05 11:42:08 +0000
commitc253f8b06be7d8fe23cb08613fad439c01d51521 (patch)
treec73a300b4bc7c02e037f790fa17d1352d9e266e4 /clang-tools-extra/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.cpp
parent591ae468201532c6ce59826d10f596c6bba37a7b (diff)
downloadllvm-c253f8b06be7d8fe23cb08613fad439c01d51521.zip
llvm-c253f8b06be7d8fe23cb08613fad439c01d51521.tar.gz
llvm-c253f8b06be7d8fe23cb08613fad439c01d51521.tar.bz2
[clang-tidy] Add a check to detect static definitions in anonymous namespace.
Summary: Fixes PR26595 Reviewers: alexfh Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D18180 llvm-svn: 265384
Diffstat (limited to 'clang-tools-extra/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.cpp')
-rw-r--r--clang-tools-extra/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.cpp72
1 files changed, 72 insertions, 0 deletions
diff --git a/clang-tools-extra/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.cpp b/clang-tools-extra/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.cpp
new file mode 100644
index 0000000..9de2d40
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.cpp
@@ -0,0 +1,72 @@
+//===--- StaticDefinitionInAnonymousNamespaceCheck.cpp - clang-tidy--------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "StaticDefinitionInAnonymousNamespaceCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace readability {
+
+namespace {
+AST_POLYMORPHIC_MATCHER(isStatic, AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
+ VarDecl)) {
+ return Node.getStorageClass() == SC_Static;
+}
+} // namespace
+
+void StaticDefinitionInAnonymousNamespaceCheck::registerMatchers(
+ MatchFinder *Finder) {
+ Finder->addMatcher(namedDecl(anyOf(functionDecl(isDefinition(), isStatic()),
+ varDecl(isDefinition(), isStatic())),
+ hasParent(namespaceDecl(isAnonymous())))
+ .bind("static-def"),
+ this);
+}
+
+void StaticDefinitionInAnonymousNamespaceCheck::check(
+ const MatchFinder::MatchResult &Result) {
+ const auto *Def = Result.Nodes.getNodeAs<NamedDecl>("static-def");
+ // Skips all static definitions defined in Macro.
+ if (Def->getLocation().isMacroID())
+ return;
+
+ // Skips all static definitions in function scope.
+ const DeclContext *DC = Def->getDeclContext();
+ if (DC->getDeclKind() != Decl::Namespace)
+ return;
+
+ auto Diag =
+ diag(Def->getLocation(), "%0 is a static definition in "
+ "anonymous namespace; static is redundant here")
+ << Def;
+ Token Tok;
+ SourceLocation Loc = Def->getSourceRange().getBegin();
+ while (Loc < Def->getSourceRange().getEnd() &&
+ !Lexer::getRawToken(Loc, Tok, *Result.SourceManager,
+ Result.Context->getLangOpts(), true)) {
+ SourceRange TokenRange(Tok.getLocation(), Tok.getEndLoc());
+ StringRef SourceText = Lexer::getSourceText(
+ CharSourceRange::getTokenRange(TokenRange),
+ *Result.SourceManager, Result.Context->getLangOpts());
+ if (SourceText == "static") {
+ Diag << FixItHint::CreateRemoval(TokenRange);
+ break;
+ }
+ Loc = Tok.getEndLoc();
+ }
+}
+
+} // namespace readability
+} // namespace tidy
+} // namespace clang