10 #include "clang/AST/ASTContext.h"
11 #include "clang/ASTMatchers/ASTMatchFinder.h"
22 return std::distance(Node.method_begin(), Node.method_end()) != 0;
25 AST_MATCHER(CXXRecordDecl, hasNonStaticNonImplicitMethod) {
26 return hasMethod(unless(anyOf(isStaticStorageClass(), isImplicit())))
27 .matches(Node, Finder,
Builder);
30 AST_MATCHER(CXXRecordDecl, hasNonPublicMemberVariable) {
31 return cxxRecordDecl(has(fieldDecl(unless(
isPublic()))))
32 .matches(Node, Finder,
Builder);
35 AST_POLYMORPHIC_MATCHER_P(
boolean, AST_POLYMORPHIC_SUPPORTED_TYPES(Stmt,
Decl),
42 NonPrivateMemberVariablesInClassesCheck::
43 NonPrivateMemberVariablesInClassesCheck(StringRef
Name,
46 IgnoreClassesWithAllMemberVariablesBeingPublic(
47 Options.get(
"IgnoreClassesWithAllMemberVariablesBeingPublic", false)),
48 IgnorePublicMemberVariables(
49 Options.get(
"IgnorePublicMemberVariables", false)) {}
53 Options.
store(Opts,
"IgnoreClassesWithAllMemberVariablesBeingPublic",
54 IgnoreClassesWithAllMemberVariablesBeingPublic);
56 IgnorePublicMemberVariables);
60 MatchFinder *Finder) {
62 auto ShouldIgnoreRecord =
63 allOf(
boolean(IgnoreClassesWithAllMemberVariablesBeingPublic),
64 unless(hasNonPublicMemberVariable()));
70 auto InterestingField = IgnorePublicMemberVariables
71 ? fieldDecl(isProtected())
72 : fieldDecl(unless(isPrivate()));
78 Finder->addMatcher(cxxRecordDecl(anyOf(isStruct(), isClass()), hasMethods(),
79 hasNonStaticNonImplicitMethod(),
80 unless(ShouldIgnoreRecord),
81 forEach(InterestingField.bind(
"field")))
87 const MatchFinder::MatchResult &Result) {
88 const auto *
Field = Result.Nodes.getNodeAs<FieldDecl>(
"field");
89 assert(
Field &&
"We should have the field we are going to complain about");
91 diag(
Field->getLocation(),
"member variable %0 has %1 visibility")