Align RHS after assignments and return statements.

This changes:
  int Result = a +  // force break
      b;
  return Result +  // force break
      5;

To:
  int Result = a +  // force break
               b;
  return Result +  // force break
         5;

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@171032 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp
index 8fb6932..056376a 100644
--- a/lib/Format/Format.cpp
+++ b/lib/Format/Format.cpp
@@ -53,6 +53,10 @@
   bool MustBreakBefore;
 };
 
+static prec::Level getPrecedence(const FormatToken &Tok) {
+  return getBinOpPrecedence(Tok.Tok.getKind(), true, true);
+}
+
 using llvm::MutableArrayRef;
 
 FormatStyle getLLVMStyle() {
@@ -266,6 +270,10 @@
       if (!DryRun)
         replaceWhitespace(Current, 0, Spaces);
 
+      // FIXME: Look into using this alignment at other ParenLevels.
+      if (ParenLevel == 0 && (getPrecedence(Previous) == prec::Assignment ||
+                              Previous.Tok.is(tok::kw_return)))
+        State.Indent[ParenLevel] = State.Column + Spaces;
       if (Previous.Tok.is(tok::l_paren) ||
           Annotations[Index - 1].Type == TokenAnnotation::TT_TemplateOpener)
         State.Indent[ParenLevel] = State.Column;
@@ -290,18 +298,20 @@
 
     State.Column += Current.Tok.getLength();
 
-    // If we encounter an opening (, [ or <, we add a level to our stacks to
+    // If we encounter an opening (, [, { or <, we add a level to our stacks to
     // prepare for the following tokens.
     if (Current.Tok.is(tok::l_paren) || Current.Tok.is(tok::l_square) ||
+        Current.Tok.is(tok::l_brace) ||
         Annotations[Index].Type == TokenAnnotation::TT_TemplateOpener) {
       State.Indent.push_back(4 + State.LastSpace.back());
       State.LastSpace.push_back(State.LastSpace.back());
       State.FirstLessLess.push_back(0);
     }
 
-    // If we encounter a closing ), ] or >, we can remove a level from our
+    // If we encounter a closing ), ], } or >, we can remove a level from our
     // stacks.
     if (Current.Tok.is(tok::r_paren) || Current.Tok.is(tok::r_square) ||
+        (Current.Tok.is(tok::r_brace) && State.ConsumedTokens > 0) ||
         Annotations[Index].Type == TokenAnnotation::TT_TemplateCloser) {
       State.Indent.pop_back();
       State.LastSpace.pop_back();
@@ -328,8 +338,7 @@
     if (Left.Tok.is(tok::l_paren))
       return 2;
 
-    prec::Level Level =
-        getBinOpPrecedence(Line.Tokens[Index].Tok.getKind(), true, true);
+    prec::Level Level = getPrecedence(Line.Tokens[Index]);
     if (Level != prec::Unknown)
       return Level;
 
@@ -742,7 +751,7 @@
       TokenAnnotation &Annotation = Annotations[i];
       const FormatToken &Tok = Line.Tokens[i];
 
-      if (getBinOpPrecedence(Tok.Tok.getKind(), true, true) == prec::Assignment)
+      if (getPrecedence(Tok) == prec::Assignment)
         IsRHS = true;
       else if (Tok.Tok.is(tok::kw_return))
         IsRHS = true;
@@ -773,7 +782,7 @@
 
   bool isBinaryOperator(const FormatToken &Tok) {
     // Comma is a binary operator, but does not behave as such wrt. formatting.
-    return getBinOpPrecedence(Tok.Tok.getKind(), true, true) > prec::Comma;
+    return getPrecedence(Tok) > prec::Comma;
   }
 
   TokenAnnotation::TokenType determineStarAmpUsage(unsigned Index,