MyDeveloperDay created this revision.
MyDeveloperDay added reviewers: klimek, mitchell-stellar, sammccall, owenpan, 
krasimir.
MyDeveloperDay added a project: clang-format.
Herald added a subscriber: mgorny.
Herald added a project: clang.

Developers these days seem to argue over east vs west const like they used to 
argue over tabs vs whitespace or the various bracing style. These previous 
arguments were mainly eliminated with tools like `clang-format` that allowed 
those rules to become part of your style guide. Anyone who has been using 
clang-format in a large team over the last couple of years knows that we don't 
have those religious arguments any more, and code reviews are more productive.

https://www.youtube.com/watch?v=fv--IKZFVO8
https://mariusbancila.ro/blog/2018/11/23/join-the-east-const-revolution/
https://www.youtube.com/watch?v=z6s6bacI424

The purpose of this revision is to try to do the same for the East/West const 
discussion. Move the debate into the style guide and leave it there!

In addition to the new `ConstStyle: West` or `ConstStyle: East` there is an 
additional command-line argument `--const-style=east/west` which would allow an 
individual developer to switch the source back and forth to their own style for 
editing, and back to the committed style before commit. (you could imagine an 
IDE might offer such a switch)

The revision works by implementing a separate pass of the Annotated lines much 
like the SortIncludes and then create replacements for constant type 
declarations.


Repository:
  rC Clang

https://reviews.llvm.org/D69764

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/CMakeLists.txt
  clang/lib/Format/EastWestConstFixer.cpp
  clang/lib/Format/EastWestConstFixer.h
  clang/lib/Format/Format.cpp
  clang/tools/clang-format/ClangFormat.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===================================================================
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -27,6 +27,10 @@
 
 FormatStyle getGoogleStyle() { return getGoogleStyle(FormatStyle::LK_Cpp); }
 
+#define VERIFYFORMAT(expect, style) verifyFormat(expect, style, __LINE__)
+#define VERIFYFORMAT2(expect, actual, style)                                   \
+  verifyFormat(expect, actual, style, __LINE__)
+
 class FormatTest : public ::testing::Test {
 protected:
   enum StatusCheck { SC_ExpectComplete, SC_ExpectIncomplete, SC_DoNotCheck };
@@ -66,10 +70,12 @@
   }
 
   void verifyFormat(llvm::StringRef Expected, llvm::StringRef Code,
-                    const FormatStyle &Style = getLLVMStyle()) {
+                    const FormatStyle &Style = getLLVMStyle(),
+                    int line = __LINE__) {
     EXPECT_EQ(Expected.str(), format(Expected, Style))
-        << "Expected code is not stable";
-    EXPECT_EQ(Expected.str(), format(Code, Style));
+        << "Expected code is not stable at " << __FILE__ << ":" << line;
+    EXPECT_EQ(Expected.str(), format(Code, Style))
+        << " at " << __FILE__ << ":" << line;
     if (Style.Language == FormatStyle::LK_Cpp) {
       // Objective-C++ is a superset of C++, so everything checked for C++
       // needs to be checked for Objective-C++ as well.
@@ -80,8 +86,9 @@
   }
 
   void verifyFormat(llvm::StringRef Code,
-                    const FormatStyle &Style = getLLVMStyle()) {
-    verifyFormat(Code, test::messUp(Code), Style);
+                    const FormatStyle &Style = getLLVMStyle(),
+                    int line = __LINE__) {
+    verifyFormat(Code, test::messUp(Code), Style, line);
   }
 
   void verifyIncompleteFormat(llvm::StringRef Code,
@@ -12502,6 +12509,11 @@
   CHECK_PARSE("ContinuationIndentWidth: 11", ContinuationIndentWidth, 11u);
   CHECK_PARSE("CommentPragmas: '// abc$'", CommentPragmas, "// abc$");
 
+  Style.ConstStyle = FormatStyle::CS_West;
+  CHECK_PARSE("ConstStyle: Leave", ConstStyle, FormatStyle::CS_Leave);
+  CHECK_PARSE("ConstStyle: East", ConstStyle, FormatStyle::CS_East);
+  CHECK_PARSE("ConstStyle: West", ConstStyle, FormatStyle::CS_West);
+
   Style.PointerAlignment = FormatStyle::PAS_Middle;
   CHECK_PARSE("PointerAlignment: Left", PointerAlignment,
               FormatStyle::PAS_Left);
@@ -14728,6 +14740,112 @@
                "#endif // while");
 }
 
+TEST_F(FormatTest, EastWestConst) {
+  FormatStyle Style = getLLVMStyle();
+
+  // keep the const style unaltered
+  VERIFYFORMAT("const int a;", Style);
+  VERIFYFORMAT("const int *a;", Style);
+  VERIFYFORMAT("const int &a;", Style);
+  VERIFYFORMAT("const int &&a;", Style);
+  VERIFYFORMAT("int const b;", Style);
+  VERIFYFORMAT("int const *b;", Style);
+  VERIFYFORMAT("int const &b;", Style);
+  VERIFYFORMAT("int const &&b;", Style);
+  VERIFYFORMAT("int const *b const;", Style);
+  VERIFYFORMAT("int *const c;", Style);
+
+  VERIFYFORMAT("const Foo a;", Style);
+  VERIFYFORMAT("const Foo *a;", Style);
+  VERIFYFORMAT("const Foo &a;", Style);
+  VERIFYFORMAT("const Foo &&a;", Style);
+  VERIFYFORMAT("Foo const b;", Style);
+  VERIFYFORMAT("Foo const *b;", Style);
+  VERIFYFORMAT("Foo const &b;", Style);
+  VERIFYFORMAT("Foo const &&b;", Style);
+  VERIFYFORMAT("Foo const *b const;", Style);
+
+  Style.ConstStyle = FormatStyle::CS_East;
+
+  VERIFYFORMAT("int const a;", Style);
+  VERIFYFORMAT("int const *a;", Style);
+  VERIFYFORMAT("int const &a;", Style);
+  VERIFYFORMAT("int const &&a;", Style);
+  VERIFYFORMAT("int const b;", Style);
+  VERIFYFORMAT("int const *b;", Style);
+  VERIFYFORMAT("int const &b;", Style);
+  VERIFYFORMAT("int const &&b;", Style);
+  VERIFYFORMAT("int const *b const;", Style);
+  VERIFYFORMAT("int *const c;", Style);
+
+  VERIFYFORMAT("Foo const a;", Style);
+  VERIFYFORMAT("Foo const *a;", Style);
+  VERIFYFORMAT("Foo const &a;", Style);
+  VERIFYFORMAT("Foo const &&a;", Style);
+  VERIFYFORMAT("Foo const b;", Style);
+  VERIFYFORMAT("Foo const *b;", Style);
+  VERIFYFORMAT("Foo const &b;", Style);
+  VERIFYFORMAT("Foo const &&b;", Style);
+  VERIFYFORMAT("Foo const *b const;", Style);
+  VERIFYFORMAT("Foo *const b;", Style);
+  VERIFYFORMAT("Foo const *const b;", Style);
+  VERIFYFORMAT("auto const v = get_value();", Style);
+  VERIFYFORMAT("long long const &a;", Style);
+  VERIFYFORMAT("unsigned char const *a;", Style);
+  VERIFYFORMAT("int main(int const argc, char const *const *const argv)",
+               Style);
+
+  VERIFYFORMAT2("int const a;", "const int a;", Style);
+  VERIFYFORMAT2("int const *a;", "const int *a;", Style);
+  VERIFYFORMAT2("int const &a;", "const int &a;", Style);
+  VERIFYFORMAT2("foo(int const &a)", "foo(const int &a)", Style);
+  VERIFYFORMAT2("unsigned char *a;", "unsigned char *a;", Style);
+  VERIFYFORMAT2("unsigned char const *a;", "const unsigned char *a;", Style);
+  VERIFYFORMAT2("vector<int, int const, int &, int const &> args1",
+                "vector<int, const int, int &, const int &> args1", Style);
+  VERIFYFORMAT2("unsigned int const &get_nu() const",
+                "const unsigned int &get_nu() const", Style);
+
+  Style.ConstStyle = FormatStyle::CS_West;
+
+  VERIFYFORMAT("const int a;", Style);
+  VERIFYFORMAT("const int *a;", Style);
+  VERIFYFORMAT("const int &a;", Style);
+  VERIFYFORMAT("const int &&a;", Style);
+  VERIFYFORMAT("const int b;", Style);
+  VERIFYFORMAT("const int *b;", Style);
+  VERIFYFORMAT("const int &b;", Style);
+  VERIFYFORMAT("const int &&b;", Style);
+  VERIFYFORMAT("const int *b const;", Style);
+  VERIFYFORMAT("int *const c;", Style);
+
+  VERIFYFORMAT("const Foo a;", Style);
+  VERIFYFORMAT("const Foo *a;", Style);
+  VERIFYFORMAT("const Foo &a;", Style);
+  VERIFYFORMAT("const Foo &&a;", Style);
+  VERIFYFORMAT("const Foo b;", Style);
+  VERIFYFORMAT("const Foo *b;", Style);
+  VERIFYFORMAT("const Foo &b;", Style);
+  VERIFYFORMAT("const Foo &&b;", Style);
+  VERIFYFORMAT("const Foo *b const;", Style);
+  VERIFYFORMAT("Foo *const b;", Style);
+  VERIFYFORMAT("const Foo *const b;", Style);
+
+  VERIFYFORMAT("const char a[];", Style);
+  VERIFYFORMAT("const auto v = get_value();", Style);
+  VERIFYFORMAT("const long long &a;", Style);
+  VERIFYFORMAT("const unsigned char *a;", Style);
+  VERIFYFORMAT2("const unsigned char *a;", "unsigned char const *a;", Style);
+
+  VERIFYFORMAT2("const int a;", "int const a;", Style);
+  VERIFYFORMAT2("const int *a;", "int const *a;", Style);
+  VERIFYFORMAT2("const int &a;", "int const &a;", Style);
+  VERIFYFORMAT2("foo(const int &a)", "foo(int const &a)", Style);
+  VERIFYFORMAT2("unsigned char *a;", "unsigned char *a;", Style);
+  VERIFYFORMAT2("const unsigned int &get_nu() const",
+                "unsigned int const &get_nu() const", Style);
+}
+
 } // namespace
 } // namespace format
 } // namespace clang
Index: clang/tools/clang-format/ClangFormat.cpp
===================================================================
--- clang/tools/clang-format/ClangFormat.cpp
+++ clang/tools/clang-format/ClangFormat.cpp
@@ -104,6 +104,12 @@
              "SortIncludes style flag"),
     cl::cat(ClangFormatCategory));
 
+static cl::opt<std::string> ConstStyle(
+    "const-style",
+    cl::desc("If set, overrides the const style behavior determined by the "
+             "ConstStyle style flag"),
+    cl::init(""), cl::cat(ClangFormatCategory));
+
 static cl::opt<bool>
     Verbose("verbose", cl::desc("If set, shows the list of processed files"),
             cl::cat(ClangFormatCategory));
@@ -410,6 +416,13 @@
     return true;
   }
 
+  StringRef ConstAlignment = ConstStyle;
+
+  if (ConstAlignment.lower() == "east")
+    FormatStyle->ConstStyle = FormatStyle::CS_East;
+  else if (ConstAlignment.lower() == "west")
+    FormatStyle->ConstStyle = FormatStyle::CS_West;
+
   if (SortIncludes.getNumOccurrences() != 0)
     FormatStyle->SortIncludes = SortIncludes;
   unsigned CursorPosition = Cursor;
Index: clang/lib/Format/Format.cpp
===================================================================
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -15,6 +15,7 @@
 #include "clang/Format/Format.h"
 #include "AffectedRangeManager.h"
 #include "ContinuationIndenter.h"
+#include "EastWestConstFixer.h"
 #include "FormatInternal.h"
 #include "FormatTokenLexer.h"
 #include "NamespaceEndCommentsFixer.h"
@@ -114,6 +115,14 @@
   }
 };
 
+template <> struct ScalarEnumerationTraits<FormatStyle::ConstAlignmentStyle> {
+  static void enumeration(IO &IO, FormatStyle::ConstAlignmentStyle &Value) {
+    IO.enumCase(Value, "Leave", FormatStyle::CS_Leave);
+    IO.enumCase(Value, "East", FormatStyle::CS_East);
+    IO.enumCase(Value, "West", FormatStyle::CS_West);
+  }
+};
+
 template <> struct ScalarEnumerationTraits<FormatStyle::ShortFunctionStyle> {
   static void enumeration(IO &IO, FormatStyle::ShortFunctionStyle &Value) {
     IO.enumCase(Value, "None", FormatStyle::SFS_None);
@@ -460,6 +469,7 @@
     IO.mapOptional("BreakStringLiterals", Style.BreakStringLiterals);
     IO.mapOptional("ColumnLimit", Style.ColumnLimit);
     IO.mapOptional("CommentPragmas", Style.CommentPragmas);
+    IO.mapOptional("ConstStyle", Style.ConstStyle);
     IO.mapOptional("CompactNamespaces", Style.CompactNamespaces);
     IO.mapOptional("ConstructorInitializerAllOnOneLineOrOnePerLine",
                    Style.ConstructorInitializerAllOnOneLineOrOnePerLine);
@@ -755,6 +765,7 @@
   LLVMStyle.BreakStringLiterals = true;
   LLVMStyle.ColumnLimit = 80;
   LLVMStyle.CommentPragmas = "^ IWYU pragma:";
+  LLVMStyle.ConstStyle = FormatStyle::CS_Leave;
   LLVMStyle.CompactNamespaces = false;
   LLVMStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = false;
   LLVMStyle.ConstructorInitializerIndentWidth = 4;
@@ -2403,6 +2414,13 @@
       });
   }
 
+  if (Style.isCpp() || Style.Language == FormatStyle::LK_ObjC) {
+    if (Style.ConstStyle != FormatStyle::CS_Leave)
+      Passes.emplace_back([&](const Environment &Env) {
+        return EastWestConstFixer(Env, Expanded).process();
+      });
+  }
+
   if (Style.Language == FormatStyle::LK_JavaScript &&
       Style.JavaScriptQuotes != FormatStyle::JSQS_Leave)
     Passes.emplace_back([&](const Environment &Env) {
Index: clang/lib/Format/EastWestConstFixer.h
===================================================================
--- /dev/null
+++ clang/lib/Format/EastWestConstFixer.h
@@ -0,0 +1,36 @@
+//===--- EastWwestConstFixer.h ----------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file declares EastWestConstFixer, a TokenAnalyzer that
+/// enforces either east or west const depending on the style.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_FORMAT_EASTWESTCONSTFIXER_H
+#define LLVM_CLANG_LIB_FORMAT_EASTWESTCONSTFIXER_H
+
+#include "TokenAnalyzer.h"
+
+namespace clang {
+namespace format {
+
+class EastWestConstFixer : public TokenAnalyzer {
+public:
+  EastWestConstFixer(const Environment &Env, const FormatStyle &Style);
+
+  std::pair<tooling::Replacements, unsigned>
+  analyze(TokenAnnotator &Annotator,
+          SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
+          FormatTokenLexer &Tokens) override;
+};
+
+} // end namespace format
+} // end namespace clang
+
+#endif
Index: clang/lib/Format/EastWestConstFixer.cpp
===================================================================
--- /dev/null
+++ clang/lib/Format/EastWestConstFixer.cpp
@@ -0,0 +1,153 @@
+//===--- EastWestConstFixer.cpp ---------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file implements EastWestConstFixer, a TokenAnalyzer that
+/// enforces either east or west const depending on the style.
+///
+//===----------------------------------------------------------------------===//
+
+#include "EastWestConstFixer.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Regex.h"
+
+#include <algorithm>
+
+#define DEBUG_TYPE "using-declarations-sorter"
+
+namespace clang {
+namespace format {
+
+static void swapFirstTwoTokens(const SourceManager &SourceMgr,
+                               tooling::Replacements &Fixes,
+                               const FormatToken *First,
+                               const FormatToken *Second) {
+  // Change `const int` to be `int const`.
+  std::string NewType = Second->TokenText;
+  NewType += " ";
+  NewType += First->TokenText;
+  auto Range = CharSourceRange::getCharRange(First->getStartOfNonWhitespace(),
+                                             Second->Tok.getEndLoc());
+
+  auto Err = Fixes.add(tooling::Replacement(SourceMgr, Range, NewType));
+
+  if (Err) {
+    llvm::errs() << "Error while rearranging const : "
+                 << llvm::toString(std::move(Err)) << "\n";
+  }
+}
+
+static void swapFirstThreeTokens(const SourceManager &SourceMgr,
+                                 tooling::Replacements &Fixes,
+                                 const FormatToken *First,
+                                 const FormatToken *Second,
+                                 const FormatToken *Third, bool West) {
+  // Change `const unsigned char` to be `unsigned char const`.
+  std::string NewType;
+  if (West) {
+    NewType = Third->TokenText;
+    NewType += " ";
+    NewType += First->TokenText;
+    NewType += " ";
+    NewType += Second->TokenText;
+  } else {
+    NewType = Second->TokenText;
+    NewType += " ";
+    NewType += Third->TokenText;
+    NewType += " ";
+    NewType += First->TokenText;
+  }
+
+  auto Range = CharSourceRange::getCharRange(First->getStartOfNonWhitespace(),
+                                             Third->Tok.getEndLoc());
+
+  auto Err = Fixes.add(tooling::Replacement(SourceMgr, Range, NewType));
+
+  if (Err) {
+    llvm::errs() << "Error while rearranging const : "
+                 << llvm::toString(std::move(Err)) << "\n";
+  }
+}
+
+EastWestConstFixer::EastWestConstFixer(const Environment &Env,
+                                       const FormatStyle &Style)
+    : TokenAnalyzer(Env, Style) {}
+
+std::pair<tooling::Replacements, unsigned>
+EastWestConstFixer::analyze(TokenAnnotator &Annotator,
+                            SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
+                            FormatTokenLexer &Tokens) {
+  const SourceManager &SourceMgr = Env.getSourceManager();
+  AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
+  tooling::Replacements Fixes;
+  for (size_t I = 0, E = AnnotatedLines.size(); I != E; ++I) {
+    const auto *Tok = AnnotatedLines[I]->First;
+    const auto *Last = AnnotatedLines[I]->Last;
+
+    while (Tok != Last) {
+      if (!Tok->Next) {
+        break;
+      }
+      if (Style.ConstStyle == FormatStyle::CS_East) {
+        if (Tok->is(tok::kw_const) && Tok->Next->isSimpleTypeSpecifier() &&
+            Tok->Next->Next && Tok->Next->Next->isSimpleTypeSpecifier()) {
+          // The unsigned/signed case  `const unsigned int` -> `unsigned int
+          // const`
+          swapFirstThreeTokens(SourceMgr, Fixes, Tok, Tok->Next,
+                               Tok->Next->Next, /*West=*/false);
+          Tok = Tok->Next->Next;
+          continue;
+        } else if (Tok->is(tok::kw_const) &&
+                   Tok->Next->isSimpleTypeSpecifier()) {
+          // The basic case  `const int` -> `int const`
+          swapFirstTwoTokens(SourceMgr, Fixes, Tok, Tok->Next);
+
+        } else if (Tok->startsSequence(tok::kw_const, tok::identifier)) {
+          // The case  `const Foo` -> `Foo const`
+          // The case  `const Foo *` -> `Foo const *`
+          if (Tok->startsSequence(tok::kw_const, tok::identifier,
+                                  tok::identifier) ||
+              Tok->startsSequence(tok::kw_const, tok::identifier, tok::star) ||
+              Tok->startsSequence(tok::kw_const, tok::identifier, tok::amp) ||
+              Tok->startsSequence(tok::kw_const, tok::identifier,
+                                  tok::ampamp)) {
+            swapFirstTwoTokens(SourceMgr, Fixes, Tok, Tok->Next);
+          }
+        }
+      } else if (Style.ConstStyle == FormatStyle::CS_West) {
+        if (Tok->isSimpleTypeSpecifier() &&
+            Tok->Next->isSimpleTypeSpecifier() && Tok->Next->Next &&
+            Tok->Next->Next->is(tok::kw_const)) {
+          // The unsigned/signed case  `unsigned int const` -> `const unsigned
+          // int`
+          swapFirstThreeTokens(SourceMgr, Fixes, Tok, Tok->Next,
+                               Tok->Next->Next, /*West=*/true);
+          Tok = Tok->Next->Next;
+          continue;
+        } else if (Tok->isSimpleTypeSpecifier() &&
+                   Tok->Next->is(tok::kw_const)) {
+          // The basic case  `int const` -> `const int`
+          swapFirstTwoTokens(SourceMgr, Fixes, Tok, Tok->Next);
+        } else if (Tok->startsSequence(tok::identifier, tok::kw_const)) {
+          if (Tok->startsSequence(tok::identifier, tok::kw_const,
+                                  tok::identifier) ||
+              Tok->startsSequence(tok::identifier, tok::kw_const, tok::star) ||
+              Tok->startsSequence(tok::identifier, tok::kw_const, tok::amp) ||
+              Tok->startsSequence(tok::identifier, tok::kw_const,
+                                  tok::ampamp)) {
+            swapFirstTwoTokens(SourceMgr, Fixes, Tok, Tok->Next);
+          }
+        }
+      }
+      Tok = Tok->Next;
+    }
+  }
+  return {Fixes, 0};
+}
+} // namespace format
+} // namespace clang
Index: clang/lib/Format/CMakeLists.txt
===================================================================
--- clang/lib/Format/CMakeLists.txt
+++ clang/lib/Format/CMakeLists.txt
@@ -14,6 +14,7 @@
   UnwrappedLineFormatter.cpp
   UnwrappedLineParser.cpp
   UsingDeclarationsSorter.cpp
+  EastWestConstFixer.cpp
   WhitespaceManager.cpp
 
   LINK_LIBS
Index: clang/include/clang/Format/Format.h
===================================================================
--- clang/include/clang/Format/Format.h
+++ clang/include/clang/Format/Format.h
@@ -1105,6 +1105,31 @@
   /// \endcode
   std::string CommentPragmas;
 
+  /// Different const alignment styles.
+  enum ConstAlignmentStyle {
+    /// Don't change const to either East const or West const.
+    /// \code
+    ///    int const a;
+    ///    const int *a;
+    /// \endcode
+    CS_Leave,
+    /// Change type decorations to be East const.
+    /// \code
+    ///    int const a;
+    ///    int const *a;
+    /// \endcode
+    CS_East,
+    /// Change type decorations to be West const.
+    /// \code
+    ///    const int a;
+    ///    const int *a;
+    /// \endcode
+    CS_West
+  };
+
+  /// Different ways to arrange const.
+  ConstAlignmentStyle ConstStyle;
+
   /// Different ways to break inheritance list.
   enum BreakInheritanceListStyle {
     /// Break inheritance list before the colon and after the commas.
@@ -2060,6 +2085,7 @@
            BreakAfterJavaFieldAnnotations == R.BreakAfterJavaFieldAnnotations &&
            BreakStringLiterals == R.BreakStringLiterals &&
            ColumnLimit == R.ColumnLimit && CommentPragmas == R.CommentPragmas &&
+           ConstStyle == R.ConstStyle &&
            BreakInheritanceList == R.BreakInheritanceList &&
            ConstructorInitializerAllOnOneLineOrOnePerLine ==
                R.ConstructorInitializerAllOnOneLineOrOnePerLine &&
Index: clang/docs/ClangFormatStyleOptions.rst
===================================================================
--- clang/docs/ClangFormatStyleOptions.rst
+++ clang/docs/ClangFormatStyleOptions.rst
@@ -1374,6 +1374,37 @@
     namespace Extra {
     }}}
 
+**ConstStyle** (``ConstAlignmentStyle``)
+  Different ways to arrange const.
+
+  Possible values:
+
+  * ``CS_Leave`` (in configuration: ``Leave``)
+    Don't change const to either East const or West const.
+
+    .. code-block:: c++
+
+       int const a;
+       const int *a;
+
+  * ``CS_East`` (in configuration: ``East``)
+    Change type decorations to be East const.
+
+    .. code-block:: c++
+
+       int const a;
+       int const *a;
+
+  * ``CS_West`` (in configuration: ``West``)
+    Change type decorations to be West const.
+
+    .. code-block:: c++
+
+       const int a;
+       const int *a;
+
+
+
 **ConstructorInitializerAllOnOneLineOrOnePerLine** (``bool``)
   If the constructor initializers don't fit on a line, put each
   initializer on its own line.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to