Date: Sat, 15 Dec 2018 21:21:17 +0200
Subject: [PATCH] Add AlwaysAfterColon to clang-format

---
 include/clang/Format/Format.h       |  9 ++++++++-
 lib/Format/ContinuationIndenter.cpp | 23 +++++++++++++++++------
 lib/Format/Format.cpp               |  1 +
 lib/Format/TokenAnnotator.cpp       | 18 ++++++++++++++----
 4 files changed, 40 insertions(+), 11 deletions(-)

diff --git a/include/clang/Format/Format.h b/include/clang/Format/Format.h
index cb37b0c890..2da1485b31 100644
--- a/include/clang/Format/Format.h
+++ b/include/clang/Format/Format.h
@@ -858,7 +858,14 @@ struct FormatStyle {
     ///        initializer1(),
     ///        initializer2()
     /// \endcode
-    BCIS_AfterColon
+    BCIS_AfterColon,
+    /// Always break constructor initializers after the colon and commas.
+    /// \code
+    ///    Constructor() :
+    ///        initializer1(),
+    ///        initializer2()
+    /// \endcode
+    BCIS_AlwaysAfterColon
   };
 
   /// The constructor initializers style to use.
diff --git a/lib/Format/ContinuationIndenter.cpp b/lib/Format/ContinuationIndenter.cpp
index c369b94b99..4002b45033 100644
--- a/lib/Format/ContinuationIndenter.cpp
+++ b/lib/Format/ContinuationIndenter.cpp
@@ -367,13 +367,17 @@ bool ContinuationIndenter::mustBreak(const LineState &State) {
     return true;
 
   const FormatToken &BreakConstructorInitializersToken =
-      Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon
+      Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon ||
+              Style.BreakConstructorInitializers ==
+                  FormatStyle::BCIS_AlwaysAfterColon
           ? Previous
           : Current;
   if (BreakConstructorInitializersToken.is(TT_CtorInitializerColon) &&
       (State.Column + State.Line->Last->TotalLength - Previous.TotalLength >
            getColumnLimit(State) ||
-       State.Stack.back().BreakBeforeParameter) &&
+       State.Stack.back().BreakBeforeParameter ||
+       Style.BreakConstructorInitializers ==
+           FormatStyle::BCIS_AlwaysAfterColon) &&
       (Style.AllowShortFunctionsOnASingleLine != FormatStyle::SFS_All ||
        Style.BreakConstructorInitializers != FormatStyle::BCIS_BeforeColon ||
        Style.ColumnLimit != 0))
@@ -689,8 +693,10 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
               (Previous.is(tok::colon) && Previous.is(TT_ObjCMethodExpr)))) {
     State.Stack.back().LastSpace = State.Column;
   } else if (Previous.is(TT_CtorInitializerColon) &&
+             (Style.BreakConstructorInitializers ==
+                     FormatStyle::BCIS_AfterColon ||
              Style.BreakConstructorInitializers ==
-                 FormatStyle::BCIS_AfterColon) {
+                 FormatStyle::BCIS_AlwaysAfterColon)) {
     State.Stack.back().Indent = State.Column;
     State.Stack.back().LastSpace = State.Column;
   } else if ((Previous.isOneOf(TT_BinaryOperator, TT_ConditionalExpr,
@@ -1028,7 +1034,8 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) {
   if (NextNonComment->is(TT_CtorInitializerComma))
     return State.Stack.back().Indent;
   if (PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
-      Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon)
+          Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon ||
+      Style.BreakConstructorInitializers == FormatStyle::BCIS_AlwaysAfterColon)
     return State.Stack.back().Indent;
   if (PreviousNonComment && PreviousNonComment->is(TT_InheritanceColon) &&
       Style.BreakInheritanceList == FormatStyle::BILS_AfterColon)
@@ -1091,7 +1098,9 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
   if (Current.is(TT_SelectorName))
     State.Stack.back().ObjCSelectorNameFound = true;
   if (Current.is(TT_CtorInitializerColon) &&
-      Style.BreakConstructorInitializers != FormatStyle::BCIS_AfterColon) {
+      Style.BreakConstructorInitializers != FormatStyle::BCIS_AfterColon &&
+      Style.BreakConstructorInitializers !=
+          FormatStyle::BCIS_AlwaysAfterColon) {
     // Indent 2 from the column, so:
     // SomeClass::SomeClass()
     //     : First(...), ...
@@ -1108,7 +1117,9 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
     State.Stack.back().BreakBeforeParameter = false;
   }
   if (Current.is(TT_CtorInitializerColon) &&
-      Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon) {
+          Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon ||
+      Style.BreakConstructorInitializers ==
+          FormatStyle::BCIS_AlwaysAfterColon) {
     State.Stack.back().Indent =
         State.FirstIndent + Style.ConstructorInitializerIndentWidth;
     State.Stack.back().NestedBlockIndent = State.Stack.back().Indent;
diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp
index 2c4f876054..a9b5058b00 100644
--- a/lib/Format/Format.cpp
+++ b/lib/Format/Format.cpp
@@ -145,6 +145,7 @@ struct ScalarEnumerationTraits<FormatStyle::BreakConstructorInitializersStyle> {
     IO.enumCase(Value, "BeforeColon", FormatStyle::BCIS_BeforeColon);
     IO.enumCase(Value, "BeforeComma", FormatStyle::BCIS_BeforeComma);
     IO.enumCase(Value, "AfterColon", FormatStyle::BCIS_AfterColon);
+    IO.enumCase(Value, "AlwaysAfterColon", FormatStyle::BCIS_AlwaysAfterColon);
   }
 };
 
diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp
index a04f2e672b..593feb623d 100644
--- a/lib/Format/TokenAnnotator.cpp
+++ b/lib/Format/TokenAnnotator.cpp
@@ -28,7 +28,7 @@ namespace {
 /// Returns \c true if the token can be used as an identifier in
 /// an Objective-C \c @selector, \c false otherwise.
 ///
-/// Because getFormattingLangOpts() always lexes source code as
+/// Because getFormattingLangOpts() always lexes source code as 
 /// Objective-C++, C++ keywords like \c new and \c delete are
 /// lexed as tok::kw_*, not tok::identifier, even for Objective-C.
 ///
@@ -2930,6 +2930,9 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
       Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma &&
       !Style.ConstructorInitializerAllOnOneLineOrOnePerLine)
     return true;
+  if (Left.is(TT_CtorInitializerColon) &&
+      Style.BreakConstructorInitializers == FormatStyle::BCIS_AlwaysAfterColon)
+    return true;
   // Break only if we have multiple inheritance.
   if (Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma &&
       Right.is(TT_InheritanceComma))
@@ -3185,7 +3188,10 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
     // list.
     return Left.BlockKind == BK_BracedInit ||
            (Left.is(TT_CtorInitializerColon) &&
-            Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon);
+                Style.BreakConstructorInitializers ==
+                    FormatStyle::BCIS_AfterColon ||
+            Style.BreakConstructorInitializers ==
+                FormatStyle::BCIS_AlwaysAfterColon);
   if (Left.is(tok::question) && Right.is(tok::colon))
     return false;
   if (Right.is(TT_ConditionalExpr) || Right.is(tok::question))
@@ -3303,9 +3309,13 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
     return true;
 
   if (Left.is(TT_CtorInitializerColon))
-    return Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon;
+    return Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon ||
+           Style.BreakConstructorInitializers ==
+               FormatStyle::BCIS_AlwaysAfterColon;
   if (Right.is(TT_CtorInitializerColon))
-    return Style.BreakConstructorInitializers != FormatStyle::BCIS_AfterColon;
+    return Style.BreakConstructorInitializers != FormatStyle::BCIS_AfterColon &&
+           Style.BreakConstructorInitializers !=
+               FormatStyle::BCIS_AlwaysAfterColon;
   if (Left.is(TT_CtorInitializerComma) &&
       Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma)
     return false;
-- 
2.17.1.windows.2

