diff options
author | Aaron Ballman <aaron@aaronballman.com> | 2019-10-30 13:26:41 -0400 |
---|---|---|
committer | Aaron Ballman <aaron@aaronballman.com> | 2019-10-30 13:30:57 -0400 |
commit | 29dc0b17de6b04afa6110a040053a19b02ca1a87 (patch) | |
tree | 0944c68c2b65e98c74d8733c4cb1988adf294e1f /clang-tools-extra/clang-tidy | |
parent | e5972f2a04ee48a9190cd25f0d5b24cbca4d47f2 (diff) | |
download | llvm-29dc0b17de6b04afa6110a040053a19b02ca1a87.zip llvm-29dc0b17de6b04afa6110a040053a19b02ca1a87.tar.gz llvm-29dc0b17de6b04afa6110a040053a19b02ca1a87.tar.bz2 |
Add the readability-redundant-access-specifiers check.
This finds redundant access specifier declarations inside classes, structs, and unions.
Patch by Mateusz Mackowski.
Diffstat (limited to 'clang-tools-extra/clang-tidy')
4 files changed, 128 insertions, 0 deletions
diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt index 2d226b1..7455e10 100644 --- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt @@ -21,6 +21,7 @@ add_clang_library(clangTidyReadabilityModule NamespaceCommentCheck.cpp NonConstParameterCheck.cpp ReadabilityTidyModule.cpp + RedundantAccessSpecifiersCheck.cpp RedundantControlFlowCheck.cpp RedundantDeclarationCheck.cpp RedundantFunctionPtrDereferenceCheck.cpp diff --git a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp index 5005ba3..2fd2870 100644 --- a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp @@ -27,6 +27,7 @@ #include "MisplacedArrayIndexCheck.h" #include "NamedParameterCheck.h" #include "NonConstParameterCheck.h" +#include "RedundantAccessSpecifiersCheck.h" #include "RedundantControlFlowCheck.h" #include "RedundantDeclarationCheck.h" #include "RedundantFunctionPtrDereferenceCheck.h" @@ -82,6 +83,8 @@ public: "readability-misleading-indentation"); CheckFactories.registerCheck<MisplacedArrayIndexCheck>( "readability-misplaced-array-index"); + CheckFactories.registerCheck<RedundantAccessSpecifiersCheck>( + "readability-redundant-access-specifiers"); CheckFactories.registerCheck<RedundantFunctionPtrDereferenceCheck>( "readability-redundant-function-ptr-dereference"); CheckFactories.registerCheck<RedundantMemberInitCheck>( diff --git a/clang-tools-extra/clang-tidy/readability/RedundantAccessSpecifiersCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantAccessSpecifiersCheck.cpp new file mode 100644 index 0000000..22625c9 --- /dev/null +++ b/clang-tools-extra/clang-tidy/readability/RedundantAccessSpecifiersCheck.cpp @@ -0,0 +1,85 @@ +//===--- RedundantAccessSpecifiersCheck.cpp - clang-tidy ------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "RedundantAccessSpecifiersCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace readability { + +void RedundantAccessSpecifiersCheck::registerMatchers(MatchFinder *Finder) { + if (!getLangOpts().CPlusPlus) + return; + + Finder->addMatcher( + cxxRecordDecl(has(accessSpecDecl())).bind("redundant-access-specifiers"), + this); +} + +void RedundantAccessSpecifiersCheck::check( + const MatchFinder::MatchResult &Result) { + const auto *MatchedDecl = + Result.Nodes.getNodeAs<CXXRecordDecl>("redundant-access-specifiers"); + + const AccessSpecDecl *LastASDecl = nullptr; + for (DeclContext::specific_decl_iterator<AccessSpecDecl> + AS(MatchedDecl->decls_begin()), + ASEnd(MatchedDecl->decls_end()); + AS != ASEnd; ++AS) { + const AccessSpecDecl *ASDecl = *AS; + + // Ignore macro expansions. + if (ASDecl->getLocation().isMacroID()) { + LastASDecl = ASDecl; + continue; + } + + if (LastASDecl == nullptr) { + // First declaration. + LastASDecl = ASDecl; + + if (CheckFirstDeclaration) { + AccessSpecifier DefaultSpecifier = + MatchedDecl->isClass() ? AS_private : AS_public; + if (ASDecl->getAccess() == DefaultSpecifier) { + diag(ASDecl->getLocation(), + "redundant access specifier has the same accessibility as the " + "implicit access specifier") + << FixItHint::CreateRemoval(ASDecl->getSourceRange()); + } + } + + continue; + } + + if (LastASDecl->getAccess() == ASDecl->getAccess()) { + // Ignore macro expansions. + if (LastASDecl->getLocation().isMacroID()) { + LastASDecl = ASDecl; + continue; + } + + diag(ASDecl->getLocation(), + "redundant access specifier has the same accessibility as the " + "previous access specifier") + << FixItHint::CreateRemoval(ASDecl->getSourceRange()); + diag(LastASDecl->getLocation(), "previously declared here", + DiagnosticIDs::Note); + } else { + LastASDecl = ASDecl; + } + } +} + +} // namespace readability +} // namespace tidy +} // namespace clang diff --git a/clang-tools-extra/clang-tidy/readability/RedundantAccessSpecifiersCheck.h b/clang-tools-extra/clang-tidy/readability/RedundantAccessSpecifiersCheck.h new file mode 100644 index 0000000..2aee22f --- /dev/null +++ b/clang-tools-extra/clang-tidy/readability/RedundantAccessSpecifiersCheck.h @@ -0,0 +1,39 @@ +//===--- RedundantAccessSpecifiersCheck.h - clang-tidy ----------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTACCESSSPECIFIERSCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTACCESSSPECIFIERSCHECK_H + +#include "../ClangTidyCheck.h" + +namespace clang { +namespace tidy { +namespace readability { + +/// Detects redundant access specifiers inside classes, structs, and unions. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/readability-redundant-access-specifiers.html +class RedundantAccessSpecifiersCheck : public ClangTidyCheck { +public: + RedundantAccessSpecifiersCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context), + CheckFirstDeclaration( + Options.getLocalOrGlobal("CheckFirstDeclaration", false)) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + +private: + const bool CheckFirstDeclaration; +}; + +} // namespace readability +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTACCESSSPECIFIERSCHECK_H |