79 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "RedundantAccessSpecifiersCheck.h"10#include "clang/AST/ASTContext.h"11#include "clang/ASTMatchers/ASTMatchFinder.h"12 13using namespace clang::ast_matchers;14 15namespace clang::tidy::readability {16 17void RedundantAccessSpecifiersCheck::registerMatchers(MatchFinder *Finder) {18 Finder->addMatcher(19 cxxRecordDecl(has(accessSpecDecl())).bind("redundant-access-specifiers"),20 this);21}22 23void RedundantAccessSpecifiersCheck::check(24 const MatchFinder::MatchResult &Result) {25 const auto *MatchedDecl =26 Result.Nodes.getNodeAs<CXXRecordDecl>("redundant-access-specifiers");27 28 const AccessSpecDecl *LastASDecl = nullptr;29 for (DeclContext::specific_decl_iterator<AccessSpecDecl>30 AS(MatchedDecl->decls_begin()),31 ASEnd(MatchedDecl->decls_end());32 AS != ASEnd; ++AS) {33 const AccessSpecDecl *ASDecl = *AS;34 35 // Ignore macro expansions.36 if (ASDecl->getLocation().isMacroID()) {37 LastASDecl = ASDecl;38 continue;39 }40 41 if (LastASDecl == nullptr) {42 // First declaration.43 LastASDecl = ASDecl;44 45 if (CheckFirstDeclaration) {46 const AccessSpecifier DefaultSpecifier =47 MatchedDecl->isClass() ? AS_private : AS_public;48 if (ASDecl->getAccess() == DefaultSpecifier) {49 diag(ASDecl->getLocation(),50 "redundant access specifier has the same accessibility as the "51 "implicit access specifier")52 << FixItHint::CreateRemoval(ASDecl->getSourceRange());53 }54 }55 56 continue;57 }58 59 if (LastASDecl->getAccess() == ASDecl->getAccess()) {60 // Ignore macro expansions.61 if (LastASDecl->getLocation().isMacroID()) {62 LastASDecl = ASDecl;63 continue;64 }65 66 diag(ASDecl->getLocation(),67 "redundant access specifier has the same accessibility as the "68 "previous access specifier")69 << FixItHint::CreateRemoval(ASDecl->getSourceRange());70 diag(LastASDecl->getLocation(), "previously declared here",71 DiagnosticIDs::Note);72 } else {73 LastASDecl = ASDecl;74 }75 }76}77 78} // namespace clang::tidy::readability79