StaticDefinitionInAnonymousNamespaceCheck.cpp 2.2 KB

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