1 //===--- StaticDefinitionInAnonymousNamespaceCheck.cpp - clang-tidy--------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "StaticDefinitionInAnonymousNamespaceCheck.h"
10 #include "clang/AST/ASTContext.h"
11 #include "clang/ASTMatchers/ASTMatchFinder.h"
12 #include "clang/Lex/Lexer.h"
14 using namespace clang::ast_matchers
;
16 namespace clang::tidy::readability
{
18 void StaticDefinitionInAnonymousNamespaceCheck::registerMatchers(
19 MatchFinder
*Finder
) {
21 namedDecl(anyOf(functionDecl(isDefinition(), isStaticStorageClass()),
22 varDecl(isDefinition(), isStaticStorageClass())),
23 isInAnonymousNamespace())
28 void StaticDefinitionInAnonymousNamespaceCheck::check(
29 const MatchFinder::MatchResult
&Result
) {
30 const auto *Def
= Result
.Nodes
.getNodeAs
<NamedDecl
>("static-def");
31 // Skips all static definitions defined in Macro.
32 if (Def
->getLocation().isMacroID())
35 // Skips all static definitions in function scope.
36 const DeclContext
*DC
= Def
->getDeclContext();
37 if (DC
->getDeclKind() != Decl::Namespace
)
41 diag(Def
->getLocation(), "%0 is a static definition in "
42 "anonymous namespace; static is redundant here")
45 SourceLocation Loc
= Def
->getSourceRange().getBegin();
46 while (Loc
< Def
->getSourceRange().getEnd() &&
47 !Lexer::getRawToken(Loc
, Tok
, *Result
.SourceManager
, getLangOpts(),
49 SourceRange
TokenRange(Tok
.getLocation(), Tok
.getEndLoc());
50 StringRef SourceText
=
51 Lexer::getSourceText(CharSourceRange::getTokenRange(TokenRange
),
52 *Result
.SourceManager
, getLangOpts());
53 if (SourceText
== "static") {
54 Diag
<< FixItHint::CreateRemoval(TokenRange
);
57 Loc
= Tok
.getEndLoc();
61 } // namespace clang::tidy::readability