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,
82 ofClass(cxxRecordDecl().bind(
"class")),
83 forEachOverridden(cxxMethodDecl(ofClass(cxxRecordDecl().bind(
"base")),
91 const MatchFinder::MatchResult &Result) {
92 const auto *
const MatchedFunction =
93 Result.Nodes.getNodeAs<FunctionDecl>(
"func");
94 if (!MatchedFunction->isCanonicalDecl())
97 const auto *
const ParentClass =
98 Result.Nodes.getNodeAs<CXXRecordDecl>(
"class");
99 const auto *
const BaseClass = Result.Nodes.getNodeAs<CXXRecordDecl>(
"base");
101 if (!ParentClass->isDerivedFrom(BaseClass, Paths))
104 const auto *
const OverriddenFunction =
105 Result.Nodes.getNodeAs<FunctionDecl>(
"base_func");
106 const AccessSpecifier ActualAccess = MatchedFunction->getAccess();
107 AccessSpecifier OverriddenAccess = OverriddenFunction->getAccess();
109 const CXXBaseSpecifier *InheritanceWithStrictVisibility =
nullptr;
110 for (
const CXXBasePath &Path : Paths) {
111 for (
const CXXBasePathElement &Elem : Path) {
112 if (Elem.Base->getAccessSpecifier() > OverriddenAccess) {
113 OverriddenAccess = Elem.Base->getAccessSpecifier();
114 InheritanceWithStrictVisibility = Elem.Base;
119 if (ActualAccess != OverriddenAccess) {
121 ActualAccess > OverriddenAccess)
124 ActualAccess < OverriddenAccess)
127 if (InheritanceWithStrictVisibility) {
128 diag(MatchedFunction->getLocation(),
129 "visibility of function %0 is changed from %1 (through %1 "
130 "inheritance of class %2) to %3")
131 << MatchedFunction << OverriddenAccess
132 << InheritanceWithStrictVisibility->getType() << ActualAccess;
133 diag(InheritanceWithStrictVisibility->getBeginLoc(),
134 "%0 is inherited as %1 here", DiagnosticIDs::Note)
135 << InheritanceWithStrictVisibility->getType() << OverriddenAccess;
137 diag(MatchedFunction->getLocation(),
138 "visibility of function %0 is changed from %1 in class %2 to %3")
139 << MatchedFunction << OverriddenAccess << BaseClass << ActualAccess;
141 diag(OverriddenFunction->getLocation(),
"function declared here as %0",
143 << OverriddenFunction->getAccess();
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.