clang-tools 22.0.0git
StaticDefinitionInAnonymousNamespaceCheck.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
10#include "clang/ASTMatchers/ASTMatchFinder.h"
11#include "clang/Lex/Lexer.h"
12
13using namespace clang::ast_matchers;
14
16
18 MatchFinder *Finder) {
19 Finder->addMatcher(
20 namedDecl(anyOf(functionDecl(isDefinition(), isStaticStorageClass()),
21 varDecl(isDefinition(), isStaticStorageClass())),
22 isInAnonymousNamespace())
23 .bind("static-def"),
24 this);
25}
26
28 const MatchFinder::MatchResult &Result) {
29 const auto *Def = Result.Nodes.getNodeAs<NamedDecl>("static-def");
30 // Skips all static definitions defined in Macro.
31 if (Def->getLocation().isMacroID())
32 return;
33
34 // Skips all static definitions in function scope.
35 const DeclContext *DC = Def->getDeclContext();
36 if (DC->getDeclKind() != Decl::Namespace)
37 return;
38
39 auto Diag =
40 diag(Def->getLocation(), "%0 is a static definition in "
41 "anonymous namespace; static is redundant here")
42 << Def;
43 Token Tok;
44 SourceLocation Loc = Def->getSourceRange().getBegin();
45 while (Loc < Def->getSourceRange().getEnd() &&
46 !Lexer::getRawToken(Loc, Tok, *Result.SourceManager, getLangOpts(),
47 true)) {
48 SourceRange TokenRange(Tok.getLocation(), Tok.getEndLoc());
49 StringRef SourceText =
50 Lexer::getSourceText(CharSourceRange::getTokenRange(TokenRange),
51 *Result.SourceManager, getLangOpts());
52 if (SourceText == "static") {
53 Diag << FixItHint::CreateRemoval(TokenRange);
54 break;
55 }
56 Loc = Tok.getEndLoc();
57 }
58}
59
60} // namespace clang::tidy::readability
void check(const ast_matchers::MatchFinder::MatchResult &Result) override