10#include "clang/ASTMatchers/ASTMatchFinder.h"
11#include "llvm/ADT/StringExtras.h"
12#include "llvm/ADT/StringRef.h"
22AST_MATCHER(VarDecl, isLocalVariable) {
return Node.isLocalVarDecl(); }
24FixItHint generateFixItHint(
const VarDecl *Decl,
bool IsConst) {
25 if (IsConst && (Decl->getStorageClass() != SC_Static)) {
31 char FC = Decl->getName()[0];
32 if (!llvm::isAlpha(FC) || Decl->getName().size() == 1) {
39 char SC = Decl->getName()[1];
40 if ((FC ==
'k' || FC ==
'g') && !llvm::isAlpha(SC)) {
47 auto NewName = (IsConst ?
"k" :
"g") +
48 llvm::StringRef(std::string(1, FC)).upper() +
49 Decl->getName().substr(1).str();
51 return FixItHint::CreateReplacement(
52 CharSourceRange::getTokenRange(SourceRange(Decl->getLocation())),
53 llvm::StringRef(NewName));
66 varDecl(hasGlobalStorage(), unless(hasType(isConstQualified())),
67 unless(isLocalVariable()), unless(matchesName(
"::g[A-Z]")))
70 Finder->addMatcher(varDecl(hasGlobalStorage(), hasType(isConstQualified()),
71 unless(isLocalVariable()),
72 unless(matchesName(
"::(k[A-Z])|([A-Z][A-Z0-9])")))
73 .bind(
"global_const"),
78 const MatchFinder::MatchResult &Result) {
79 if (
const auto *Decl = Result.Nodes.getNodeAs<VarDecl>(
"global_var")) {
80 if (Decl->isStaticDataMember())
82 diag(Decl->getLocation(),
83 "non-const global variable '%0' must have a name which starts with "
85 << Decl->getName() << generateFixItHint(Decl,
false);
87 if (
const auto *Decl = Result.Nodes.getNodeAs<VarDecl>(
"global_const")) {
88 if (Decl->isStaticDataMember())
90 diag(Decl->getLocation(),
91 "const global variable '%0' must have a name which starts with "
92 "an appropriate prefix")
93 << Decl->getName() << generateFixItHint(Decl,
true);
void check(const ast_matchers::MatchFinder::MatchResult &Result) override
void registerMatchers(ast_matchers::MatchFinder *Finder) override
AST_MATCHER(BinaryOperator, isRelationalOperator)