Added AnnotatedToken::isOneOf + a few other refactorings

Summary: <subj>

Reviewers: djasper

Reviewed By: djasper

CC: cfe-commits, klimek

Differential Revision: http://llvm-reviews.chandlerc.com/D536

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@176951 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp
index 74adebe..67ca928 100644
--- a/lib/Format/Format.cpp
+++ b/lib/Format/Format.cpp
@@ -499,9 +499,8 @@
                  State.Stack.back().FirstLessLess != 0) {
         State.Column = State.Stack.back().FirstLessLess;
       } else if (State.ParenLevel != 0 &&
-                 (Previous.is(tok::equal) || Previous.is(tok::coloncolon) ||
-                  Current.is(tok::period) || Current.is(tok::arrow) ||
-                  Current.is(tok::question))) {
+                 (Previous.isOneOf(tok::equal, tok::coloncolon) ||
+                  Current.isOneOf(tok::period, tok::arrow, tok::question))) {
         // Indent and extra 4 spaces after if we know the current expression is
         // continued.  Don't do that on the top level, as we already indent 4
         // there.
@@ -534,7 +533,7 @@
 
       if (Current.is(tok::question))
         State.Stack.back().BreakBeforeParameter = true;
-      if ((Previous.is(tok::comma) || Previous.is(tok::semi)) &&
+      if (Previous.isOneOf(tok::comma, tok::semi) &&
           !State.Stack.back().AvoidBinPacking)
         State.Stack.back().BreakBeforeParameter = false;
 
@@ -562,7 +561,7 @@
       for (unsigned i = 0, e = State.Stack.size() - 1; i != e; ++i) {
         State.Stack[i].BreakBeforeParameter = true;
       }
-      if (Current.is(tok::period) || Current.is(tok::arrow))
+      if (Current.isOneOf(tok::period, tok::arrow))
         State.Stack.back().BreakBeforeParameter = true;
 
       // If we break after {, we should also break before the corresponding }.
@@ -600,7 +599,7 @@
       }
 
       if (Current.Type != TT_LineComment &&
-          (Previous.is(tok::l_paren) || Previous.is(tok::l_brace) ||
+          (Previous.isOneOf(tok::l_paren, tok::l_brace) ||
            State.NextToken->Parent->Type == TT_TemplateOpener))
         State.Stack.back().Indent = State.Column + Spaces;
       if (Previous.is(tok::comma) && !isTrailingComment(Current))
@@ -622,8 +621,7 @@
       else if (Previous.Type == TT_InheritanceColon)
         State.Stack.back().Indent = State.Column;
       else if (Previous.ParameterCount > 1 &&
-               (Previous.is(tok::l_paren) || Previous.is(tok::l_square) ||
-                Previous.is(tok::l_brace) ||
+               (Previous.isOneOf(tok::l_paren, tok::l_square, tok::l_brace) ||
                 Previous.Type == TT_TemplateOpener))
         // If this function has multiple parameters, indent nested calls from
         // the start of the first parameter.
@@ -645,7 +643,7 @@
       State.Stack.back().FirstLessLess = State.Column;
     if (Current.is(tok::question))
       State.Stack.back().QuestionColumn = State.Column;
-    if ((Current.is(tok::period) || Current.is(tok::arrow)) &&
+    if (Current.isOneOf(tok::period, tok::arrow) &&
         Line.Type == LT_BuilderTypeCall && State.ParenLevel == 0)
       State.Stack.back().StartOfFunctionCall =
           Current.LastInChainOfCalls ? 0 : State.Column;
@@ -665,8 +663,7 @@
 
     // If we encounter an opening (, [, { or <, we add a level to our stacks to
     // prepare for the following tokens.
-    if (Current.is(tok::l_paren) || Current.is(tok::l_square) ||
-        Current.is(tok::l_brace) ||
+    if (Current.isOneOf(tok::l_paren, tok::l_square, tok::l_brace) ||
         State.NextToken->Type == TT_TemplateOpener) {
       unsigned NewIndent;
       bool AvoidBinPacking;
@@ -695,7 +692,7 @@
 
     // If we encounter a closing ), ], } or >, we can remove a level from our
     // stacks.
-    if (Current.is(tok::r_paren) || Current.is(tok::r_square) ||
+    if (Current.isOneOf(tok::r_paren, tok::r_square) ||
         (Current.is(tok::r_brace) && State.NextToken != &RootToken) ||
         State.NextToken->Type == TT_TemplateCloser) {
       State.Stack.pop_back();
@@ -985,8 +982,7 @@
     if (State.NextToken->Parent->is(tok::semi) &&
         State.LineContainsContinuedForLoopSection)
       return true;
-    if ((State.NextToken->Parent->is(tok::comma) ||
-         State.NextToken->Parent->is(tok::semi) ||
+    if ((State.NextToken->Parent->isOneOf(tok::comma, tok::semi) ||
          State.NextToken->is(tok::question) ||
          State.NextToken->Type == TT_ConditionalExpr) &&
         State.Stack.back().BreakBeforeParameter &&
@@ -1126,6 +1122,88 @@
 
   virtual ~Formatter() {}
 
+  tooling::Replacements format() {
+    LexerBasedFormatTokenSource Tokens(Lex, SourceMgr);
+    UnwrappedLineParser Parser(Diag, Style, Tokens, *this);
+    StructuralError = Parser.parse();
+    unsigned PreviousEndOfLineColumn = 0;
+    TokenAnnotator Annotator(Style, SourceMgr, Lex,
+                             Tokens.getIdentTable().get("in"));
+    for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
+      Annotator.annotate(AnnotatedLines[i]);
+    }
+    deriveLocalStyle();
+    for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
+      Annotator.calculateFormattingInformation(AnnotatedLines[i]);
+    }
+    std::vector<int> IndentForLevel;
+    bool PreviousLineWasTouched = false;
+    for (std::vector<AnnotatedLine>::iterator I = AnnotatedLines.begin(),
+                                              E = AnnotatedLines.end();
+         I != E; ++I) {
+      const AnnotatedLine &TheLine = *I;
+      const FormatToken &FirstTok = TheLine.First.FormatTok;
+      int Offset = getIndentOffset(TheLine.First);
+      while (IndentForLevel.size() <= TheLine.Level)
+        IndentForLevel.push_back(-1);
+      IndentForLevel.resize(TheLine.Level + 1);
+      bool WasMoved =
+          PreviousLineWasTouched && FirstTok.NewlinesBefore == 0;
+      if (TheLine.First.is(tok::eof)) {
+        if (PreviousLineWasTouched) {
+          unsigned NewLines = std::min(FirstTok.NewlinesBefore, 1u);
+          Whitespaces.replaceWhitespace(TheLine.First, NewLines, /*Indent*/ 0,
+                                        /*WhitespaceStartColumn*/ 0, Style);
+        }
+      } else if (TheLine.Type != LT_Invalid &&
+                 (WasMoved || touchesLine(TheLine))) {
+        unsigned LevelIndent = getIndent(IndentForLevel, TheLine.Level);
+        unsigned Indent = LevelIndent;
+        if (static_cast<int>(Indent) + Offset >= 0)
+          Indent += Offset;
+        if (!FirstTok.WhiteSpaceStart.isValid() || StructuralError) {
+          Indent = LevelIndent = SourceMgr.getSpellingColumnNumber(
+              FirstTok.Tok.getLocation()) - 1;
+        } else {
+          formatFirstToken(TheLine.First, Indent, TheLine.InPPDirective,
+                           PreviousEndOfLineColumn);
+        }
+        tryFitMultipleLinesInOne(Indent, I, E);
+        UnwrappedLineFormatter Formatter(Style, SourceMgr, TheLine, Indent,
+                                         TheLine.First, Whitespaces,
+                                         StructuralError);
+        PreviousEndOfLineColumn =
+            Formatter.format(I + 1 != E ? &*(I + 1) : NULL);
+        IndentForLevel[TheLine.Level] = LevelIndent;
+        PreviousLineWasTouched = true;
+      } else {
+        if (FirstTok.NewlinesBefore > 0 || FirstTok.IsFirst) {
+          unsigned Indent =
+              SourceMgr.getSpellingColumnNumber(FirstTok.Tok.getLocation()) - 1;
+          unsigned LevelIndent = Indent;
+          if (static_cast<int>(LevelIndent) - Offset >= 0)
+            LevelIndent -= Offset;
+          IndentForLevel[TheLine.Level] = LevelIndent;
+
+          // Remove trailing whitespace of the previous line if it was touched.
+          if (PreviousLineWasTouched || touchesEmptyLineBefore(TheLine))
+            formatFirstToken(TheLine.First, Indent, TheLine.InPPDirective,
+                             PreviousEndOfLineColumn);
+        }
+        // If we did not reformat this unwrapped line, the column at the end of
+        // the last token is unchanged - thus, we can calculate the end of the
+        // last token.
+        SourceLocation LastLoc = TheLine.Last->FormatTok.Tok.getLocation();
+        PreviousEndOfLineColumn =
+            SourceMgr.getSpellingColumnNumber(LastLoc) +
+            Lex.MeasureTokenLength(LastLoc, SourceMgr, Lex.getLangOpts()) - 1;
+        PreviousLineWasTouched = false;
+      }
+    }
+    return Whitespaces.generateReplacements();
+  }
+
+private:
   void deriveLocalStyle() {
     unsigned CountBoundToVariable = 0;
     unsigned CountBoundToType = 0;
@@ -1163,91 +1241,6 @@
     }
   }
 
-  tooling::Replacements format() {
-    LexerBasedFormatTokenSource Tokens(Lex, SourceMgr);
-    UnwrappedLineParser Parser(Diag, Style, Tokens, *this);
-    StructuralError = Parser.parse();
-    unsigned PreviousEndOfLineColumn = 0;
-    TokenAnnotator Annotator(Style, SourceMgr, Lex,
-                             Tokens.getIdentTable().get("in"));
-    for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
-      Annotator.annotate(AnnotatedLines[i]);
-    }
-    deriveLocalStyle();
-    for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
-      Annotator.calculateFormattingInformation(AnnotatedLines[i]);
-    }
-    std::vector<int> IndentForLevel;
-    bool PreviousLineWasTouched = false;
-    for (std::vector<AnnotatedLine>::iterator I = AnnotatedLines.begin(),
-                                              E = AnnotatedLines.end();
-         I != E; ++I) {
-      const AnnotatedLine &TheLine = *I;
-      int Offset = getIndentOffset(TheLine.First);
-      while (IndentForLevel.size() <= TheLine.Level)
-        IndentForLevel.push_back(-1);
-      IndentForLevel.resize(TheLine.Level + 1);
-      bool WasMoved =
-          PreviousLineWasTouched && TheLine.First.FormatTok.NewlinesBefore == 0;
-      if (TheLine.First.is(tok::eof)) {
-        if (PreviousLineWasTouched) {
-          unsigned NewLines =
-              std::min(TheLine.First.FormatTok.NewlinesBefore, 1u);
-          Whitespaces.replaceWhitespace(TheLine.First, NewLines, /*Indent*/ 0,
-                                        /*WhitespaceStartColumn*/ 0, Style);
-        }
-      } else if (TheLine.Type != LT_Invalid &&
-                 (WasMoved || touchesLine(TheLine))) {
-        unsigned LevelIndent = getIndent(IndentForLevel, TheLine.Level);
-        unsigned Indent = LevelIndent;
-        if (static_cast<int>(Indent) + Offset >= 0)
-          Indent += Offset;
-        if (!TheLine.First.FormatTok.WhiteSpaceStart.isValid() ||
-            StructuralError) {
-          Indent = LevelIndent = SourceMgr.getSpellingColumnNumber(
-              TheLine.First.FormatTok.Tok.getLocation()) - 1;
-        } else {
-          formatFirstToken(TheLine.First, Indent, TheLine.InPPDirective,
-                           PreviousEndOfLineColumn);
-        }
-        tryFitMultipleLinesInOne(Indent, I, E);
-        UnwrappedLineFormatter Formatter(Style, SourceMgr, TheLine, Indent,
-                                         TheLine.First, Whitespaces,
-                                         StructuralError);
-        PreviousEndOfLineColumn =
-            Formatter.format(I + 1 != E ? &*(I + 1) : NULL);
-        IndentForLevel[TheLine.Level] = LevelIndent;
-        PreviousLineWasTouched = true;
-      } else {
-        if (TheLine.First.FormatTok.NewlinesBefore > 0 ||
-            TheLine.First.FormatTok.IsFirst) {
-          unsigned Indent = SourceMgr.getSpellingColumnNumber(
-              TheLine.First.FormatTok.Tok.getLocation()) - 1;
-          unsigned LevelIndent = Indent;
-          if (static_cast<int>(LevelIndent) - Offset >= 0)
-            LevelIndent -= Offset;
-          IndentForLevel[TheLine.Level] = LevelIndent;
-
-          // Remove trailing whitespace of the previous line if it was touched.
-          if (PreviousLineWasTouched || touchesEmptyLineBefore(TheLine))
-            formatFirstToken(TheLine.First, Indent, TheLine.InPPDirective,
-                             PreviousEndOfLineColumn);
-        }
-        // If we did not reformat this unwrapped line, the column at the end of
-        // the last token is unchanged - thus, we can calculate the end of the
-        // last token.
-        PreviousEndOfLineColumn =
-            SourceMgr.getSpellingColumnNumber(
-                TheLine.Last->FormatTok.Tok.getLocation()) +
-            Lex.MeasureTokenLength(TheLine.Last->FormatTok.Tok.getLocation(),
-                                   SourceMgr, Lex.getLangOpts()) - 1;
-        PreviousLineWasTouched = false;
-      }
-    }
-    return Whitespaces.generateReplacements();
-  }
-
-private:
   /// \brief Get the indent of \p Level from \p IndentForLevel.
   ///
   /// \p IndentForLevel must contain the indent for the level \c l
@@ -1267,8 +1260,7 @@
   /// characters to the left from their level.
   int getIndentOffset(const AnnotatedToken &RootToken) {
     bool IsAccessModifier = false;
-    if (RootToken.is(tok::kw_public) || RootToken.is(tok::kw_protected) ||
-        RootToken.is(tok::kw_private))
+    if (RootToken.isOneOf(tok::kw_public, tok::kw_protected, tok::kw_private))
       IsAccessModifier = true;
     else if (RootToken.is(tok::at) && !RootToken.Children.empty() &&
              (RootToken.Children[0].isObjCAtKeyword(tok::objc_public) ||
@@ -1361,15 +1353,11 @@
     // we're not in a control flow statement and the last token is an opening
     // brace.
     AnnotatedLine &Line = *I;
-    bool AllowedTokens =
-        Line.First.isNot(tok::kw_if) && Line.First.isNot(tok::kw_while) &&
-        Line.First.isNot(tok::kw_do) && Line.First.isNot(tok::r_brace) &&
-        Line.First.isNot(tok::kw_else) && Line.First.isNot(tok::kw_try) &&
-        Line.First.isNot(tok::kw_catch) && Line.First.isNot(tok::kw_for) &&
-        // This gets rid of all ObjC @ keywords and methods.
-        Line.First.isNot(tok::at) && Line.First.isNot(tok::minus) &&
-        Line.First.isNot(tok::plus);
-    if (!AllowedTokens)
+    if (Line.First.isOneOf(tok::kw_if, tok::kw_while, tok::kw_do, tok::r_brace,
+                           tok::kw_else, tok::kw_try, tok::kw_catch,
+                           tok::kw_for,
+                           // This gets rid of all ObjC @ keywords and methods.
+                           tok::at, tok::minus, tok::plus))
       return;
 
     AnnotatedToken *Tok = &(I + 1)->First;
@@ -1391,7 +1379,7 @@
       if ((I + 1)->Last->Type == TT_LineComment || Tok->MustBreakBefore)
         return;
       do {
-        if (Tok->is(tok::l_brace) || Tok->is(tok::r_brace))
+        if (Tok->isOneOf(tok::l_brace, tok::r_brace))
           return;
         Tok = Tok->Children.empty() ? NULL : &Tok->Children.back();
       } while (Tok != NULL);
diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp
index 72edc76..ac12716 100644
--- a/lib/Format/TokenAnnotator.cpp
+++ b/lib/Format/TokenAnnotator.cpp
@@ -71,6 +71,16 @@
   return NextToken;
 }
 
+static bool closesScope(const AnnotatedToken &Tok) {
+  return Tok.isOneOf(tok::r_paren, tok::r_brace, tok::r_square) ||
+         Tok.Type == TT_TemplateCloser;
+}
+
+static bool opensScope(const AnnotatedToken &Tok) {
+  return Tok.isOneOf(tok::l_paren, tok::l_brace, tok::l_square) ||
+         Tok.Type == TT_TemplateOpener;
+}
+
 /// \brief A parser that gathers additional information about tokens.
 ///
 /// The \c TokenAnnotator tries to match parenthesis and square brakets and
@@ -100,11 +110,9 @@
         next();
         return true;
       }
-      if (CurrentToken->is(tok::r_paren) || CurrentToken->is(tok::r_square) ||
-          CurrentToken->is(tok::r_brace))
-        return false;
-      if (CurrentToken->is(tok::pipepipe) || CurrentToken->is(tok::ampamp) ||
-          CurrentToken->is(tok::question) || CurrentToken->is(tok::colon))
+      if (CurrentToken->isOneOf(tok::r_paren, tok::r_square, tok::r_brace,
+                                tok::pipepipe, tok::ampamp, tok::question,
+                                tok::colon))
         return false;
       updateParameterCount(Left, CurrentToken);
       if (!consumeToken())
@@ -149,7 +157,7 @@
         AnnotatedToken &Prev = *CurrentToken->Parent;
         AnnotatedToken &Next = CurrentToken->Children[0];
         if (Prev.Parent->is(tok::identifier) &&
-            (Prev.is(tok::star) || Prev.is(tok::amp) || Prev.is(tok::ampamp)) &&
+            Prev.isOneOf(tok::star, tok::amp, tok::ampamp) &&
             CurrentToken->is(tok::identifier) && Next.isNot(tok::equal)) {
           Prev.Type = TT_BinaryOperator;
           LookForDecls = false;
@@ -171,7 +179,7 @@
         next();
         return true;
       }
-      if (CurrentToken->is(tok::r_square) || CurrentToken->is(tok::r_brace))
+      if (CurrentToken->isOneOf(tok::r_square, tok::r_brace))
         return false;
       updateParameterCount(Left, CurrentToken);
       if (!consumeToken())
@@ -191,10 +199,10 @@
     AnnotatedToken *Parent = getPreviousToken(*Left);
     bool StartsObjCMethodExpr =
         Contexts.back().CanBeExpression &&
-        (!Parent || Parent->is(tok::colon) || Parent->is(tok::l_square) ||
-         Parent->is(tok::l_paren) || Parent->is(tok::kw_return) ||
-         Parent->is(tok::kw_throw) || isUnaryOperator(*Parent) ||
-         Parent->Type == TT_ObjCForIn || Parent->Type == TT_CastRParen ||
+        (!Parent || Parent->isOneOf(tok::colon, tok::l_square, tok::l_paren,
+                                    tok::kw_return, tok::kw_throw) ||
+         isUnaryOperator(*Parent) || Parent->Type == TT_ObjCForIn ||
+         Parent->Type == TT_CastRParen ||
          getBinOpPrecedence(Parent->FormatTok.Tok.getKind(), true, true) >
          prec::Unknown);
     ScopedContextCreator ContextCreator(*this, 10);
@@ -235,7 +243,7 @@
         next();
         return true;
       }
-      if (CurrentToken->is(tok::r_paren) || CurrentToken->is(tok::r_brace))
+      if (CurrentToken->isOneOf(tok::r_paren, tok::r_brace))
         return false;
       updateParameterCount(Left, CurrentToken);
       if (!consumeToken())
@@ -257,7 +265,7 @@
         next();
         return true;
       }
-      if (CurrentToken->is(tok::r_paren) || CurrentToken->is(tok::r_square))
+      if (CurrentToken->isOneOf(tok::r_paren, tok::r_square))
         return false;
       updateParameterCount(Left, CurrentToken);
       if (!consumeToken())
@@ -380,7 +388,7 @@
       break;
     case tok::kw_operator:
       while (CurrentToken && CurrentToken->isNot(tok::l_paren)) {
-        if (CurrentToken->is(tok::star) || CurrentToken->is(tok::amp))
+        if (CurrentToken->isOneOf(tok::star, tok::amp))
           CurrentToken->Type = TT_PointerOrReference;
         consumeToken();
       }
@@ -472,7 +480,7 @@
     while (CurrentToken != NULL) {
       if (CurrentToken->is(tok::kw_virtual))
         KeywordVirtualFound = true;
-      if (CurrentToken->is(tok::period) || CurrentToken->is(tok::arrow)) {
+      if (CurrentToken->isOneOf(tok::period, tok::arrow)) {
         ++PeriodsAndArrows;
         LastPeriodOrArrow = CurrentToken;
       }
@@ -560,18 +568,17 @@
         if (Previous->is(tok::r_square))
           Previous = Previous->MatchingParen;
         if (Previous->Type == TT_BinaryOperator &&
-            (Previous->is(tok::star) || Previous->is(tok::amp))) {
+            Previous->isOneOf(tok::star, tok::amp)) {
           Previous->Type = TT_PointerOrReference;
         }
       }
-    } else if (Current.is(tok::kw_return) || Current.is(tok::kw_throw) ||
+    } else if (Current.isOneOf(tok::kw_return, tok::kw_throw) ||
                (Current.is(tok::l_paren) && !Line.MustBeDeclaration &&
                 (!Current.Parent || Current.Parent->isNot(tok::kw_for)))) {
       Contexts.back().IsExpression = true;
-    } else if (Current.is(tok::r_paren) || Current.is(tok::greater) ||
-               Current.is(tok::comma)) {
+    } else if (Current.isOneOf(tok::r_paren, tok::greater, tok::comma)) {
       for (AnnotatedToken *Previous = Current.Parent;
-           Previous && (Previous->is(tok::star) || Previous->is(tok::amp));
+           Previous && Previous->isOneOf(tok::star, tok::amp);
            Previous = Previous->Parent)
         Previous->Type = TT_PointerOrReference;
     } else if (Current.Parent &&
@@ -589,14 +596,12 @@
            Current.Parent->Type == TT_PointerOrReference ||
            Current.Parent->Type == TT_TemplateCloser)) {
         Current.Type = TT_StartOfName;
-      } else if (Current.is(tok::star) || Current.is(tok::amp) ||
-                 Current.is(tok::ampamp)) {
+      } else if (Current.isOneOf(tok::star, tok::amp, tok::ampamp)) {
         Current.Type =
             determineStarAmpUsage(Current, Contexts.back().IsExpression);
-      } else if (Current.is(tok::minus) || Current.is(tok::plus) ||
-                 Current.is(tok::caret)) {
+      } else if (Current.isOneOf(tok::minus, tok::plus, tok::caret)) {
         Current.Type = determinePlusMinusCaretUsage(Current);
-      } else if (Current.is(tok::minusminus) || Current.is(tok::plusplus)) {
+      } else if (Current.isOneOf(tok::minusminus, tok::plusplus)) {
         Current.Type = determineIncrementUsage(Current);
       } else if (Current.is(tok::exclaim)) {
         Current.Type = TT_UnaryOperator;
@@ -614,9 +619,8 @@
                              Current.Parent->Type == TT_PointerOrReference ||
                              Current.Parent->Type == TT_TemplateCloser;
         bool ParensCouldEndDecl =
-            !Current.Children.empty() && (Current.Children[0].is(tok::equal) ||
-                                          Current.Children[0].is(tok::semi) ||
-                                          Current.Children[0].is(tok::l_brace));
+            !Current.Children.empty() &&
+            Current.Children[0].isOneOf(tok::equal, tok::semi, tok::l_brace);
         if (ParensNotExpr && !ParensCouldEndDecl &&
             Contexts.back().IsExpression)
           // FIXME: We need to get smarter and understand more cases of casts.
@@ -652,20 +656,20 @@
     if (PrevToken->is(tok::l_paren) && !IsExpression)
       return TT_PointerOrReference;
 
-    if (PrevToken->is(tok::l_paren) || PrevToken->is(tok::l_square) ||
-        PrevToken->is(tok::l_brace) || PrevToken->is(tok::comma) ||
-        PrevToken->is(tok::kw_return) || PrevToken->is(tok::colon) ||
-        PrevToken->is(tok::equal) || PrevToken->Type == TT_BinaryOperator ||
+    if (PrevToken->isOneOf(tok::l_paren, tok::l_square, tok::l_brace,
+                           tok::comma, tok::kw_return, tok::colon,
+                           tok::equal) ||
+        PrevToken->Type == TT_BinaryOperator ||
         PrevToken->Type == TT_UnaryOperator || PrevToken->Type == TT_CastRParen)
       return TT_UnaryOperator;
 
     if (NextToken->is(tok::l_square))
       return TT_PointerOrReference;
 
-    if (PrevToken->FormatTok.Tok.isLiteral() || PrevToken->is(tok::r_paren) ||
-        PrevToken->is(tok::r_square) || NextToken->FormatTok.Tok.isLiteral() ||
-        isUnaryOperator(*NextToken) || NextToken->is(tok::l_paren) ||
-        NextToken->is(tok::l_square))
+    if (PrevToken->FormatTok.Tok.isLiteral() ||
+        PrevToken->isOneOf(tok::r_paren, tok::r_square) ||
+        NextToken->FormatTok.Tok.isLiteral() || isUnaryOperator(*NextToken) ||
+        NextToken->isOneOf(tok::l_paren, tok::l_square))
       return TT_BinaryOperator;
 
     // It is very unlikely that we are going to find a pointer or reference type
@@ -682,11 +686,9 @@
       return TT_UnaryOperator;
 
     // Use heuristics to recognize unary operators.
-    if (PrevToken->is(tok::equal) || PrevToken->is(tok::l_paren) ||
-        PrevToken->is(tok::comma) || PrevToken->is(tok::l_square) ||
-        PrevToken->is(tok::question) || PrevToken->is(tok::colon) ||
-        PrevToken->is(tok::kw_return) || PrevToken->is(tok::kw_case) ||
-        PrevToken->is(tok::at) || PrevToken->is(tok::l_brace))
+    if (PrevToken->isOneOf(tok::equal, tok::l_paren, tok::comma, tok::l_square,
+                           tok::question, tok::colon, tok::kw_return,
+                           tok::kw_case, tok::at, tok::l_brace))
       return TT_UnaryOperator;
 
     // There can't be two consecutive binary operators.
@@ -702,8 +704,7 @@
     const AnnotatedToken *PrevToken = getPreviousToken(Tok);
     if (PrevToken == NULL)
       return TT_UnaryOperator;
-    if (PrevToken->is(tok::r_paren) || PrevToken->is(tok::r_square) ||
-        PrevToken->is(tok::identifier))
+    if (PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::identifier))
       return TT_TrailingUnaryOperator;
 
     return TT_UnaryOperator;
@@ -798,16 +799,6 @@
       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;
 };
 
@@ -901,11 +892,11 @@
       Left.Type == TT_InheritanceColon)
     return 2;
 
-  if (Right.is(tok::arrow) || Right.is(tok::period)) {
+  if (Right.isOneOf(tok::arrow, tok::period)) {
     if (Line.Type == LT_BuilderTypeCall)
       return 5;
-    if ((Left.is(tok::r_paren) || Left.is(tok::r_square)) &&
-        Left.MatchingParen && Left.MatchingParen->ParameterCount > 0)
+    if (Left.isOneOf(tok::r_paren, tok::r_square) && Left.MatchingParen &&
+        Left.MatchingParen->ParameterCount > 0)
       return 20; // Should be smaller than breaking at a nested comma.
     return 150;
   }
@@ -926,8 +917,7 @@
   if (Left.is(tok::colon) && Left.Type == TT_ObjCMethodExpr)
     return 20;
 
-  if (Left.is(tok::l_paren) || Left.is(tok::l_square) ||
-      Left.is(tok::l_brace) || Left.Type == TT_TemplateOpener)
+  if (opensScope(Left))
     return 20;
 
   if (Right.is(tok::lessless)) {
@@ -955,9 +945,9 @@
                                           const AnnotatedToken &Right) {
   if (Right.is(tok::hashhash))
     return Left.is(tok::hash);
-  if (Left.is(tok::hashhash) || Left.is(tok::hash))
+  if (Left.isOneOf(tok::hashhash, tok::hash))
     return Right.is(tok::hash);
-  if (Right.is(tok::r_paren) || Right.is(tok::semi) || Right.is(tok::comma))
+  if (Right.isOneOf(tok::r_paren, tok::semi, tok::comma))
     return false;
   if (Right.is(tok::less) &&
       (Left.is(tok::kw_template) ||
@@ -965,20 +955,18 @@
     return true;
   if (Left.is(tok::arrow) || Right.is(tok::arrow))
     return false;
-  if (Left.is(tok::exclaim) || Left.is(tok::tilde))
+  if (Left.isOneOf(tok::exclaim, tok::tilde))
     return false;
   if (Left.is(tok::at) &&
-      (Right.is(tok::identifier) || Right.is(tok::string_literal) ||
-       Right.is(tok::char_constant) || Right.is(tok::numeric_constant) ||
-       Right.is(tok::l_paren) || Right.is(tok::l_brace) ||
-       Right.is(tok::kw_true) || Right.is(tok::kw_false)))
+      Right.isOneOf(tok::identifier, tok::string_literal, tok::char_constant,
+                    tok::numeric_constant, tok::l_paren, tok::l_brace,
+                    tok::kw_true, tok::kw_false))
     return false;
   if (Left.is(tok::coloncolon))
     return false;
   if (Right.is(tok::coloncolon))
-    return Left.isNot(tok::identifier) && Left.isNot(tok::greater) &&
-           Left.isNot(tok::l_paren);
-  if (Left.is(tok::less) || Right.is(tok::greater) || Right.is(tok::less))
+    return !Left.isOneOf(tok::identifier, tok::greater, tok::l_paren);
+  if (Left.is(tok::less) || Right.isOneOf(tok::greater, tok::less))
     return false;
   if (Right.Type == TT_PointerOrReference)
     return Left.FormatTok.Tok.isLiteral() ||
@@ -1004,11 +992,10 @@
   if (Left.is(tok::l_paren))
     return false;
   if (Right.is(tok::l_paren)) {
-    return Line.Type == LT_ObjCDecl || Left.is(tok::kw_if) ||
-           Left.is(tok::kw_for) || Left.is(tok::kw_while) ||
-           Left.is(tok::kw_switch) || Left.is(tok::kw_return) ||
-           Left.is(tok::kw_catch) || Left.is(tok::kw_new) ||
-           Left.is(tok::kw_delete);
+    return Line.Type == LT_ObjCDecl ||
+           Left.isOneOf(tok::kw_if, tok::kw_for, tok::kw_while, tok::kw_switch,
+                        tok::kw_return, tok::kw_catch, tok::kw_new,
+                        tok::kw_delete);
   }
   if (Left.is(tok::at) &&
       Right.FormatTok.Tok.getObjCKeywordID() != tok::objc_not_keyword)
@@ -1045,9 +1032,8 @@
   if (Tok.Type == TT_OverloadedOperatorLParen)
     return false;
   if (Tok.is(tok::colon))
-    return Line.First.isNot(tok::kw_case) &&
-           Line.First.isNot(tok::kw_default) && !Tok.Children.empty() &&
-           Tok.Type != TT_ObjCMethodExpr;
+    return !Line.First.isOneOf(tok::kw_case, tok::kw_default) &&
+           !Tok.Children.empty() && Tok.Type != TT_ObjCMethodExpr;
   if (Tok.is(tok::l_paren) && !Tok.Children.empty() &&
       Tok.Children[0].Type == TT_PointerOrReference &&
       !Tok.Children[0].Children.empty() &&
@@ -1056,8 +1042,7 @@
   if (Tok.Parent->Type == TT_UnaryOperator || Tok.Parent->Type == TT_CastRParen)
     return false;
   if (Tok.Type == TT_UnaryOperator)
-    return Tok.Parent->isNot(tok::l_paren) &&
-           Tok.Parent->isNot(tok::l_square) && Tok.Parent->isNot(tok::at) &&
+    return !Tok.Parent->isOneOf(tok::l_paren, tok::l_square, tok::at) &&
            (Tok.Parent->isNot(tok::colon) ||
             Tok.Parent->Type != TT_ObjCMethodExpr);
   if (Tok.Parent->is(tok::greater) && Tok.is(tok::greater)) {
@@ -1103,7 +1088,7 @@
     return false;
   if (Left.Type == TT_PointerOrReference || Left.Type == TT_TemplateCloser ||
       Left.Type == TT_UnaryOperator || Left.Type == TT_ConditionalExpr ||
-      Left.is(tok::question) || Left.is(tok::kw_operator))
+      Left.isOneOf(tok::question, tok::kw_operator))
     return false;
   if (Left.is(tok::equal) && Line.Type == LT_VirtualFunctionDecl)
     return false;
@@ -1120,25 +1105,22 @@
   // unless it is follow by ';', '{' or '='.
   if (Left.is(tok::kw_const) && Left.Parent != NULL &&
       Left.Parent->is(tok::r_paren))
-    return Right.isNot(tok::l_brace) && Right.isNot(tok::semi) &&
-           Right.isNot(tok::equal);
+    return !Right.isOneOf(tok::l_brace, tok::semi, tok::equal);
 
   // We only break before r_brace if there was a corresponding break before
   // the l_brace, which is tracked by BreakBeforeClosingBrace.
   if (Right.is(tok::r_brace))
     return false;
 
-  if (Right.is(tok::r_paren) || Right.is(tok::greater))
+  if (Right.isOneOf(tok::r_paren, tok::greater))
     return false;
   if (Left.is(tok::identifier) && Right.is(tok::string_literal))
     return true;
   return (isBinaryOperator(Left) && Left.isNot(tok::lessless)) ||
-         Left.is(tok::comma) || Right.is(tok::lessless) ||
-         Right.is(tok::arrow) || Right.is(tok::period) ||
-         Right.is(tok::colon) || Left.is(tok::coloncolon) ||
-         Left.is(tok::semi) || Left.is(tok::l_brace) ||
+         Left.isOneOf(tok::comma, tok::coloncolon, tok::semi, tok::l_brace) ||
+         Right.isOneOf(tok::lessless, tok::arrow, tok::period, tok::colon) ||
          (Left.is(tok::r_paren) && Left.Type != TT_CastRParen &&
-          (Right.is(tok::identifier) || Right.is(tok::kw___attribute))) ||
+          Right.isOneOf(tok::identifier, tok::kw___attribute)) ||
          (Left.is(tok::l_paren) && !Right.is(tok::r_paren)) ||
          (Left.is(tok::l_square) && !Right.is(tok::r_square));
 }
diff --git a/lib/Format/TokenAnnotator.h b/lib/Format/TokenAnnotator.h
index b79ee97..2b93836 100644
--- a/lib/Format/TokenAnnotator.h
+++ b/lib/Format/TokenAnnotator.h
@@ -79,6 +79,27 @@
   }
 
   bool is(tok::TokenKind Kind) const { return FormatTok.Tok.is(Kind); }
+
+  bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const {
+    return is(K1) || is(K2);
+  }
+
+  bool isOneOf(tok::TokenKind K1, tok::TokenKind K2, tok::TokenKind K3) const {
+    return is(K1) || is(K2) || is(K3);
+  }
+
+  bool isOneOf(
+      tok::TokenKind K1, tok::TokenKind K2, tok::TokenKind K3,
+      tok::TokenKind K4, tok::TokenKind K5 = tok::NUM_TOKENS,
+      tok::TokenKind K6 = tok::NUM_TOKENS, tok::TokenKind K7 = tok::NUM_TOKENS,
+      tok::TokenKind K8 = tok::NUM_TOKENS, tok::TokenKind K9 = tok::NUM_TOKENS,
+      tok::TokenKind K10 = tok::NUM_TOKENS,
+      tok::TokenKind K11 = tok::NUM_TOKENS,
+      tok::TokenKind K12 = tok::NUM_TOKENS) const {
+    return is(K1) || is(K2) || is(K3) || is(K4) || is(K5) || is(K6) || is(K7) ||
+           is(K8) || is(K9) || is(K10) || is(K11) || is(K12);
+  }
+
   bool isNot(tok::TokenKind Kind) const { return FormatTok.Tok.isNot(Kind); }
 
   bool isObjCAtKeyword(tok::ObjCKeywordKind Kind) const {