10 #include "clang/AST/ASTContext.h"
11 #include "clang/ASTMatchers/ASTMatchFinder.h"
12 #include "clang/ASTMatchers/ASTMatchers.h"
18 namespace cppcoreguidelines {
21 AST_MATCHER(VarDecl, isLocalVarDecl) {
return Node.isLocalVarDecl(); }
24 void AvoidNonConstGlobalVariablesCheck::registerMatchers(MatchFinder *Finder) {
25 auto GlobalVariable = varDecl(
28 isLocalVarDecl(), isConstexpr(), hasType(isConstQualified()),
29 hasType(referenceType()))));
32 auto GlobalReferenceToNonConst =
33 varDecl(hasGlobalStorage(), hasType(referenceType()),
34 unless(hasType(references(qualType(isConstQualified())))));
36 auto GlobalPointerToNonConst =
37 varDecl(hasGlobalStorage(),
38 hasType(pointerType(pointee(unless(isConstQualified())))));
40 Finder->addMatcher(GlobalVariable.bind(
"non-const_variable"),
this);
41 Finder->addMatcher(GlobalReferenceToNonConst.bind(
"indirection_to_non-const"),
43 Finder->addMatcher(GlobalPointerToNonConst.bind(
"indirection_to_non-const"),
47 void AvoidNonConstGlobalVariablesCheck::check(
48 const MatchFinder::MatchResult &Result) {
50 if (
const auto *Variable =
51 Result.Nodes.getNodeAs<VarDecl>(
"non-const_variable")) {
52 diag(Variable->getLocation(),
"variable %0 is non-const and globally "
53 "accessible, consider making it const")
60 Result.Nodes.getNodeAs<VarDecl>(
"indirection_to_non-const")) {
61 diag(VD->getLocation(),
62 "variable %0 provides global access to a non-const object; consider "
63 "making the %select{referenced|pointed-to}1 data 'const'")
65 << VD->getType()->isPointerType();