m4tx updated this revision to Diff 178543.
m4tx added a comment.

Don't use `CXXRecordDecl::accessSpecs()`, use unique comments in tests.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D55793/new/

https://reviews.llvm.org/D55793

Files:
  clang-tidy/readability/CMakeLists.txt
  clang-tidy/readability/DuplicatedAccessSpecifiersCheck.cpp
  clang-tidy/readability/DuplicatedAccessSpecifiersCheck.h
  clang-tidy/readability/ReadabilityTidyModule.cpp
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/readability-duplicated-access-specifiers.rst
  test/clang-tidy/readability-duplicated-access-specifiers.cpp

Index: test/clang-tidy/readability-duplicated-access-specifiers.cpp
===================================================================
--- /dev/null
+++ test/clang-tidy/readability-duplicated-access-specifiers.cpp
@@ -0,0 +1,74 @@
+// RUN: %check_clang_tidy %s readability-duplicated-access-specifiers %t
+
+class FooPublic {
+public:
+  int a;
+public: // comment-0
+  // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: duplicated access specifier [readability-duplicated-access-specifiers]
+  // CHECK-MESSAGES: :[[@LINE-4]]:1: note: previously declared here
+  // CHECK-FIXES: {{^}}// comment-0{{$}}
+  int b;
+private:
+  int c;
+};
+
+struct StructPublic {
+public:
+  int a;
+public: // comment-1
+  // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: duplicated access specifier [readability-duplicated-access-specifiers]
+  // CHECK-MESSAGES: :[[@LINE-4]]:1: note: previously declared here
+  // CHECK-FIXES: {{^}}// comment-1{{$}}
+  int b;
+private:
+  int c;
+};
+
+union UnionPublic {
+public:
+  int a;
+public: // comment-2
+  // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: duplicated access specifier [readability-duplicated-access-specifiers]
+  // CHECK-MESSAGES: :[[@LINE-4]]:1: note: previously declared here
+  // CHECK-FIXES: {{^}}// comment-2{{$}}
+  int b;
+private:
+  int c;
+};
+
+class FooProtected {
+protected:
+  int a;
+protected: // comment-3
+  // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: duplicated access specifier [readability-duplicated-access-specifiers]
+  // CHECK-MESSAGES: :[[@LINE-4]]:1: note: previously declared here
+  // CHECK-FIXES: {{^}}// comment-3{{$}}
+  int b;
+private:
+  int c;
+};
+
+class FooPrivate {
+private:
+  int a;
+private: // comment-4
+  // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: duplicated access specifier [readability-duplicated-access-specifiers]
+  // CHECK-MESSAGES: :[[@LINE-4]]:1: note: previously declared here
+  // CHECK-FIXES: {{^}}// comment-4{{$}}
+  int b;
+public:
+  int c;
+};
+
+class Valid {
+private:
+  int a;
+public:
+  int b;
+private:
+  int c;
+protected:
+  int d;
+public:
+  int e;
+};
Index: docs/clang-tidy/checks/readability-duplicated-access-specifiers.rst
===================================================================
--- /dev/null
+++ docs/clang-tidy/checks/readability-duplicated-access-specifiers.rst
@@ -0,0 +1,26 @@
+.. title:: clang-tidy - readability-duplicated-access-specifiers
+
+readability-duplicated-access-specifiers
+========================================
+
+Finds classes, structs and unions containing duplicated member access specifiers
+that can be removed.
+
+Examples:
+
+.. code-block:: c++
+
+  class Foo {
+  public:
+    int x;
+    int y;
+  public:
+    int z;
+  protected:
+    int a;
+  public:
+    int c;
+  }
+
+In the example above, the second ``public`` declaration can be removed without
+any changes of behavior.
Index: docs/clang-tidy/checks/list.rst
===================================================================
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -238,6 +238,7 @@
    readability-container-size-empty
    readability-delete-null-pointer
    readability-deleted-default
+   readability-duplicated-access-specifiers
    readability-else-after-return
    readability-function-size
    readability-identifier-naming
Index: docs/ReleaseNotes.rst
===================================================================
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -192,6 +192,12 @@
   Checks for functions with a ``const``-qualified return type and recommends
   removal of the ``const`` keyword.
 
+- New :doc:`readability-duplicated-access-specifiers
+  <clang-tidy/checks/readability-duplicated-access-specifiers>` check.
+
+  Finds classes, structs, and unions that contain duplicated member
+  access specifiers.
+
 - New :doc:`readability-magic-numbers
   <clang-tidy/checks/readability-magic-numbers>` check.
 
Index: clang-tidy/readability/ReadabilityTidyModule.cpp
===================================================================
--- clang-tidy/readability/ReadabilityTidyModule.cpp
+++ clang-tidy/readability/ReadabilityTidyModule.cpp
@@ -16,6 +16,7 @@
 #include "ContainerSizeEmptyCheck.h"
 #include "DeleteNullPointerCheck.h"
 #include "DeletedDefaultCheck.h"
+#include "DuplicatedAccessSpecifiersCheck.h"
 #include "ElseAfterReturnCheck.h"
 #include "FunctionSizeCheck.h"
 #include "IdentifierNamingCheck.h"
@@ -61,6 +62,8 @@
         "readability-delete-null-pointer");
     CheckFactories.registerCheck<DeletedDefaultCheck>(
         "readability-deleted-default");
+    CheckFactories.registerCheck<DuplicatedAccessSpecifiersCheck>(
+        "readability-duplicated-access-specifiers");
     CheckFactories.registerCheck<ElseAfterReturnCheck>(
         "readability-else-after-return");
     CheckFactories.registerCheck<FunctionSizeCheck>(
Index: clang-tidy/readability/DuplicatedAccessSpecifiersCheck.h
===================================================================
--- /dev/null
+++ clang-tidy/readability/DuplicatedAccessSpecifiersCheck.h
@@ -0,0 +1,35 @@
+//===--- DuplicatedAccessSpecifiersCheck.h - clang-tidy ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_DUPLICATEDACCESSSPECIFIERSCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_DUPLICATEDACCESSSPECIFIERSCHECK_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace readability {
+
+/// Detects duplicated access specifiers inside classes, structs, and unions.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/readability-duplicated-access-specifiers.html
+class DuplicatedAccessSpecifiersCheck : public ClangTidyCheck {
+public:
+  DuplicatedAccessSpecifiersCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace readability
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_DUPLICATEDACCESSSPECIFIERSCHECK_H
Index: clang-tidy/readability/DuplicatedAccessSpecifiersCheck.cpp
===================================================================
--- /dev/null
+++ clang-tidy/readability/DuplicatedAccessSpecifiersCheck.cpp
@@ -0,0 +1,53 @@
+//===--- DuplicatedAccessSpecifiersCheck.cpp - clang-tidy -----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DuplicatedAccessSpecifiersCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace readability {
+
+void DuplicatedAccessSpecifiersCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(
+      cxxRecordDecl(has(accessSpecDecl()))
+          .bind("duplicated-access-specifiers"), this);
+}
+
+void DuplicatedAccessSpecifiersCheck::check(
+    const MatchFinder::MatchResult &Result) {
+  const auto *MatchedDecl =
+      Result.Nodes.getNodeAs<CXXRecordDecl>("duplicated-access-specifiers");
+
+  AccessSpecDecl const *lastAccessDecl = nullptr;
+  for (DeclContext::specific_decl_iterator<AccessSpecDecl>
+           NS(MatchedDecl->decls_begin()),
+       NSEnd(MatchedDecl->decls_end());
+       NS != NSEnd; ++NS) {
+    const auto *decl = *NS;
+
+    if (lastAccessDecl != nullptr &&
+        lastAccessDecl->getAccess() == decl->getAccess()) {
+      diag(decl->getLocation(), "duplicated access specifier")
+          << MatchedDecl
+          << FixItHint::CreateRemoval(decl->getSourceRange());
+      diag(lastAccessDecl->getLocation(), "previously declared here",
+           DiagnosticIDs::Note);
+    } else {
+      lastAccessDecl = decl;
+    }
+  }
+}
+
+} // namespace readability
+} // namespace tidy
+} // namespace clang
Index: clang-tidy/readability/CMakeLists.txt
===================================================================
--- clang-tidy/readability/CMakeLists.txt
+++ clang-tidy/readability/CMakeLists.txt
@@ -7,6 +7,7 @@
   ContainerSizeEmptyCheck.cpp
   DeleteNullPointerCheck.cpp
   DeletedDefaultCheck.cpp
+  DuplicatedAccessSpecifiersCheck.cpp
   ElseAfterReturnCheck.cpp
   FunctionSizeCheck.cpp
   IdentifierNamingCheck.cpp
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to