Implement a tiny expression parser to improve formatting decisions.

With this patch, the formatter introduces 'fake' parenthesis according
to the operator precedence of binary operators.

Before:
return aaaa & AAAAAAAAAAAAAAAAAAAAAAAAAAAAA || bbbb &
       BBBBBBBBBBBBBBBBBBBBBBBBBBBBB || cccc & CCCCCCCCCCCCCCCCCCCCCCCCCC ||
       dddd & DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD;
f(aaaaaaaaaaaaaaaaaaaa && aaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaa &&
  aaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaa && aaaaaaaaaaaaaaaaaaaa);

After:
return aaaa & AAAAAAAAAAAAAAAAAAAAAAAAAAAAA ||
       bbbb & BBBBBBBBBBBBBBBBBBBBBBBBBBBBB ||
       cccc & CCCCCCCCCCCCCCCCCCCCCCCCCC ||
       dddd & DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD;
f(aaaaaaaaaaaaaaaaaaaa && aaaaaaaaaaaaaaaaaaaa,
  aaaaaaaaaaaaaaaaaaaa && aaaaaaaaaaaaaaaaaaaa,
  aaaaaaaaaaaaaaaaaaaa && aaaaaaaaaaaaaaaaaaaa);

Future improvements:
- Get rid of some of the hacky ways to nicely format certain constructs.
- Merge this parser and the AnnotatingParser as we now have several parsers
  that analyze (), [], etc.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@174714 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp
index 8a38454..485624b 100644
--- a/lib/Format/TokenAnnotator.cpp
+++ b/lib/Format/TokenAnnotator.cpp
@@ -52,6 +52,12 @@
   return getPreviousToken(const_cast<AnnotatedToken &>(Tok));
 }
 
+static bool isTrailingComment(AnnotatedToken *Tok) {
+  return Tok != NULL && Tok->is(tok::comment) &&
+         (Tok->Children.empty() ||
+          Tok->Children[0].FormatTok.NewlinesBefore > 0);
+}
+
 // Returns the next token ignoring comments.
 static const AnnotatedToken *getNextToken(const AnnotatedToken &Tok) {
   if (Tok.Children.empty())
@@ -681,12 +687,91 @@
   bool KeywordVirtualFound;
 };
 
+/// \brief Parses binary expressions by inserting fake parenthesis based on
+/// operator precedence.
+class ExpressionParser {
+public:
+  ExpressionParser(AnnotatedLine &Line) : Current(&Line.First) {}
+
+  /// \brief Parse expressions with the given operatore precedence.
+  void parse(unsigned Precedence = prec::Unknown) {
+    if (Precedence > prec::PointerToMember || Current == NULL)
+      return;
+
+    // Skip over "return" until we can properly parse it.
+    if (Current->is(tok::kw_return))
+      next();
+
+    // Eagerly consume trailing comments.
+    while (isTrailingComment(Current)) {
+      next();
+    }
+
+    AnnotatedToken *Start = Current;
+    bool OperatorFound = false;
+
+    while (Current != NULL) {
+      // Consume operators with higher precedence.
+      parse(Precedence + 1);
+
+      // At the end of the line or when an operator with higher precedence is
+      // found, insert fake parenthesis and return.
+      if (Current == NULL || Current->is(tok::semi) || closesScope(*Current) ||
+          ((Current->Type == TT_BinaryOperator || Current->is(tok::comma)) &&
+           getPrecedence(*Current) < Precedence)) {
+        if (OperatorFound) {
+          ++Start->FakeLParens;
+          if (Current != NULL)
+            ++Current->FakeRParens;
+        }
+        return;
+      }
+
+      // Consume scopes: (), [], <> and {}
+      if (opensScope(*Current)) {
+        while (Current != NULL && !closesScope(*Current)) {
+          next();
+          parse();
+        }
+        next();
+      } else {
+        // Operator found.
+        if (getPrecedence(*Current) == Precedence)
+          OperatorFound = true;
+
+        next();
+      }
+    }
+  }
+
+private:
+  void next() {
+    if (Current != NULL)
+      Current = Current->Children.empty() ? NULL : &Current->Children[0];
+  }
+
+  bool closesScope(const AnnotatedToken &Tok) {
+    return Current->is(tok::r_paren) || Current->Type == TT_TemplateCloser ||
+           Current->is(tok::r_brace) || Current->is(tok::r_square);
+  }
+
+  bool opensScope(const AnnotatedToken &Tok) {
+    return Current->is(tok::l_paren) || Current->Type == TT_TemplateOpener ||
+           Current->is(tok::l_brace) || Current->is(tok::l_square);
+  }
+
+  AnnotatedToken *Current;
+};
+
 void TokenAnnotator::annotate(AnnotatedLine &Line) {
   AnnotatingParser Parser(SourceMgr, Lex, Line);
   Line.Type = Parser.parseLine();
   if (Line.Type == LT_Invalid)
     return;
 
+  ExpressionParser ExprParser(Line);
+  ExprParser.parse();
+
   if (Line.First.Type == TT_ObjCMethodSpecifier)
     Line.Type = LT_ObjCMethodDecl;
   else if (Line.First.Type == TT_ObjCDecl)
@@ -712,8 +797,7 @@
       Current->MustBreakBefore = true;
     } else if (Current->Type == TT_LineComment) {
       Current->MustBreakBefore = Current->FormatTok.NewlinesBefore > 0;
-    } else if ((Current->Parent->is(tok::comment) &&
-                Current->FormatTok.NewlinesBefore > 0) ||
+    } else if (isTrailingComment(Current->Parent) ||
                (Current->is(tok::string_literal) &&
                 Current->Parent->is(tok::string_literal))) {
       Current->MustBreakBefore = true;
@@ -839,8 +923,7 @@
            (Left.isNot(tok::star) && Left.isNot(tok::amp) &&
             !Style.PointerBindsToType);
   if (Left.is(tok::amp) || Left.is(tok::star))
-    return Right.FormatTok.Tok.isLiteral() ||
-           Style.PointerBindsToType;
+    return Right.FormatTok.Tok.isLiteral() || Style.PointerBindsToType;
   if (Right.is(tok::star) && Left.is(tok::l_paren))
     return false;
   if (Left.is(tok::l_square) || Right.is(tok::r_square))
@@ -911,8 +994,9 @@
            (Tok.Parent->isNot(tok::colon) ||
             Tok.Parent->Type != TT_ObjCMethodExpr);
   if (Tok.Parent->is(tok::greater) && Tok.is(tok::greater)) {
-    return Tok.Type == TT_TemplateCloser && Tok.Parent->Type ==
-           TT_TemplateCloser && Style.Standard != FormatStyle::LS_Cpp11;
+    return Tok.Type == TT_TemplateCloser &&
+           Tok.Parent->Type == TT_TemplateCloser &&
+           Style.Standard != FormatStyle::LS_Cpp11;
   }
   if (Tok.Type == TT_BinaryOperator || Tok.Parent->Type == TT_BinaryOperator)
     return true;