
Removed the uses of the allOf() matcher inside node matchers that are implicit allOf(). Replaced uses of allOf() with the explicit node matcher where it makes matchers more readable. Replace anyOf(hasName(), hasName(), ...) with the more efficient and readable hasAnyName(). llvm-svn: 347520
92 lines
3.3 KiB
C++
92 lines
3.3 KiB
C++
//===--- NonPrivateMemberVariablesInClassesCheck.cpp - clang-tidy ---------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "NonPrivateMemberVariablesInClassesCheck.h"
|
|
#include "clang/AST/ASTContext.h"
|
|
#include "clang/ASTMatchers/ASTMatchFinder.h"
|
|
|
|
using namespace clang::ast_matchers;
|
|
|
|
namespace clang {
|
|
namespace tidy {
|
|
namespace misc {
|
|
|
|
namespace {
|
|
|
|
AST_MATCHER(CXXRecordDecl, hasMethods) {
|
|
return std::distance(Node.method_begin(), Node.method_end()) != 0;
|
|
}
|
|
|
|
AST_MATCHER(CXXRecordDecl, hasNonStaticMethod) {
|
|
return hasMethod(unless(isStaticStorageClass()))
|
|
.matches(Node, Finder, Builder);
|
|
}
|
|
|
|
AST_MATCHER(CXXRecordDecl, hasNonPublicMemberVariable) {
|
|
return cxxRecordDecl(has(fieldDecl(unless(isPublic()))))
|
|
.matches(Node, Finder, Builder);
|
|
}
|
|
|
|
AST_POLYMORPHIC_MATCHER_P(boolean, AST_POLYMORPHIC_SUPPORTED_TYPES(Stmt, Decl),
|
|
bool, Boolean) {
|
|
return Boolean;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
NonPrivateMemberVariablesInClassesCheck::
|
|
NonPrivateMemberVariablesInClassesCheck(StringRef Name,
|
|
ClangTidyContext *Context)
|
|
: ClangTidyCheck(Name, Context),
|
|
IgnoreClassesWithAllMemberVariablesBeingPublic(
|
|
Options.get("IgnoreClassesWithAllMemberVariablesBeingPublic", false)),
|
|
IgnorePublicMemberVariables(
|
|
Options.get("IgnorePublicMemberVariables", false)) {}
|
|
|
|
void NonPrivateMemberVariablesInClassesCheck::registerMatchers(
|
|
MatchFinder *Finder) {
|
|
if (!getLangOpts().CPlusPlus)
|
|
return;
|
|
|
|
// We can ignore structs/classes with all member variables being public.
|
|
auto ShouldIgnoreRecord =
|
|
allOf(boolean(IgnoreClassesWithAllMemberVariablesBeingPublic),
|
|
unless(hasNonPublicMemberVariable()));
|
|
|
|
// There are three visibility types: public, protected, private.
|
|
// If we are ok with public fields, then we only want to complain about
|
|
// protected fields, else we want to complain about all non-private fields.
|
|
// We can ignore public member variables in structs/classes, in unions.
|
|
auto InterestingField = fieldDecl(
|
|
IgnorePublicMemberVariables ? isProtected() : unless(isPrivate()));
|
|
|
|
// We only want the records that not only contain the mutable data (non-static
|
|
// member variables), but also have some logic (non-static member functions).
|
|
// We may optionally ignore records where all the member variables are public.
|
|
Finder->addMatcher(cxxRecordDecl(anyOf(isStruct(), isClass()), hasMethods(),
|
|
hasNonStaticMethod(),
|
|
unless(ShouldIgnoreRecord),
|
|
forEach(InterestingField.bind("field")))
|
|
.bind("record"),
|
|
this);
|
|
}
|
|
|
|
void NonPrivateMemberVariablesInClassesCheck::check(
|
|
const MatchFinder::MatchResult &Result) {
|
|
const auto *Field = Result.Nodes.getNodeAs<FieldDecl>("field");
|
|
assert(Field && "We should have the field we are going to complain about");
|
|
|
|
diag(Field->getLocation(), "member variable %0 has %1 visibility")
|
|
<< Field << Field->getAccess();
|
|
}
|
|
|
|
} // namespace misc
|
|
} // namespace tidy
|
|
} // namespace clang
|