72 MatchFinder *Finder) {
73 const auto IgnoredDecl =
75 const auto FilterDestructors =
76 CheckDestructors ? decl() : decl(unless(cxxDestructorDecl()));
77 const auto FilterOperators =
78 CheckOperators ? namedDecl() : namedDecl(unless(isOperatorDecl()));
81 isVirtual(), FilterDestructors, FilterOperators,
83 cxxRecordDecl(unless(isExpansionInSystemHeader())).bind(
"class")),
84 forEachOverridden(cxxMethodDecl(ofClass(cxxRecordDecl().bind(
"base")),
92 const MatchFinder::MatchResult &Result) {
93 const auto *
const MatchedFunction =
94 Result.Nodes.getNodeAs<FunctionDecl>(
"func");
95 if (!MatchedFunction->isCanonicalDecl())
98 const auto *
const ParentClass =
99 Result.Nodes.getNodeAs<CXXRecordDecl>(
"class");
100 const auto *
const BaseClass = Result.Nodes.getNodeAs<CXXRecordDecl>(
"base");
102 if (!ParentClass->isDerivedFrom(BaseClass, Paths))
105 const auto *
const OverriddenFunction =
106 Result.Nodes.getNodeAs<FunctionDecl>(
"base_func");
107 const AccessSpecifier ActualAccess = MatchedFunction->getAccess();
108 AccessSpecifier OverriddenAccess = OverriddenFunction->getAccess();
110 const CXXBaseSpecifier *InheritanceWithStrictVisibility =
nullptr;
111 for (
const CXXBasePath &Path : Paths) {
112 for (
const CXXBasePathElement &Elem : Path) {
113 if (Elem.Base->getAccessSpecifier() > OverriddenAccess) {
114 OverriddenAccess = Elem.Base->getAccessSpecifier();
115 InheritanceWithStrictVisibility = Elem.Base;
120 if (ActualAccess != OverriddenAccess) {
122 ActualAccess > OverriddenAccess)
125 ActualAccess < OverriddenAccess)
128 if (InheritanceWithStrictVisibility) {
129 diag(MatchedFunction->getLocation(),
130 "visibility of function %0 is changed from %1 (through %1 "
131 "inheritance of class %2) to %3")
132 << MatchedFunction << OverriddenAccess
133 << InheritanceWithStrictVisibility->getType() << ActualAccess;
134 diag(InheritanceWithStrictVisibility->getBeginLoc(),
135 "%0 is inherited as %1 here", DiagnosticIDs::Note)
136 << InheritanceWithStrictVisibility->getType() << OverriddenAccess;
138 diag(MatchedFunction->getLocation(),
139 "visibility of function %0 is changed from %1 in class %2 to %3")
140 << MatchedFunction << OverriddenAccess << BaseClass << ActualAccess;
142 diag(OverriddenFunction->getLocation(),
"function declared here as %0",
144 << OverriddenFunction->getAccess();
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.