/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "EmptyBasesChecker.h" #include "CustomMatchers.h" namespace clang { namespace ast_matchers { AST_MATCHER_P(CXXRecordDecl, emptyBaseCountAtLeast, unsigned, N) { unsigned NumEmptyBases = 0; for (const auto &Base : Node.bases()) { if (const Type *BaseType = Base.getType().getTypePtrOrNull()) { if (const CXXRecordDecl *CRD = BaseType->getAsCXXRecordDecl(); CRD && CRD->isEmpty()) NumEmptyBases += 1; } } return NumEmptyBases >= N; } AST_MATCHER(CXXRecordDecl, hasMozEmptyBasesAttr) { return Node.hasAttr(); } } // namespace ast_matchers } // namespace clang void EmptyBasesChecker::registerMatchers(MatchFinder *AstMatcher) { AstMatcher->addMatcher(cxxRecordDecl(isDefinition(), isFirstParty(), emptyBaseCountAtLeast(2), unless(hasMozEmptyBasesAttr())) .bind("class"), this); } void EmptyBasesChecker::check(const MatchFinder::MatchResult &Result) { const CXXRecordDecl *Cls = Result.Nodes.getNodeAs("class"); diag(Cls->getBeginLoc(), "Missing MOZ_EMPTY_BASES", DiagnosticIDs::Error); }