11 #include "clang/AST/ASTContext.h"
12 #include "clang/ASTMatchers/ASTMatchFinder.h"
13 #include "clang/Lex/Lexer.h"
15 using namespace clang::ast_matchers;
19 namespace readability {
22 AST_POLYMORPHIC_MATCHER(isStatic, AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
24 return Node.getStorageClass() == SC_Static;
28 void StaticDefinitionInAnonymousNamespaceCheck::registerMatchers(
30 Finder->addMatcher(namedDecl(anyOf(functionDecl(isDefinition(), isStatic()),
31 varDecl(isDefinition(), isStatic())),
32 hasParent(namespaceDecl(isAnonymous())))
37 void StaticDefinitionInAnonymousNamespaceCheck::check(
38 const MatchFinder::MatchResult &
Result) {
39 const auto *Def = Result.Nodes.getNodeAs<NamedDecl>(
"static-def");
41 if (Def->getLocation().isMacroID())
45 const DeclContext *DC = Def->getDeclContext();
46 if (DC->getDeclKind() != Decl::Namespace)
50 diag(Def->getLocation(),
"%0 is a static definition in "
51 "anonymous namespace; static is redundant here")
54 SourceLocation
Loc = Def->getSourceRange().getBegin();
55 while (Loc < Def->getSourceRange().getEnd() &&
56 !Lexer::getRawToken(Loc, Tok, *Result.SourceManager,
57 Result.Context->getLangOpts(),
true)) {
58 SourceRange TokenRange(Tok.getLocation(), Tok.getEndLoc());
59 StringRef SourceText = Lexer::getSourceText(
60 CharSourceRange::getTokenRange(TokenRange),
61 *Result.SourceManager, Result.Context->getLangOpts());
62 if (SourceText ==
"static") {
63 Diag << FixItHint::CreateRemoval(TokenRange);
66 Loc = Tok.getEndLoc();
SourceLocation Loc
'#' location in the include directive
std::unique_ptr< ast_matchers::MatchFinder > Finder