Mordante created this revision.
Mordante added reviewers: aaron.ballman, alexfh, JonasToth, LegalizeAdulthood, 
njames93.
Herald added subscribers: carlosgalvezp, xazax.hun.
Herald added a project: All.
Mordante requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.

The fixit for misc-const-correctness was hard-coded to use east const.
Clang-format has the option to change east const to west const, but
that's not fool-proof.

This adds a option to the checker to select the placement of the const.
The naming is based on clang-format For backwards compatibility the east
const is the default.

Also fixes the documentation; previously it suggested west const is the
default.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D131859

Files:
  clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp
  clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/misc/const-correctness.rst
  
clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-transform-pointer-as-values.cpp
  
clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-transform-values.cpp
  
clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-wrong-config.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-wrong-config.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-wrong-config.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-wrong-config.cpp
@@ -2,9 +2,11 @@
 // RUN: -config='{CheckOptions: \
 // RUN:  [{key: "misc-const-correctness.AnalyzeValues", value: false},\
 // RUN:   {key: "misc-const-correctness.AnalyzeReferences", value: false},\
+// RUN:   {key: 'misc-const-correctness.QualifierAlignment', value: centre}, \
 // RUN:  ]}' -- -fno-delayed-template-parsing
 
 // CHECK-MESSAGES: warning: The check 'misc-const-correctness' will not perform any analysis because both 'AnalyzeValues' and 'AnalyzeReferences' are false. [clang-tidy-config]
+// CHECK-MESSAGES: warning: invalid configuration value 'centre' for option 'misc-const-correctness.QualifierAlignment' [clang-tidy-config]
 
 void g() {
   int p_local0 = 42;
Index: clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-transform-values.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-transform-values.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-transform-values.cpp
@@ -1,10 +1,26 @@
-// RUN: %check_clang_tidy %s misc-const-correctness %t -- \
+// RUN: %check_clang_tidy -check-suffix=RIGHT %s misc-const-correctness %t -- \
 // RUN:   -config="{CheckOptions: [\
 // RUN:   {key: 'misc-const-correctness.TransformValues', value: true},\
 // RUN:   {key: 'misc-const-correctness.WarnPointersAsValues', value: false}, \
 // RUN:   {key: 'misc-const-correctness.TransformPointersAsValues', value: false}, \
 // RUN:   ]}" -- -fno-delayed-template-parsing
 
+// RUN: %check_clang_tidy -check-suffix=RIGHT %s misc-const-correctness %t -- \
+// RUN:   -config="{CheckOptions: [\
+// RUN:   {key: 'misc-const-correctness.TransformValues', value: true},\
+// RUN:   {key: 'misc-const-correctness.WarnPointersAsValues', value: false}, \
+// RUN:   {key: 'misc-const-correctness.TransformPointersAsValues', value: false}, \
+// RUN:   {key: 'misc-const-correctness.QualifierAlignment', value: right}, \
+// RUN:   ]}" -- -fno-delayed-template-parsing
+
+// RUN: %check_clang_tidy -check-suffix=LEFT %s misc-const-correctness %t -- \
+// RUN:   -config="{CheckOptions: [\
+// RUN:   {key: 'misc-const-correctness.TransformValues', value: true},\
+// RUN:   {key: 'misc-const-correctness.WarnPointersAsValues', value: false}, \
+// RUN:   {key: 'misc-const-correctness.TransformPointersAsValues', value: false}, \
+// RUN:   {key: 'misc-const-correctness.QualifierAlignment', value: left}, \
+// RUN:   ]}" -- -fno-delayed-template-parsing
+
 bool global;
 char np_global = 0; // globals can't be known to be const
 
@@ -23,15 +39,17 @@
 
 void some_function(double np_arg0, wchar_t np_arg1) {
   int p_local0 = 2;
-  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const'
-  // CHECK-FIXES: int const p_local0 = 2;
+  // CHECK-MESSAGES-RIGHT: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const'
+  // CHECK-FIXES-RIGHT: int const p_local0 = 2;
+  // CHECK-FIXES-LEFT: const int p_local0 = 2;
 }
 
 void nested_scopes() {
   {
     int p_local1 = 42;
-    // CHECK-MESSAGES: [[@LINE-1]]:5: warning: variable 'p_local1' of type 'int' can be declared 'const'
-    // CHECK-FIXES: int const p_local1 = 42;
+    // CHECK-MESSAGES-RIGHT: [[@LINE-1]]:5: warning: variable 'p_local1' of type 'int' can be declared 'const'
+    // CHECK-FIXES-RIGHT: int const p_local1 = 42;
+    // CHECK-FIXES-LEFT: const int p_local1 = 42;
   }
 }
 
@@ -39,8 +57,9 @@
 void define_locals(T np_arg0, T &np_arg1, int np_arg2) {
   T np_local0 = 0;
   int p_local1 = 42;
-  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'int' can be declared 'const'
-  // CHECK-FIXES: int const p_local1 = 42;
+  // CHECK-MESSAGES-RIGHT: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'int' can be declared 'const'
+  // CHECK-FIXES-RIGHT: int const p_local1 = 42;
+  // CHECK-FIXES-LEFT: const int p_local1 = 42;
 }
 
 void template_instantiation() {
@@ -70,15 +89,17 @@
 
 void direct_class_access() {
   ConstNonConstClass p_local0;
-  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'ConstNonConstClass' can be declared 'const'
-  // CHECK-FIXES: ConstNonConstClass const p_local0;
+  // CHECK-MESSAGES-RIGHT: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'ConstNonConstClass' can be declared 'const'
+  // CHECK-FIXES-RIGHT: ConstNonConstClass const p_local0;
+  // CHECK-FIXES-LEFT: const ConstNonConstClass p_local0;
   p_local0.constMethod();
 }
 
 void class_access_array() {
   ConstNonConstClass p_local0[2];
-  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'ConstNonConstClass[2]' can be declared 'const'
-  // CHECK-FIXES: ConstNonConstClass const p_local0[2];
+  // CHECK-MESSAGES-RIGHT: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'ConstNonConstClass[2]' can be declared 'const'
+  // CHECK-FIXES-RIGHT: ConstNonConstClass const p_local0[2];
+  // CHECK-FIXES-LEFT: const ConstNonConstClass p_local0[2];
   p_local0[0].constMethod();
 }
 
@@ -97,8 +118,9 @@
 
 void vector_usage() {
   double p_local0[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.};
-  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'double[10]' can be declared 'const'
-  // CHECK-FIXES: double const p_local0[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.};
+  // CHECK-MESSAGES-RIGHT: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'double[10]' can be declared 'const'
+  // CHECK-FIXES-RIGHT: double const p_local0[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.};
+  // CHECK-FIXES-LEFT: const double p_local0[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.};
 }
 
 void range_for() {
@@ -117,8 +139,9 @@
 
 void decltype_declaration() {
   decltype(sizeof(void *)) p_local0 = 42;
-  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'decltype(sizeof(void *))'
-  // CHECK-FIXES: decltype(sizeof(void *)) const p_local0 = 42;
+  // CHECK-MESSAGES-RIGHT: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'decltype(sizeof(void *))'
+  // CHECK-FIXES-RIGHT: decltype(sizeof(void *)) const p_local0 = 42;
+  // CHECK-FIXES-LEFT: const decltype(sizeof(void *)) p_local0 = 42;
 }
 
 // Taken from libcxx/include/type_traits and improved readability.
@@ -160,14 +183,16 @@
 
 void meta_type() {
   TMPClass<int> p_local0;
-  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'TMPClass<int>' can be declared 'const'
-  // CHECK-FIXES: TMPClass<int> const p_local0;
+  // CHECK-MESSAGES-RIGHT: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'TMPClass<int>' can be declared 'const'
+  // CHECK-FIXES-RIGHT: TMPClass<int> const p_local0;
+  // CHECK-FIXES-LEFT: const TMPClass<int> p_local0;
   p_local0.alwaysConst();
   p_local0.sometimesConst();
 
   TMPClass<double> p_local1;
-  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'TMPClass<double>' can be declared 'const'
-  // CHECK-FIXES: TMPClass<double> const p_local1;
+  // CHECK-MESSAGES-RIGHT: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'TMPClass<double>' can be declared 'const'
+  // CHECK-FIXES-RIGHT: TMPClass<double> const p_local1;
+  // CHECK-FIXES-LEFT: const TMPClass<double> p_local1;
   p_local1.alwaysConst();
 
   TMPClass<double> p_local2; // Don't attempt to make this const
Index: clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-transform-pointer-as-values.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-transform-pointer-as-values.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-transform-pointer-as-values.cpp
@@ -5,6 +5,22 @@
 // RUN:   {key: "misc-const-correctness.TransformPointersAsValues", value: true},\
 // RUN:  ]}' -- -fno-delayed-template-parsing
 
+// RUN: %check_clang_tidy %s misc-const-correctness %t \
+// RUN: -config='{CheckOptions: \
+// RUN:  [{key: "misc-const-correctness.AnalyzeValues", value: true},\
+// RUN:   {key: "misc-const-correctness.WarnPointersAsValues", value: true}, \
+// RUN:   {key: "misc-const-correctness.TransformPointersAsValues", value: true},\
+// RUN:   {key: 'misc-const-correctness.QualifierAlignment', value: right}, \
+// RUN:  ]}' -- -fno-delayed-template-parsing
+
+// RUN: %check_clang_tidy %s misc-const-correctness %t \
+// RUN: -config='{CheckOptions: \
+// RUN:  [{key: "misc-const-correctness.AnalyzeValues", value: true},\
+// RUN:   {key: "misc-const-correctness.WarnPointersAsValues", value: true}, \
+// RUN:   {key: "misc-const-correctness.TransformPointersAsValues", value: true},\
+// RUN:   {key: 'misc-const-correctness.QualifierAlignment', value: left}, \
+// RUN:  ]}' -- -fno-delayed-template-parsing
+
 void potential_const_pointer() {
   double np_local0[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.};
   double *p_local0 = &np_local0[1];
Index: clang-tools-extra/docs/clang-tidy/checks/misc/const-correctness.rst
===================================================================
--- clang-tools-extra/docs/clang-tidy/checks/misc/const-correctness.rst
+++ clang-tools-extra/docs/clang-tidy/checks/misc/const-correctness.rst
@@ -25,18 +25,18 @@
 .. code-block:: c++
 
   // Normal values like built-ins or objects.
-  int potential_const_int = 42; // 'const int potential_const_int = 42' suggestion.
+  int potential_const_int = 42; // 'int const potential_const_int = 42' suggestion.
   int copy_of_value = potential_const_int;
 
-  MyClass could_be_const; // 'const MyClass could_be_const' suggestion;
+  MyClass could_be_const; // 'MyClass const could_be_const' suggestion;
   could_be_const.const_qualified_method();
 
   // References can be declared const as well.
-  int &reference_value = potential_const_int; // 'const int &reference_value' suggestion.
+  int &reference_value = potential_const_int; // 'int const &reference_value' suggestion.
   int another_copy = reference_value;
 
   // The similar semantics of pointers are not (yet) analyzed.
-  int *pointer_variable = &potential_const_int; // Not 'const int *pointer_variable' suggestion.
+  int *pointer_variable = &potential_const_int; // Not 'int const *pointer_variable' suggestion.
   int last_copy = *pointer_variable;
 
 The automatic code transformation is only applied to variables that are declared in single
@@ -63,7 +63,7 @@
   int constant_value = 42;
 
   // Declare a pointer to that variable, that does not modify either, but misses 'const'.
-  // Could be 'const int *pointer_to_constant = &constant_value;'
+  // Could be 'int const *pointer_to_constant = &constant_value;'
   int *pointer_to_constant = &constant_value;
 
   // Usage:
@@ -99,11 +99,11 @@
 
 .. option:: TransformValues (default = 1)
 
-  Provides fixit-hints for value types that automatically adds ``const`` if its a single declaration.
+  Provides fixit-hints for value types that automatically adds ``const`` if it's a single declaration.
 
   .. code-block:: c++
 
-    // Emits a hint for 'value' to become 'const int value = 42;'.
+    // Emits a hint for 'value' to become 'int const value = 42;'.
     int value = 42;
     // Result is modified later in its life-time. No diagnostic and fixit hint will be emitted.
     int result = value * 3;
@@ -119,7 +119,7 @@
     // This variable could still be a constant. But because there is a non-const reference to
     // it, it can not be transformed (yet).
     int value = 42;
-    // The reference 'ref_value' is not modified and can be made 'const int &ref_value = value;'
+    // The reference 'ref_value' is not modified and can be made 'int const &ref_value = value;'
     int &ref_value = value;
 
     // Result is modified later in its life-time. No diagnostic and fixit hint will be emitted.
@@ -148,3 +148,28 @@
     int *changing_pointee = &value;
     changing_pointee = &result;
 
+.. option:: QualifierAlignment (default = right)
+
+   Determines the position of the ``const`` in the fixit-hints:
+
+   * ``right`` places the ``const`` at the right hand side, also known as east const.
+
+     .. code-block:: c++
+
+      // Emits a hint for 'value' to become 'int const value = 42;'.
+      int value = 42;
+
+      // Emits a hint for 'ref_value' to become 'int const &ref_value = value;'
+      int &ref_value = value;
+
+
+   * ``left`` places the ``const`` at the left hand side, also known as west const.
+
+     .. code-block:: c++
+
+      // Emits a hint for 'value' to become 'const int value = 42;'.
+      int value = 42;a
+
+      // Emits a hint for 'ref_value' to become 'const int &ref_value = value;'
+      int &ref_value = value;
+
Index: clang-tools-extra/docs/ReleaseNotes.rst
===================================================================
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -121,6 +121,10 @@
   support for C++14 signal handler rules was added. Bug report generation was
   improved.
 
+* :doc:`misc-const-correctness <clang-tidy/checks/misc/const-correctness>`
+  check now supports a ``QualifierAlignment`` option to control the location of
+  ``const`` in the fixit-hints.
+
 Removed checks
 ^^^^^^^^^^^^^^
 
Index: clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h
===================================================================
--- clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h
+++ clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h
@@ -10,6 +10,7 @@
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_CONSTCORRECTNESSCHECK_H
 
 #include "../ClangTidyCheck.h"
+#include "../utils/FixItHintUtils.h"
 #include "clang/Analysis/Analyses/ExprMutationAnalyzer.h"
 #include "llvm/ADT/DenseSet.h"
 
@@ -48,6 +49,8 @@
   const bool TransformValues;
   const bool TransformReferences;
   const bool TransformPointersAsValues;
+
+  const utils::fixit::QualifierPolicy QualPolicy;
 };
 
 } // namespace misc
Index: clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp
===================================================================
--- clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp
+++ clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp
@@ -7,7 +7,6 @@
 //===----------------------------------------------------------------------===//
 
 #include "ConstCorrectnessCheck.h"
-#include "../utils/FixItHintUtils.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
@@ -18,6 +17,17 @@
 
 namespace clang {
 namespace tidy {
+
+template <> struct OptionEnumMapping<utils::fixit::QualifierPolicy> {
+  static llvm::ArrayRef<std::pair<utils::fixit::QualifierPolicy, StringRef>>
+  getEnumMapping() {
+    static constexpr std::pair<utils::fixit::QualifierPolicy, StringRef>
+        Mapping[] = {{utils::fixit::QualifierPolicy::Left, "left"},
+                     {utils::fixit::QualifierPolicy::Right, "right"}};
+    return makeArrayRef(Mapping);
+  }
+};
+
 namespace misc {
 
 namespace {
@@ -45,7 +55,9 @@
       TransformValues(Options.get("TransformValues", true)),
       TransformReferences(Options.get("TransformReferences", true)),
       TransformPointersAsValues(
-          Options.get("TransformPointersAsValues", false)) {
+          Options.get("TransformPointersAsValues", false)),
+      QualPolicy(Options.get("QualifierAlignment",
+                             utils::fixit::QualifierPolicy::Right)) {
   if (AnalyzeValues == false && AnalyzeReferences == false)
     this->configurationDiag(
         "The check 'misc-const-correctness' will not "
@@ -173,7 +185,7 @@
   if (VC == VariableCategory::Value && TransformValues) {
     Diag << addQualifierToVarDecl(*Variable, *Result.Context,
                                   DeclSpec::TQ_const, QualifierTarget::Value,
-                                  QualifierPolicy::Right);
+                                  QualPolicy);
     // FIXME: Add '{}' for default initialization if no user-defined default
     // constructor exists and there is no initializer.
     return;
@@ -182,7 +194,7 @@
   if (VC == VariableCategory::Reference && TransformReferences) {
     Diag << addQualifierToVarDecl(*Variable, *Result.Context,
                                   DeclSpec::TQ_const, QualifierTarget::Value,
-                                  QualifierPolicy::Right);
+                                  QualPolicy);
     return;
   }
 
@@ -190,7 +202,7 @@
     if (WarnPointersAsValues && TransformPointersAsValues) {
       Diag << addQualifierToVarDecl(*Variable, *Result.Context,
                                     DeclSpec::TQ_const, QualifierTarget::Value,
-                                    QualifierPolicy::Right);
+                                    QualPolicy);
     }
     return;
   }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to