Hi,

the attached patch adds a clang-format option to always break
constructor initializers before the initial colon.

So this patch adds an option to turn

Constructor : foo(bar)
{}

into

Constructor
    : foo(bar)
{}

I don't know if this style is widely distributed, but I use it to
minimize the diff when I add new members to the list of constructor
initializers, since I can add a second member to the list without
modifying any of the existing lines:

Constructor
    : foo(bar)
    , baz()
{}

>From my understanding this is not possible with the current set of
options.

Florian Sowade
diff --git a/docs/ClangFormatStyleOptions.rst b/docs/ClangFormatStyleOptions.rst
index d73801c..08f4b3a 100644
--- a/docs/ClangFormatStyleOptions.rst
+++ b/docs/ClangFormatStyleOptions.rst
@@ -117,6 +117,10 @@ the configuration (without a prefix: ``Auto``).
 **AlwaysBreakBeforeMultilineStrings** (``bool``)
   If ``true``, always break before multiline string literals.
 
+**AlwaysBreakConstructorInitializersBeforeColon** (``bool``)
+  Always break constructor initializers before the initial colon,
+  even if they fit into a single line.
+
 **AlwaysBreakTemplateDeclarations** (``bool``)
   If ``true``, always break after the ``template<...>`` of a
   template declaration.
diff --git a/include/clang/Format/Format.h b/include/clang/Format/Format.h
index 5da14fc..3a0a5d6 100644
--- a/include/clang/Format/Format.h
+++ b/include/clang/Format/Format.h
@@ -148,6 +148,10 @@ struct FormatStyle {
   /// the commas with the colon.
   bool BreakConstructorInitializersBeforeComma;
 
+  /// \brief Always break constructor initializers before the initial colon,
+  /// even if they fit into a single line.
+  bool AlwaysBreakConstructorInitializersBeforeColon;
+
   /// \brief If \c true, <tt>if (a) return;</tt> can be put on a single
   /// line.
   bool AllowShortIfStatementsOnASingleLine;
@@ -283,6 +287,8 @@ struct FormatStyle {
                R.AlwaysBreakTemplateDeclarations &&
            AlwaysBreakBeforeMultilineStrings ==
                R.AlwaysBreakBeforeMultilineStrings &&
+           AlwaysBreakConstructorInitializersBeforeColon ==
+               R.AlwaysBreakConstructorInitializersBeforeColon &&
            BinPackParameters == R.BinPackParameters &&
            BreakBeforeBinaryOperators == R.BreakBeforeBinaryOperators &&
            BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators &&
diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp
index 26a320b..a9e548e 100644
--- a/lib/Format/Format.cpp
+++ b/lib/Format/Format.cpp
@@ -136,6 +136,8 @@ template <> struct MappingTraits<clang::format::FormatStyle> {
                    Style.AlwaysBreakTemplateDeclarations);
     IO.mapOptional("AlwaysBreakBeforeMultilineStrings",
                    Style.AlwaysBreakBeforeMultilineStrings);
+    IO.mapOptional("AlwaysBreakConstructorInitializersBeforeColon",
+                   Style.AlwaysBreakConstructorInitializersBeforeColon);
     IO.mapOptional("BreakBeforeBinaryOperators",
                    Style.BreakBeforeBinaryOperators);
     IO.mapOptional("BreakBeforeTernaryOperators",
@@ -240,6 +242,7 @@ FormatStyle getLLVMStyle() {
   LLVMStyle.AllowShortIfStatementsOnASingleLine = false;
   LLVMStyle.AllowShortLoopsOnASingleLine = false;
   LLVMStyle.AlwaysBreakBeforeMultilineStrings = false;
+  LLVMStyle.AlwaysBreakConstructorInitializersBeforeColon = false;
   LLVMStyle.AlwaysBreakTemplateDeclarations = false;
   LLVMStyle.BinPackParameters = true;
   LLVMStyle.BreakBeforeBinaryOperators = false;
@@ -289,6 +292,7 @@ FormatStyle getGoogleStyle() {
   GoogleStyle.AllowShortIfStatementsOnASingleLine = true;
   GoogleStyle.AllowShortLoopsOnASingleLine = true;
   GoogleStyle.AlwaysBreakBeforeMultilineStrings = true;
+  GoogleStyle.AlwaysBreakConstructorInitializersBeforeColon = false;
   GoogleStyle.AlwaysBreakTemplateDeclarations = true;
   GoogleStyle.BinPackParameters = true;
   GoogleStyle.BreakBeforeBinaryOperators = false;
diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp
index 804db62..7f2fed2 100644
--- a/lib/Format/TokenAnnotator.cpp
+++ b/lib/Format/TokenAnnotator.cpp
@@ -1404,6 +1404,9 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
              Style.BreakConstructorInitializersBeforeComma &&
              !Style.ConstructorInitializerAllOnOneLineOrOnePerLine) {
     return true;
+  } else if (Right.Type == TT_CtorInitializerColon &&
+             Style.AlwaysBreakConstructorInitializersBeforeColon) {
+    return true;
   } else if (Right.Previous->BlockKind == BK_Block &&
              Right.Previous->isNot(tok::r_brace) && Right.isNot(tok::r_brace)) {
     return true;
diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp
index 575644e..ee33e3a 100644
--- a/unittests/Format/FormatTest.cpp
+++ b/unittests/Format/FormatTest.cpp
@@ -2866,6 +2866,15 @@ TEST_F(FormatTest, ConstructorInitializers) {
                "    : aaaaa(aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa,\n"
                "            aaaaaaaaaaaaaaaaaaaaaa) {}",
                OnePerLine);
+
+  FormatStyle AlwaysBreakColon = getLLVMStyle();
+  AlwaysBreakColon.AlwaysBreakConstructorInitializersBeforeColon = true;
+  verifyFormat("Constructor()\n"
+               "    : Initializer(FitsOnTheLine) {}",
+               AlwaysBreakColon);
+  verifyFormat("Constructor()\n"
+               "    : aaa(aaa), aaa(aaa), aaa(aaa) {}",
+               AlwaysBreakColon);
 }
 
 TEST_F(FormatTest, MemoizationTests) {
@@ -6959,6 +6968,7 @@ TEST_F(FormatTest, ParsesConfiguration) {
   CHECK_PARSE_BOOL(AllowShortIfStatementsOnASingleLine);
   CHECK_PARSE_BOOL(AllowShortLoopsOnASingleLine);
   CHECK_PARSE_BOOL(AlwaysBreakTemplateDeclarations);
+  CHECK_PARSE_BOOL(AlwaysBreakConstructorInitializersBeforeColon);
   CHECK_PARSE_BOOL(BinPackParameters);
   CHECK_PARSE_BOOL(BreakBeforeBinaryOperators);
   CHECK_PARSE_BOOL(BreakBeforeTernaryOperators);
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to