clang-tools 10.0.0

RedundantAccessSpecifiersCheck.cpp
Go to the documentation of this file.
1 //===--- RedundantAccessSpecifiersCheck.cpp - clang-tidy ------------------===//
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "RedundantAccessSpecifiersCheck.h"
10 #include "clang/AST/ASTContext.h"
11 #include "clang/ASTMatchers/ASTMatchFinder.h"
12
13 using namespace clang::ast_matchers;
14
15 namespace clang {
16 namespace tidy {
17 namespace readability {
18
19 void RedundantAccessSpecifiersCheck::registerMatchers(MatchFinder *Finder) {
20 if (!getLangOpts().CPlusPlus)
21 return;
22
23 Finder->addMatcher(
24 cxxRecordDecl(has(accessSpecDecl())).bind("redundant-access-specifiers"),
25 this);
26 }
27
28 void RedundantAccessSpecifiersCheck::check(
29 const MatchFinder::MatchResult &Result) {
30 const auto *MatchedDecl =
31 Result.Nodes.getNodeAs<CXXRecordDecl>("redundant-access-specifiers");
32
33 const AccessSpecDecl *LastASDecl = nullptr;
34 for (DeclContext::specific_decl_iterator<AccessSpecDecl>
35 AS(MatchedDecl->decls_begin()),
36 ASEnd(MatchedDecl->decls_end());
37 AS != ASEnd; ++AS) {
38 const AccessSpecDecl *ASDecl = *AS;
39
40 // Ignore macro expansions.
41 if (ASDecl->getLocation().isMacroID()) {
42 LastASDecl = ASDecl;
43 continue;
44 }
45
46 if (LastASDecl == nullptr) {
47 // First declaration.
48 LastASDecl = ASDecl;
49
50 if (CheckFirstDeclaration) {
51 AccessSpecifier DefaultSpecifier =
52 MatchedDecl->isClass() ? AS_private : AS_public;
53 if (ASDecl->getAccess() == DefaultSpecifier) {
54 diag(ASDecl->getLocation(),
55 "redundant access specifier has the same accessibility as the "
56 "implicit access specifier")
57 << FixItHint::CreateRemoval(ASDecl->getSourceRange());
58 }
59 }
60
61 continue;
62 }
63
64 if (LastASDecl->getAccess() == ASDecl->getAccess()) {
65 // Ignore macro expansions.
66 if (LastASDecl->getLocation().isMacroID()) {
67 LastASDecl = ASDecl;
68 continue;
69 }
70
71 diag(ASDecl->getLocation(),
72 "redundant access specifier has the same accessibility as the "
73 "previous access specifier")
74 << FixItHint::CreateRemoval(ASDecl->getSourceRange());
75 diag(LastASDecl->getLocation(), "previously declared here",
76 DiagnosticIDs::Note);
77 } else {
78 LastASDecl = ASDecl;
79 }
80 }
81 }
82
83 } // namespace readability
84 } // namespace tidy
85 } // namespace clang
clang::ast_matchers
Definition: AbseilMatcher.h:14
RedundantAccessSpecifiersCheck.h
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27