clang-format: Add two new style options to support WebKit style.

New options:
* Break before the commas of constructor initializers and align
  the commas with the colon.
* Break before binary operators

Additionally, for styles without column limit, don't just accept
linebreaks done by the user, but instead remove 'invalid' (according
to the current style) linebreaks and add 'required' ones.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@187210 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp
index 2dee567..0086936 100644
--- a/lib/Format/Format.cpp
+++ b/lib/Format/Format.cpp
@@ -89,6 +89,10 @@
                    Style.AlwaysBreakTemplateDeclarations);
     IO.mapOptional("AlwaysBreakBeforeMultilineStrings",
                    Style.AlwaysBreakBeforeMultilineStrings);
+    IO.mapOptional("BreakBeforeBinaryOperators",
+                   Style.BreakBeforeBinaryOperators);
+    IO.mapOptional("BreakConstructorInitializersBeforeComma",
+                   Style.BreakConstructorInitializersBeforeComma);
     IO.mapOptional("BinPackParameters", Style.BinPackParameters);
     IO.mapOptional("ColumnLimit", Style.ColumnLimit);
     IO.mapOptional("ConstructorInitializerAllOnOneLineOrOnePerLine",
@@ -139,24 +143,26 @@
   LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true;
   LLVMStyle.AllowShortIfStatementsOnASingleLine = false;
   LLVMStyle.AllowShortLoopsOnASingleLine = false;
-  LLVMStyle.AlwaysBreakTemplateDeclarations = false;
   LLVMStyle.AlwaysBreakBeforeMultilineStrings = false;
+  LLVMStyle.AlwaysBreakTemplateDeclarations = false;
   LLVMStyle.BinPackParameters = true;
+  LLVMStyle.BreakBeforeBinaryOperators = false;
+  LLVMStyle.BreakBeforeBraces = FormatStyle::BS_Attach;
+  LLVMStyle.BreakConstructorInitializersBeforeComma = false;
   LLVMStyle.ColumnLimit = 80;
   LLVMStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = false;
+  LLVMStyle.Cpp11BracedListStyle = false;
   LLVMStyle.DerivePointerBinding = false;
   LLVMStyle.ExperimentalAutoDetectBinPacking = false;
   LLVMStyle.IndentCaseLabels = false;
+  LLVMStyle.IndentFunctionDeclarationAfterType = false;
+  LLVMStyle.IndentWidth = 2;
   LLVMStyle.MaxEmptyLinesToKeep = 1;
   LLVMStyle.ObjCSpaceBeforeProtocolList = true;
   LLVMStyle.PointerBindsToType = false;
   LLVMStyle.SpacesBeforeTrailingComments = 1;
-  LLVMStyle.Cpp11BracedListStyle = false;
   LLVMStyle.Standard = FormatStyle::LS_Cpp03;
-  LLVMStyle.IndentWidth = 2;
   LLVMStyle.UseTab = false;
-  LLVMStyle.BreakBeforeBraces = FormatStyle::BS_Attach;
-  LLVMStyle.IndentFunctionDeclarationAfterType = false;
 
   setDefaultPenalties(LLVMStyle);
   LLVMStyle.PenaltyReturnTypeOnItsOwnLine = 60;
@@ -171,24 +177,26 @@
   GoogleStyle.AllowAllParametersOfDeclarationOnNextLine = true;
   GoogleStyle.AllowShortIfStatementsOnASingleLine = true;
   GoogleStyle.AllowShortLoopsOnASingleLine = true;
-  GoogleStyle.AlwaysBreakTemplateDeclarations = true;
   GoogleStyle.AlwaysBreakBeforeMultilineStrings = true;
+  GoogleStyle.AlwaysBreakTemplateDeclarations = true;
   GoogleStyle.BinPackParameters = true;
+  GoogleStyle.BreakBeforeBinaryOperators = false;
+  GoogleStyle.BreakBeforeBraces = FormatStyle::BS_Attach;
+  GoogleStyle.BreakConstructorInitializersBeforeComma = false;
   GoogleStyle.ColumnLimit = 80;
   GoogleStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = true;
+  GoogleStyle.Cpp11BracedListStyle = true;
   GoogleStyle.DerivePointerBinding = true;
   GoogleStyle.ExperimentalAutoDetectBinPacking = false;
   GoogleStyle.IndentCaseLabels = true;
+  GoogleStyle.IndentFunctionDeclarationAfterType = true;
+  GoogleStyle.IndentWidth = 2;
   GoogleStyle.MaxEmptyLinesToKeep = 1;
   GoogleStyle.ObjCSpaceBeforeProtocolList = false;
   GoogleStyle.PointerBindsToType = true;
   GoogleStyle.SpacesBeforeTrailingComments = 2;
-  GoogleStyle.Cpp11BracedListStyle = true;
   GoogleStyle.Standard = FormatStyle::LS_Auto;
-  GoogleStyle.IndentWidth = 2;
   GoogleStyle.UseTab = false;
-  GoogleStyle.BreakBeforeBraces = FormatStyle::BS_Attach;
-  GoogleStyle.IndentFunctionDeclarationAfterType = true;
 
   setDefaultPenalties(GoogleStyle);
   GoogleStyle.PenaltyReturnTypeOnItsOwnLine = 200;
@@ -202,8 +210,8 @@
   ChromiumStyle.AllowShortIfStatementsOnASingleLine = false;
   ChromiumStyle.AllowShortLoopsOnASingleLine = false;
   ChromiumStyle.BinPackParameters = false;
-  ChromiumStyle.Standard = FormatStyle::LS_Cpp03;
   ChromiumStyle.DerivePointerBinding = false;
+  ChromiumStyle.Standard = FormatStyle::LS_Cpp03;
   return ChromiumStyle;
 }
 
@@ -222,8 +230,10 @@
 FormatStyle getWebKitStyle() {
   FormatStyle Style = getLLVMStyle();
   Style.ColumnLimit = 0;
-  Style.IndentWidth = 4;
   Style.BreakBeforeBraces = FormatStyle::BS_Stroustrup;
+  Style.BreakBeforeBinaryOperators = true;
+  Style.BreakConstructorInitializersBeforeComma = true;
+  Style.IndentWidth = 4;
   Style.PointerBindsToType = true;
   return Style;
 }
@@ -526,7 +536,8 @@
   /// input's line breaking decisions.
   void formatWithoutColumnLimit(LineState &State) {
     while (State.NextToken != NULL) {
-      bool Newline = State.NextToken->NewlinesBefore > 0;
+      bool Newline = mustBreak(State) ||
+                     (canBreak(State) && State.NextToken->NewlinesBefore > 0);
       addTokenToState(Newline, /*DryRun=*/false, State);
     }
   }
@@ -786,7 +797,8 @@
       //     : First(...), ...
       //       Next(...)
       //       ^ line up here.
-      State.Stack.back().Indent = State.Column + 2;
+      if (!Style.BreakConstructorInitializersBeforeComma)
+        State.Stack.back().Indent = State.Column + 2;
       if (Style.ConstructorInitializerAllOnOneLineOrOnePerLine)
         State.Stack.back().AvoidBinPacking = true;
       State.Stack.back().BreakBeforeParameter = false;
@@ -825,7 +837,8 @@
       // prec::Assignment) as those have different indentation rules. Indent
       // other expression, unless the indentation needs to be skipped.
       if (*I == prec::Conditional ||
-          (!SkipFirstExtraIndent && *I > prec::Assignment))
+          (!SkipFirstExtraIndent && *I > prec::Assignment &&
+           !Style.BreakBeforeBinaryOperators))
         NewParenState.Indent += 4;
       if (Previous && !Previous->opensScope())
         NewParenState.BreakBeforeParameter = false;
@@ -1196,6 +1209,12 @@
        return true;
     if (Previous.is(tok::semi) && State.LineContainsContinuedForLoopSection)
       return true;
+    if (Style.BreakConstructorInitializersBeforeComma) {
+      if (Previous.Type == TT_CtorInitializerComma)
+        return false;
+      if (Current.Type == TT_CtorInitializerComma)
+        return true;
+    }
     if ((Previous.isOneOf(tok::comma, tok::semi) || Current.is(tok::question) ||
          Current.Type == TT_ConditionalExpr) &&
         State.Stack.back().BreakBeforeParameter &&
@@ -1211,29 +1230,34 @@
          (Current.TokenText.find("\\\n") != StringRef::npos)))
       return true;
 
-    // If we need to break somewhere inside the LHS of a binary expression, we
-    // should also break after the operator. Otherwise, the formatting would
-    // hide the operator precedence, e.g. in:
-    //   if (aaaaaaaaaaaaaa ==
-    //           bbbbbbbbbbbbbb && c) {..
-    // For comparisons, we only apply this rule, if the LHS is a binary
-    // expression itself as otherwise, the line breaks seem superfluous.
-    // We need special cases for ">>" which we have split into two ">" while
-    // lexing in order to make template parsing easier.
-    bool IsComparison = (Previous.getPrecedence() == prec::Relational ||
-                         Previous.getPrecedence() == prec::Equality) &&
-                        Previous.Previous &&
-                        Previous.Previous->Type != TT_BinaryOperator; // For >>.
-    bool LHSIsBinaryExpr =
-        Previous.Previous && Previous.Previous->FakeRParens > 0;
-    if (Previous.Type == TT_BinaryOperator &&
-        (!IsComparison || LHSIsBinaryExpr) &&
-        Current.Type != TT_BinaryOperator && // For >>.
-        !Current.isTrailingComment() &&
-        !Previous.isOneOf(tok::lessless, tok::question) &&
-        Previous.getPrecedence() != prec::Assignment &&
-        State.Stack.back().BreakBeforeParameter)
-      return true;
+    if (!Style.BreakBeforeBinaryOperators) {
+      // If we need to break somewhere inside the LHS of a binary expression, we
+      // should also break after the operator. Otherwise, the formatting would
+      // hide the operator precedence, e.g. in:
+      //   if (aaaaaaaaaaaaaa ==
+      //           bbbbbbbbbbbbbb && c) {..
+      // For comparisons, we only apply this rule, if the LHS is a binary
+      // expression itself as otherwise, the line breaks seem superfluous.
+      // We need special cases for ">>" which we have split into two ">" while
+      // lexing in order to make template parsing easier.
+      //
+      // FIXME: We'll need something similar for styles that break before binary
+      // operators.
+      bool IsComparison = (Previous.getPrecedence() == prec::Relational ||
+                           Previous.getPrecedence() == prec::Equality) &&
+                          Previous.Previous && Previous.Previous->Type !=
+                                                   TT_BinaryOperator; // For >>.
+      bool LHSIsBinaryExpr =
+          Previous.Previous && Previous.Previous->FakeRParens > 0;
+      if (Previous.Type == TT_BinaryOperator &&
+          (!IsComparison || LHSIsBinaryExpr) &&
+          Current.Type != TT_BinaryOperator && // For >>.
+          !Current.isTrailingComment() &&
+          !Previous.isOneOf(tok::lessless, tok::question) &&
+          Previous.getPrecedence() != prec::Assignment &&
+          State.Stack.back().BreakBeforeParameter)
+        return true;
+    }
 
     // Same as above, but for the first "<<" operator.
     if (Current.is(tok::lessless) && State.Stack.back().BreakBeforeParameter &&
diff --git a/lib/Format/FormatToken.h b/lib/Format/FormatToken.h
index 3841e49..0f9f47a 100644
--- a/lib/Format/FormatToken.h
+++ b/lib/Format/FormatToken.h
@@ -28,6 +28,7 @@
   TT_CastRParen,
   TT_ConditionalExpr,
   TT_CtorInitializerColon,
+  TT_CtorInitializerComma,
   TT_DesignatedInitializerPeriod,
   TT_ImplicitStringLiteral,
   TT_InlineASMColon,
diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp
index 3199cd9..a7fa3ec 100644
--- a/lib/Format/TokenAnnotator.cpp
+++ b/lib/Format/TokenAnnotator.cpp
@@ -405,6 +405,8 @@
     case tok::comma:
       if (Contexts.back().FirstStartOfName)
         Contexts.back().FirstStartOfName->PartOfMultiVariableDeclStmt = true;
+      if (Contexts.back().InCtorInitializer)
+        Tok->Type = TT_CtorInitializerComma;
       break;
     default:
       break;
@@ -538,7 +540,8 @@
           LongestObjCSelectorName(0), ColonIsForRangeExpr(false),
           ColonIsObjCDictLiteral(false), ColonIsObjCMethodExpr(false),
           FirstObjCSelectorName(NULL), FirstStartOfName(NULL),
-          IsExpression(IsExpression), CanBeExpression(true) {}
+          IsExpression(IsExpression), CanBeExpression(true),
+          InCtorInitializer(false) {}
 
     tok::TokenKind ContextKind;
     unsigned BindingStrength;
@@ -550,6 +553,7 @@
     FormatToken *FirstStartOfName;
     bool IsExpression;
     bool CanBeExpression;
+    bool InCtorInitializer;
   };
 
   /// \brief Puts a new \c Context onto the stack \c Contexts for the lifetime
@@ -595,6 +599,7 @@
     } else if (Current.Previous &&
                Current.Previous->Type == TT_CtorInitializerColon) {
       Contexts.back().IsExpression = true;
+      Contexts.back().InCtorInitializer = true;
     } else if (Current.is(tok::kw_new)) {
       Contexts.back().CanBeExpression = false;
     } else if (Current.is(tok::semi)) {
@@ -963,6 +968,9 @@
     } else if (Current->Previous->ClosesTemplateDeclaration &&
                Style.AlwaysBreakTemplateDeclarations) {
       Current->MustBreakBefore = true;
+    } else if (Current->Type == TT_CtorInitializerComma &&
+               Style.BreakConstructorInitializersBeforeComma) {
+      Current->MustBreakBefore = true;
     }
     Current->CanBreakBefore =
         Current->MustBreakBefore || canBreakBefore(Line, *Current);
@@ -1278,7 +1286,8 @@
 
   // We only break before r_brace if there was a corresponding break before
   // the l_brace, which is tracked by BreakBeforeClosingBrace.
-  if (Right.isOneOf(tok::r_brace, tok::r_paren, tok::greater))
+  if (Right.isOneOf(tok::r_brace, tok::r_paren) ||
+      Right.Type == TT_TemplateCloser)
     return false;
 
   // Allow breaking after a trailing 'const', e.g. after a method declaration,
@@ -1292,7 +1301,14 @@
 
   if (Left.is(tok::identifier) && Right.is(tok::string_literal))
     return true;
-  return (Left.isBinaryOperator() && Left.isNot(tok::lessless)) ||
+
+  if (Left.Type == TT_CtorInitializerComma &&
+      Style.BreakConstructorInitializersBeforeComma)
+    return false;
+  if (Right.isBinaryOperator() && Style.BreakBeforeBinaryOperators)
+    return true;
+  return (Left.isBinaryOperator() && Left.isNot(tok::lessless) &&
+          !Style.BreakBeforeBinaryOperators) ||
          Left.isOneOf(tok::comma, tok::coloncolon, tok::semi, tok::l_brace,
                       tok::kw_class, tok::kw_struct) ||
          Right.isOneOf(tok::lessless, tok::arrow, tok::period, tok::colon) ||