lebedev.ri updated this revision to Diff 168088.
lebedev.ri added a subscriber: cfe-commits.
lebedev.ri added a comment.
Finds classes that not only contain the data (non-static member variables),
but also have logic (non-static member functions), and diagnoses all member
variables that have any other scope other than `private`. They should be
made `private`, and manipulated exclusively via the member functions.
Optionally, classes with all member variables being `public` could be
ignored, and optionally all `public` member variables could be ignored.
Options
-------
- IgnoreClassesWithAllMemberVariablesBeingPublic
Allows to completely ignore classes if **all** the member variables in that
class have `public` visibility.
- IgnorePublicMemberVariables
Allows to ignore (not diagnose) **all** the member variables with `public`
visibility scope.
References:
- MISRA 11-0-1 Member data in non-POD class types shall be private.
- http://www.codingstandard.com/rule/11-1-1-declare-all-data-members-private/
-
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c2-use-class-if-the-class-has-an-invariant-use-struct-if-the-data-members-can-vary-independently
-
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Rc-private
-
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Rh-protected
Repository:
rCTE Clang Tools Extra
https://reviews.llvm.org/D52771
Files:
clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
clang-tidy/hicpp/HICPPTidyModule.cpp
clang-tidy/misc/CMakeLists.txt
clang-tidy/misc/MiscTidyModule.cpp
clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.cpp
clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.h
docs/ReleaseNotes.rst
docs/clang-tidy/checks/cppcoreguidelines-non-private-member-variables-in-classes.rst
docs/clang-tidy/checks/hicpp-non-private-member-variables-in-classes.rst
docs/clang-tidy/checks/list.rst
docs/clang-tidy/checks/misc-non-private-member-variables-in-classes.rst
test/clang-tidy/misc-non-private-member-variables-in-classes.cpp
Index: test/clang-tidy/misc-non-private-member-variables-in-classes.cpp
===================================================================
--- /dev/null
+++ test/clang-tidy/misc-non-private-member-variables-in-classes.cpp
@@ -0,0 +1,350 @@
+// RUN: %check_clang_tidy -check-suffix=NONPRIVATE %s misc-non-private-member-variables-in-classes %t
+// RUN: %check_clang_tidy -check-suffix=NONPRIVATE %s misc-non-private-member-variables-in-classes %t -- -config='{CheckOptions: [{key: misc-non-private-member-variables-in-classes.IgnorePublicMemberVariables, value: 0}, {key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic, value: 0}]}' --
+// RUN: %check_clang_tidy -check-suffix=PROTECTED %s misc-non-private-member-variables-in-classes %t -- -config='{CheckOptions: [{key: misc-non-private-member-variables-in-classes.IgnorePublicMemberVariables, value: 1}, {key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic, value: 0}]}' --
+// RUN: %check_clang_tidy -check-suffix=IGNOREPUBLICONLY %s misc-non-private-member-variables-in-classes %t -- -config='{CheckOptions: [{key: misc-non-private-member-variables-in-classes.IgnorePublicMemberVariables, value: 0}, {key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic, value: 1}]}' --
+// RUN: %check_clang_tidy -check-suffix=IGNOREPUBLIC %s misc-non-private-member-variables-in-classes %t -- -config='{CheckOptions: [{key: misc-non-private-member-variables-in-classes.IgnorePublicMemberVariables, value: 1}, {key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic, value: 1}]}' --
+
+//----------------------------------------------------------------------------//
+
+// Only data, do not warn
+
+struct S0 {
+ int S0_v0;
+
+public:
+ int S0_v1;
+
+protected:
+ int S0_v2;
+
+private:
+ int S0_v3;
+};
+
+class S1 {
+ int S1_v0;
+
+public:
+ int S1_v1;
+
+protected:
+ int S1_v2;
+
+private:
+ int S1_v3;
+};
+
+//----------------------------------------------------------------------------//
+
+// All functions are static, do not warn.
+
+struct S2 {
+ static void S2_m0();
+ int S2_v0;
+
+public:
+ static void S2_m1();
+ int S2_v1;
+
+protected:
+ static void S2_m3();
+ int S2_v2;
+
+private:
+ static void S2_m4();
+ int S2_v3;
+};
+
+class S3 {
+ static void S3_m0();
+ int S3_v0;
+
+public:
+ static void S3_m1();
+ int S3_v1;
+
+protected:
+ static void S3_m3();
+ int S3_v2;
+
+private:
+ static void S3_m4();
+ int S3_v3;
+};
+
+//============================================================================//
+
+// Has non-static method with default visibility.
+
+struct S4 {
+ void S4_m0();
+
+ int S4_v0;
+ // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S4_v0' of struct 'S4' has public visibility
+ // CHECK-MESSAGES-IGNOREPUBLICONLY: :[[@LINE-2]]:7: warning: member variable 'S4_v0' of struct 'S4' has public visibility
+public:
+ int S4_v1;
+ // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S4_v1' of struct 'S4' has public visibility
+ // CHECK-MESSAGES-IGNOREPUBLICONLY: :[[@LINE-2]]:7: warning: member variable 'S4_v1' of struct 'S4' has public visibility
+protected:
+ int S4_v2;
+ // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S4_v2' of struct 'S4' has protected visibility
+ // CHECK-MESSAGES-PROTECTED: :[[@LINE-2]]:7: warning: member variable 'S4_v2' of struct 'S4' has protected visibility
+ // CHECK-MESSAGES-IGNOREPUBLICONLY: :[[@LINE-3]]:7: warning: member variable 'S4_v2' of struct 'S4' has protected visibility
+ // CHECK-MESSAGES-IGNOREPUBLIC: :[[@LINE-4]]:7: warning: member variable 'S4_v2' of struct 'S4' has protected visibility
+private:
+ int S4_v3;
+};
+
+class S5 {
+ void S5_m0();
+
+ int S5_v0;
+
+public:
+ int S5_v1;
+ // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S5_v1' of class 'S5' has public visibility
+ // CHECK-MESSAGES-IGNOREPUBLICONLY: :[[@LINE-2]]:7: warning: member variable 'S5_v1' of class 'S5' has public visibility
+protected:
+ int S5_v2;
+ // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S5_v2' of class 'S5' has protected visibility
+ // CHECK-MESSAGES-PROTECTED: :[[@LINE-2]]:7: warning: member variable 'S5_v2' of class 'S5' has protected visibility
+ // CHECK-MESSAGES-IGNOREPUBLICONLY: :[[@LINE-3]]:7: warning: member variable 'S5_v2' of class 'S5' has protected visibility
+ // CHECK-MESSAGES-IGNOREPUBLIC: :[[@LINE-4]]:7: warning: member variable 'S5_v2' of class 'S5' has protected visibility
+private:
+ int S5_v3;
+};
+
+//----------------------------------------------------------------------------//
+
+// Has non-static method with public visibility.
+
+struct S6 {
+ int S6_v0;
+ // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S6_v0' of struct 'S6' has public visibility
+ // CHECK-MESSAGES-IGNOREPUBLICONLY: :[[@LINE-2]]:7: warning: member variable 'S6_v0' of struct 'S6' has public visibility
+public:
+ void S6_m0();
+ int S6_v1;
+ // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S6_v1' of struct 'S6' has public visibility
+ // CHECK-MESSAGES-IGNOREPUBLICONLY: :[[@LINE-2]]:7: warning: member variable 'S6_v1' of struct 'S6' has public visibility
+protected:
+ int S6_v2;
+ // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S6_v2' of struct 'S6' has protected visibility
+ // CHECK-MESSAGES-PROTECTED: :[[@LINE-2]]:7: warning: member variable 'S6_v2' of struct 'S6' has protected visibility
+ // CHECK-MESSAGES-IGNOREPUBLICONLY: :[[@LINE-3]]:7: warning: member variable 'S6_v2' of struct 'S6' has protected visibility
+ // CHECK-MESSAGES-IGNOREPUBLIC: :[[@LINE-4]]:7: warning: member variable 'S6_v2' of struct 'S6' has protected visibility
+private:
+ int S6_v3;
+};
+
+class S7 {
+ int S7_v0;
+
+public:
+ void S7_m0();
+ int S7_v1;
+ // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S7_v1' of class 'S7' has public visibility
+ // CHECK-MESSAGES-IGNOREPUBLICONLY: :[[@LINE-2]]:7: warning: member variable 'S7_v1' of class 'S7' has public visibility
+protected:
+ int S7_v2;
+ // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S7_v2' of class 'S7' has protected visibility
+ // CHECK-MESSAGES-PROTECTED: :[[@LINE-2]]:7: warning: member variable 'S7_v2' of class 'S7' has protected visibility
+ // CHECK-MESSAGES-IGNOREPUBLICONLY: :[[@LINE-3]]:7: warning: member variable 'S7_v2' of class 'S7' has protected visibility
+ // CHECK-MESSAGES-IGNOREPUBLIC: :[[@LINE-4]]:7: warning: member variable 'S7_v2' of class 'S7' has protected visibility
+private:
+ int S7_v3;
+};
+
+//----------------------------------------------------------------------------//
+
+// Has non-static method with protected visibility.
+
+struct S8 {
+ int S8_v0;
+ // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S8_v0' of struct 'S8' has public visibility
+ // CHECK-MESSAGES-IGNOREPUBLICONLY: :[[@LINE-2]]:7: warning: member variable 'S8_v0' of struct 'S8' has public visibility
+public:
+ int S8_v1;
+ // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S8_v1' of struct 'S8' has public visibility
+ // CHECK-MESSAGES-IGNOREPUBLICONLY: :[[@LINE-2]]:7: warning: member variable 'S8_v1' of struct 'S8' has public visibility
+protected:
+ void S8_m0();
+ int S8_v2;
+ // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S8_v2' of struct 'S8' has protected visibility
+ // CHECK-MESSAGES-PROTECTED: :[[@LINE-2]]:7: warning: member variable 'S8_v2' of struct 'S8' has protected visibility
+ // CHECK-MESSAGES-IGNOREPUBLICONLY: :[[@LINE-3]]:7: warning: member variable 'S8_v2' of struct 'S8' has protected visibility
+ // CHECK-MESSAGES-IGNOREPUBLIC: :[[@LINE-4]]:7: warning: member variable 'S8_v2' of struct 'S8' has protected visibility
+private:
+ int S8_v3;
+};
+
+class S9 {
+ int S9_v0;
+
+public:
+ int S9_v1;
+ // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S9_v1' of class 'S9' has public visibility
+ // CHECK-MESSAGES-IGNOREPUBLICONLY: :[[@LINE-2]]:7: warning: member variable 'S9_v1' of class 'S9' has public visibility
+protected:
+ void S9_m0();
+ int S9_v2;
+ // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S9_v2' of class 'S9' has protected visibility
+ // CHECK-MESSAGES-PROTECTED: :[[@LINE-2]]:7: warning: member variable 'S9_v2' of class 'S9' has protected visibility
+ // CHECK-MESSAGES-IGNOREPUBLICONLY: :[[@LINE-3]]:7: warning: member variable 'S9_v2' of class 'S9' has protected visibility
+ // CHECK-MESSAGES-IGNOREPUBLIC: :[[@LINE-4]]:7: warning: member variable 'S9_v2' of class 'S9' has protected visibility
+private:
+ int S9_v3;
+};
+
+//----------------------------------------------------------------------------//
+
+// Has non-static method with private visibility.
+
+struct S10 {
+ int S10_v0;
+ // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S10_v0' of struct 'S10' has public visibility
+ // CHECK-MESSAGES-IGNOREPUBLICONLY: :[[@LINE-2]]:7: warning: member variable 'S10_v0' of struct 'S10' has public visibility
+public:
+ int S10_v1;
+ // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S10_v1' of struct 'S10' has public visibility
+ // CHECK-MESSAGES-IGNOREPUBLICONLY: :[[@LINE-2]]:7: warning: member variable 'S10_v1' of struct 'S10' has public visibility
+protected:
+ int S10_v2;
+ // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S10_v2' of struct 'S10' has protected visibility
+ // CHECK-MESSAGES-PROTECTED: :[[@LINE-2]]:7: warning: member variable 'S10_v2' of struct 'S10' has protected visibility
+ // CHECK-MESSAGES-IGNOREPUBLICONLY: :[[@LINE-3]]:7: warning: member variable 'S10_v2' of struct 'S10' has protected visibility
+ // CHECK-MESSAGES-IGNOREPUBLIC: :[[@LINE-4]]:7: warning: member variable 'S10_v2' of struct 'S10' has protected visibility
+private:
+ void S10_m0();
+ int S10_v3;
+};
+
+class S11 {
+ int S11_v0;
+
+public:
+ int S11_v1;
+ // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S11_v1' of class 'S11' has public visibility
+ // CHECK-MESSAGES-IGNOREPUBLICONLY: :[[@LINE-2]]:7: warning: member variable 'S11_v1' of class 'S11' has public visibility
+protected:
+ int S11_v2;
+ // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S11_v2' of class 'S11' has protected visibility
+ // CHECK-MESSAGES-PROTECTED: :[[@LINE-2]]:7: warning: member variable 'S11_v2' of class 'S11' has protected visibility
+ // CHECK-MESSAGES-IGNOREPUBLICONLY: :[[@LINE-3]]:7: warning: member variable 'S11_v2' of class 'S11' has protected visibility
+ // CHECK-MESSAGES-IGNOREPUBLIC: :[[@LINE-4]]:7: warning: member variable 'S11_v2' of class 'S11' has protected visibility
+private:
+ void S11_m0();
+ int S11_v3;
+};
+
+//============================================================================//
+
+// Static variables are ignored.
+// Has non-static methods and static variables.
+
+struct S12 {
+ void S12_m0();
+ static int S12_v0;
+
+public:
+ void S12_m1();
+ static int S12_v1;
+
+protected:
+ void S12_m2();
+ static int S12_v2;
+
+private:
+ void S12_m3();
+ static int S12_v3;
+};
+
+class S13 {
+ void S13_m0();
+ static int S13_v0;
+
+public:
+ void S13_m1();
+ static int S13_v1;
+
+protected:
+ void S13_m2();
+ static int S13_v2;
+
+private:
+ void S13_m3();
+ static int S13_v3;
+};
+
+struct S14 {
+ void S14_m0();
+ int S14_v0;
+ // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S14_v0' of struct 'S14' has public visibility
+
+public:
+ void S14_m1();
+ int S14_v1;
+ // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S14_v1' of struct 'S14' has public visibility
+
+protected:
+ void S14_m2();
+
+private:
+ void S14_m3();
+};
+
+class S15 {
+ void S15_m0();
+
+public:
+ void S15_m1();
+ int S15_v1;
+ // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S15_v1' of class 'S15' has public visibility
+
+protected:
+ void S15_m2();
+
+private:
+ void S15_m3();
+};
+
+//----------------------------------------------------------------------------//
+
+// Don't look in descendant classes.
+class S99 {
+ void method();
+
+ struct S99_0 {
+ int S99_S0_v0;
+ };
+
+public:
+ struct S99_1 {
+ int S99_S0_v0;
+ };
+
+protected:
+ struct S99_2 {
+ int S99_S0_v0;
+ };
+
+private:
+ struct S99_3 {
+ int S99_S0_v0;
+ };
+};
+
+//----------------------------------------------------------------------------//
+
+// Only diagnose once, don't let the inheritance fool you.
+struct S100 {
+ int S100_v0;
+ // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S100_v0' of struct 'S100' has public visibility
+ void m0();
+};
+struct S101 : S100 {
+ int S101_v0;
+ // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S101_v0' of struct 'S101' has public visibility
+ void m1();
+};
Index: docs/clang-tidy/checks/misc-non-private-member-variables-in-classes.rst
===================================================================
--- /dev/null
+++ docs/clang-tidy/checks/misc-non-private-member-variables-in-classes.rst
@@ -0,0 +1,31 @@
+.. title:: clang-tidy - misc-non-private-member-variables-in-classes
+
+misc-non-private-member-variables-in-classes
+============================================
+
+`cppcoreguidelines-non-private-member-variables-in-classes` redirects here
+as an alias for this check.
+
+`hicpp-non-private-member-variables-in-classes` redirects here
+as an alias for this check.
+
+Finds classes that not only contain the data (non-static member variables),
+but also have logic (non-static member functions), and diagnoses all member
+variables that have any other scope other than ``private``. They should be
+made ``private``, and manipulated exclusively via the member functions.
+
+Optionally, classes with all member variables being ``public`` could be
+ignored, and optionally all ``public`` member variables could be ignored.
+
+Options
+-------
+
+.. option:: IgnoreClassesWithAllMemberVariablesBeingPublic
+
+ Allows to completely ignore classes if **all** the member variables in that
+ class have ``public`` visibility.
+
+.. option:: IgnorePublicMemberVariables
+
+ Allows to ignore (not diagnose) **all** the member variables with ``public``
+ visibility scope.
Index: docs/clang-tidy/checks/list.rst
===================================================================
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -90,6 +90,7 @@
cppcoreguidelines-interfaces-global-init
cppcoreguidelines-narrowing-conversions
cppcoreguidelines-no-malloc
+ cppcoreguidelines-non-private-member-variables-in-classes (redirects to misc-non-private-member-variables-in-classes) <cppcoreguidelines-non-private-member-variables-in-classes>
cppcoreguidelines-owning-memory
cppcoreguidelines-pro-bounds-array-to-pointer-decay
cppcoreguidelines-pro-bounds-constant-array-index
@@ -143,6 +144,7 @@
hicpp-no-assembler
hicpp-no-malloc (redirects to cppcoreguidelines-no-malloc) <hicpp-no-malloc>
hicpp-noexcept-move (redirects to misc-noexcept-moveconstructor) <hicpp-noexcept-move>
+ hicpp-non-private-member-variables-in-classes (redirects to misc-non-private-member-variables-in-classes) <hicpp-non-private-member-variables-in-classes>
hicpp-signed-bitwise
hicpp-special-member-functions (redirects to cppcoreguidelines-special-member-functions) <hicpp-special-member-functions>
hicpp-static-assert (redirects to misc-static-assert) <hicpp-static-assert>
@@ -163,6 +165,7 @@
misc-misplaced-const
misc-new-delete-overloads
misc-non-copyable-objects
+ misc-non-private-member-variables-in-classes
misc-redundant-expression
misc-static-assert
misc-throw-by-value-catch-by-reference
Index: docs/clang-tidy/checks/hicpp-non-private-member-variables-in-classes.rst
===================================================================
--- /dev/null
+++ docs/clang-tidy/checks/hicpp-non-private-member-variables-in-classes.rst
@@ -0,0 +1,11 @@
+.. title:: clang-tidy - hicpp-non-private-member-variables-in-classes
+.. meta::
+ :http-equiv=refresh: 5;URL=misc-non-private-member-variables-in-classes.html
+
+hicpp-non-private-member-variables-in-classes
+=============================================
+
+The hicpp-non-private-member-variables-in-classes check is an alias,
+please see
+`misc-non-private-member-variables-in-classes <misc-non-private-member-variables-in-classes.html>`_
+for more information.
Index: docs/clang-tidy/checks/cppcoreguidelines-non-private-member-variables-in-classes.rst
===================================================================
--- /dev/null
+++ docs/clang-tidy/checks/cppcoreguidelines-non-private-member-variables-in-classes.rst
@@ -0,0 +1,11 @@
+.. title:: clang-tidy - cppcoreguidelines-non-private-member-variables-in-classes
+.. meta::
+ :http-equiv=refresh: 5;URL=misc-non-private-member-variables-in-classes.html
+
+cppcoreguidelines-non-private-member-variables-in-classes
+=========================================================
+
+The cppcoreguidelines-non-private-member-variables-in-classes check is an alias,
+please see
+`misc-non-private-member-variables-in-classes <misc-non-private-member-variables-in-classes.html>`_
+for more information.
Index: docs/ReleaseNotes.rst
===================================================================
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -93,6 +93,29 @@
Flags uses of ``absl::StrCat()`` to append to a ``std::string``. Suggests
``absl::StrAppend()`` should be used instead.
+- New :doc:`misc-non-private-member-variables-in-classes
+ <clang-tidy/checks/misc-non-private-member-variables-in-classes>` check.
+
+ Finds classes that not only contain the data (non-static member variables),
+ but also have logic (non-static member functions), and diagnoses all member
+ variables that have any other scope other than ``private``. They should be
+ made ``private``, and manipulated exclusively via the member functions.
+
+ Optionally, classes with all member variables being ``public`` could be
+ ignored, and optionally all ``public`` member variables could be ignored.
+
+- New alias :doc:`cppcoreguidelines-non-private-member-variables-in-classes
+ <clang-tidy/checks/cppcoreguidelines-non-private-member-variables-in-classes>`
+ to :doc:`misc-non-private-member-variables-in-classes
+ <clang-tidy/checks/misc-non-private-member-variables-in-classes>`
+ added.
+
+- New alias :doc:`hicpp-non-private-member-variables-in-classes
+ <clang-tidy/checks/hicpp-non-private-member-variables-in-classes>`
+ to :doc:`misc-non-private-member-variables-in-classes
+ <clang-tidy/checks/misc-non-private-member-variables-in-classes>`
+ added.
+
- New :doc:`modernize-concat-nested-namespaces
<clang-tidy/checks/modernize-concat-nested-namespaces>` check.
Index: clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.h
===================================================================
--- /dev/null
+++ clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.h
@@ -0,0 +1,45 @@
+//===--- NonPrivateMemberVariablesInClassesCheck.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_MISC_NONPRIVATEMEMBERVARIABLESINCLASSESCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_NONPRIVATEMEMBERVARIABLESINCLASSESCHECK_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace misc {
+
+/// This checker finds classes that not only contain the data
+/// (non-static member variables), but also have logic (non-static member
+/// functions), and diagnoses all member variables that have any other scope
+/// other than `private`. They should be made `private`, and manipulated
+/// exclusively via the member functions.
+///
+/// Optionally, classes with all member variables being `public` could be
+/// ignored and optionally all `public` member variables could be ignored.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/misc-non-private-member-variables-in-classes.html
+class NonPrivateMemberVariablesInClassesCheck : public ClangTidyCheck {
+ const bool IgnoreClassesWithAllMemberVariablesBeingPublic;
+ const bool IgnorePublicMemberVariables;
+
+public:
+ NonPrivateMemberVariablesInClassesCheck(StringRef Name,
+ ClangTidyContext *Context);
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace misc
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_NONPRIVATEMEMBERVARIABLESINCLASSESCHECK_H
Index: clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.cpp
===================================================================
--- /dev/null
+++ clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.cpp
@@ -0,0 +1,85 @@
+//===--- NonPrivateMemberVariablesInClassesCheck.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 "NonPrivateMemberVariablesInClassesCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace misc {
+
+namespace {
+
+AST_MATCHER(clang::CXXRecordDecl, hasMethods) {
+ return std::distance(Node.method_begin(), Node.method_end()) != 0;
+}
+
+AST_MATCHER(clang::CXXRecordDecl, hasNonStaticMethod) {
+ return hasMethod(unless(isStaticStorageClass()))
+ .matches(Node, Finder, Builder);
+}
+
+AST_MATCHER(clang::CXXRecordDecl, hasNonPublicMemberVariable) {
+ return cxxRecordDecl(has(fieldDecl(unless(isPublic()))))
+ .matches(Node, Finder, Builder);
+}
+
+} // namespace
+
+NonPrivateMemberVariablesInClassesCheck::
+ NonPrivateMemberVariablesInClassesCheck(StringRef Name,
+ ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context),
+ IgnoreClassesWithAllMemberVariablesBeingPublic(
+ Options.get("IgnoreClassesWithAllMemberVariablesBeingPublic", false)),
+ IgnorePublicMemberVariables(
+ Options.get("IgnorePublicMemberVariables", false)) {}
+
+void NonPrivateMemberVariablesInClassesCheck::registerMatchers(
+ MatchFinder *Finder) {
+ if (!getLangOpts().CPlusPlus)
+ return;
+
+ // We only want the classes that not only contain the mutable data (non-static
+ // member variables), but also have some logic (non-static member functions).
+ // We may optionally ignore classes where all the member variables are public.
+ auto recordIsInteresting =
+ allOf(anyOf(isStruct(), isClass()), hasMethods(), hasNonStaticMethod(),
+ IgnoreClassesWithAllMemberVariablesBeingPublic
+ ? hasNonPublicMemberVariable()
+ : anything());
+
+ // There are three visibility types: public, protected, private.
+ // If we are ok with public fields, then we only want to complain about
+ // protected fields, else we want to complain about all non-private fields.
+ auto interestingField = fieldDecl(
+ IgnorePublicMemberVariables ? isProtected() : unless(isPrivate()));
+
+ Finder->addMatcher(cxxRecordDecl(recordIsInteresting,
+ forEach(interestingField.bind("field")))
+ .bind("record"),
+ this);
+}
+
+void NonPrivateMemberVariablesInClassesCheck::check(
+ const MatchFinder::MatchResult &Result) {
+ const auto *Field = Result.Nodes.getNodeAs<FieldDecl>("field");
+ const auto *Record = Result.Nodes.getNodeAs<CXXRecordDecl>("record");
+ diag(Field->getLocation(),
+ "member variable '%0' of %1 '%2' has %3 visibility")
+ << Field->getName() << Record->getKindName() << Record->getName()
+ << Field->getAccess();
+}
+
+} // namespace misc
+} // namespace tidy
+} // namespace clang
Index: clang-tidy/misc/MiscTidyModule.cpp
===================================================================
--- clang-tidy/misc/MiscTidyModule.cpp
+++ clang-tidy/misc/MiscTidyModule.cpp
@@ -14,6 +14,7 @@
#include "MisplacedConstCheck.h"
#include "NewDeleteOverloadsCheck.h"
#include "NonCopyableObjects.h"
+#include "NonPrivateMemberVariablesInClassesCheck.h"
#include "RedundantExpressionCheck.h"
#include "StaticAssertCheck.h"
#include "ThrowByValueCatchByReferenceCheck.h"
@@ -37,6 +38,8 @@
"misc-new-delete-overloads");
CheckFactories.registerCheck<NonCopyableObjectsCheck>(
"misc-non-copyable-objects");
+ CheckFactories.registerCheck<NonPrivateMemberVariablesInClassesCheck>(
+ "misc-non-private-member-variables-in-classes");
CheckFactories.registerCheck<RedundantExpressionCheck>(
"misc-redundant-expression");
CheckFactories.registerCheck<StaticAssertCheck>("misc-static-assert");
Index: clang-tidy/misc/CMakeLists.txt
===================================================================
--- clang-tidy/misc/CMakeLists.txt
+++ clang-tidy/misc/CMakeLists.txt
@@ -6,6 +6,7 @@
MisplacedConstCheck.cpp
NewDeleteOverloadsCheck.cpp
NonCopyableObjects.cpp
+ NonPrivateMemberVariablesInClassesCheck.cpp
RedundantExpressionCheck.cpp
StaticAssertCheck.cpp
ThrowByValueCatchByReferenceCheck.cpp
Index: clang-tidy/hicpp/HICPPTidyModule.cpp
===================================================================
--- clang-tidy/hicpp/HICPPTidyModule.cpp
+++ clang-tidy/hicpp/HICPPTidyModule.cpp
@@ -20,6 +20,7 @@
#include "../google/DefaultArgumentsCheck.h"
#include "../google/ExplicitConstructorCheck.h"
#include "../misc/NewDeleteOverloadsCheck.h"
+#include "../misc/NonPrivateMemberVariablesInClassesCheck.h"
#include "../misc/StaticAssertCheck.h"
#include "../bugprone/UndelegatedConstructorCheck.h"
#include "../modernize/DeprecatedHeadersCheck.h"
@@ -80,6 +81,8 @@
CheckFactories.registerCheck<NoAssemblerCheck>("hicpp-no-assembler");
CheckFactories.registerCheck<cppcoreguidelines::NoMallocCheck>(
"hicpp-no-malloc");
+ CheckFactories.registerCheck<misc::NonPrivateMemberVariablesInClassesCheck>(
+ "hicpp-non-private-member-variables-in-classes");
CheckFactories
.registerCheck<cppcoreguidelines::SpecialMemberFunctionsCheck>(
"hicpp-special-member-functions");
Index: clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
===================================================================
--- clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
+++ clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
@@ -10,6 +10,7 @@
#include "../ClangTidy.h"
#include "../ClangTidyModule.h"
#include "../ClangTidyModuleRegistry.h"
+#include "../misc/NonPrivateMemberVariablesInClassesCheck.h"
#include "../misc/UnconventionalAssignOperatorCheck.h"
#include "../readability/MagicNumbersCheck.h"
#include "AvoidGotoCheck.h"
@@ -47,6 +48,8 @@
CheckFactories.registerCheck<NarrowingConversionsCheck>(
"cppcoreguidelines-narrowing-conversions");
CheckFactories.registerCheck<NoMallocCheck>("cppcoreguidelines-no-malloc");
+ CheckFactories.registerCheck<misc::NonPrivateMemberVariablesInClassesCheck>(
+ "cppcoreguidelines-non-private-member-variables-in-classes");
CheckFactories.registerCheck<OwningMemoryCheck>(
"cppcoreguidelines-owning-memory");
CheckFactories.registerCheck<ProBoundsArrayToPointerDecayCheck>(
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits