TokenAnnotator.cpp revision 561211d35b5a2825fba6d0c017044f6896b204fd
132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper//===--- TokenAnnotator.cpp - Format C++ code -----------------------------===//
232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper//
332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper//                     The LLVM Compiler Infrastructure
432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper//
532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper// This file is distributed under the University of Illinois Open Source
632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper// License. See LICENSE.TXT for details.
732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper//
832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper//===----------------------------------------------------------------------===//
932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper///
1032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper/// \file
1132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper/// \brief This file implements a token annotator, i.e. creates
1232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper/// \c AnnotatedTokens out of \c FormatTokens with required extra information.
1332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper///
1432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper//===----------------------------------------------------------------------===//
1532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
1632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper#include "TokenAnnotator.h"
1732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper#include "clang/Basic/SourceManager.h"
18bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper#include "llvm/Support/Debug.h"
1932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
2032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jaspernamespace clang {
2132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jaspernamespace format {
2232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
2314e66498781b7d81639bdc48716e09700552ac21Craig Toppernamespace {
2414e66498781b7d81639bdc48716e09700552ac21Craig Topper
2532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper/// \brief A parser that gathers additional information about tokens.
2632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper///
273fd9ccdd9f8d259bcf518e7056cfd419d992e984Alexander Kornienko/// The \c TokenAnnotator tries to match parenthesis and square brakets and
2832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper/// store a parenthesis levels. It also tries to resolve matching "<" and ">"
2932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper/// into template parameter lists.
3032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasperclass AnnotatingParser {
3132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasperpublic:
3200895106f9ed602af67984ec4d225a0cdc8c12afAlexander Kornienko  AnnotatingParser(AnnotatedLine &Line, IdentifierInfo &Ident_in)
3300895106f9ed602af67984ec4d225a0cdc8c12afAlexander Kornienko      : Line(Line), CurrentToken(Line.First), KeywordVirtualFound(false),
342ca3741a962ded08866596577aaee2f4ab74c955Daniel Jasper        NameFound(false), AutoFound(false), Ident_in(Ident_in) {
352726877196b41b922f10f794801b313980e1a8adNico Weber    Contexts.push_back(Context(tok::unknown, 1, /*IsExpression=*/false));
3632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  }
3732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
3895e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weberprivate:
3932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  bool parseAngle() {
4032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    if (CurrentToken == NULL)
4132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      return false;
42923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper    ScopedContextCreator ContextCreator(*this, tok::less, 10);
43b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek    FormatToken *Left = CurrentToken->Previous;
444e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper    Contexts.back().IsExpression = false;
4532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    while (CurrentToken != NULL) {
4632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      if (CurrentToken->is(tok::greater)) {
4732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        Left->MatchingParen = CurrentToken;
4832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        CurrentToken->MatchingParen = Left;
4932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        CurrentToken->Type = TT_TemplateCloser;
5032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        next();
5132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        return true;
5232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      }
53e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko      if (CurrentToken->isOneOf(tok::r_paren, tok::r_square, tok::r_brace,
545d823e3a00a3e21a0823288e6dee26a93758332bDaniel Jasper                                tok::question, tok::colon))
555d823e3a00a3e21a0823288e6dee26a93758332bDaniel Jasper        return false;
560348be0c78781c5ddb8c271976812705410c731aDaniel Jasper      // If a && or || is found and interpreted as a binary operator, this set
5715f33f03e742fb6567e4789996fa0391a8e18068Daniel Jasper      // of angles is likely part of something like "a < b && c > d". If the
580348be0c78781c5ddb8c271976812705410c731aDaniel Jasper      // angles are inside an expression, the ||/&& might also be a binary
590348be0c78781c5ddb8c271976812705410c731aDaniel Jasper      // operator that was misinterpreted because we are parsing template
600348be0c78781c5ddb8c271976812705410c731aDaniel Jasper      // parameters.
610348be0c78781c5ddb8c271976812705410c731aDaniel Jasper      // FIXME: This is getting out of hand, write a decent parser.
62b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek      if (CurrentToken->Previous->isOneOf(tok::pipepipe, tok::ampamp) &&
630348be0c78781c5ddb8c271976812705410c731aDaniel Jasper          (CurrentToken->Previous->Type == TT_BinaryOperator ||
640348be0c78781c5ddb8c271976812705410c731aDaniel Jasper           Contexts[Contexts.size() - 2].IsExpression) &&
65b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek          Line.First->isNot(tok::kw_template))
6632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        return false;
679fc56f2636137fcde8acb38865555ed6c7b84dfdDaniel Jasper      updateParameterCount(Left, CurrentToken);
6832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      if (!consumeToken())
6932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        return false;
7032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    }
7132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return false;
7232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  }
7332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
7432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  bool parseParens(bool LookForDecls = false) {
7532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    if (CurrentToken == NULL)
7632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      return false;
77923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper    ScopedContextCreator ContextCreator(*this, tok::l_paren, 1);
784e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper
794e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper    // FIXME: This is a bit of a hack. Do better.
804e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper    Contexts.back().ColonIsForRangeExpr =
814e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper        Contexts.size() == 2 && Contexts[0].ColonIsForRangeExpr;
824e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper
8332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    bool StartsObjCMethodExpr = false;
84b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek    FormatToken *Left = CurrentToken->Previous;
8532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    if (CurrentToken->is(tok::caret)) {
8632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      // ^( starts a block.
8732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      Left->Type = TT_ObjCBlockLParen;
88b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek    } else if (FormatToken *MaybeSel = Left->Previous) {
8932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      // @selector( starts a selector.
90b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek      if (MaybeSel->isObjCAtKeyword(tok::objc_selector) && MaybeSel->Previous &&
91b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek          MaybeSel->Previous->is(tok::at)) {
9232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        StartsObjCMethodExpr = true;
9332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      }
9432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    }
9532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
964e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper    if (StartsObjCMethodExpr) {
974e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper      Contexts.back().ColonIsObjCMethodExpr = true;
984e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper      Left->Type = TT_ObjCMethodExpr;
994e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper    }
10032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
101431f5918281dd1f178bf838b7a47ab1d11c52961Daniel Jasper    bool MightBeFunctionType = CurrentToken->is(tok::star);
102c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper    bool HasMultipleLines = false;
103c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper    bool HasMultipleParametersOnALine = false;
10432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    while (CurrentToken != NULL) {
10532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      // LookForDecls is set when "if (" has been seen. Check for
10632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      // 'identifier' '*' 'identifier' followed by not '=' -- this
10732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      // '*' has to be a binary operator but determineStarAmpUsage() will
10832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      // categorize it as an unary operator, so set the right type here.
109b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek      if (LookForDecls && CurrentToken->Next) {
1100bdc6434fa0fea933b6ab566eff751afdba40a2aAlexander Kornienko        FormatToken *Prev = CurrentToken->getPreviousNonComment();
1112785b9aabcb2c3fd6f7dd8b63d3cd3d4b9bca284Alexander Kornienko        if (Prev) {
1120bdc6434fa0fea933b6ab566eff751afdba40a2aAlexander Kornienko          FormatToken *PrevPrev = Prev->getPreviousNonComment();
1132785b9aabcb2c3fd6f7dd8b63d3cd3d4b9bca284Alexander Kornienko          FormatToken *Next = CurrentToken->Next;
1142785b9aabcb2c3fd6f7dd8b63d3cd3d4b9bca284Alexander Kornienko          if (PrevPrev && PrevPrev->is(tok::identifier) &&
1152785b9aabcb2c3fd6f7dd8b63d3cd3d4b9bca284Alexander Kornienko              Prev->isOneOf(tok::star, tok::amp, tok::ampamp) &&
1162785b9aabcb2c3fd6f7dd8b63d3cd3d4b9bca284Alexander Kornienko              CurrentToken->is(tok::identifier) && Next->isNot(tok::equal)) {
1172785b9aabcb2c3fd6f7dd8b63d3cd3d4b9bca284Alexander Kornienko            Prev->Type = TT_BinaryOperator;
1182785b9aabcb2c3fd6f7dd8b63d3cd3d4b9bca284Alexander Kornienko            LookForDecls = false;
1192785b9aabcb2c3fd6f7dd8b63d3cd3d4b9bca284Alexander Kornienko          }
12032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        }
12132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      }
12232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
12332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      if (CurrentToken->is(tok::r_paren)) {
124b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek        if (MightBeFunctionType && CurrentToken->Next &&
125e7d3bff31e3ef4fea1e2a5a7cd5441b6b0752e3fDaniel Jasper            (CurrentToken->Next->is(tok::l_paren) ||
126e7d3bff31e3ef4fea1e2a5a7cd5441b6b0752e3fDaniel Jasper             (CurrentToken->Next->is(tok::l_square) &&
127e7d3bff31e3ef4fea1e2a5a7cd5441b6b0752e3fDaniel Jasper              !Contexts.back().IsExpression)))
128431f5918281dd1f178bf838b7a47ab1d11c52961Daniel Jasper          Left->Type = TT_FunctionTypeLParen;
12932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        Left->MatchingParen = CurrentToken;
13032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        CurrentToken->MatchingParen = Left;
13132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
13263d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper        if (StartsObjCMethodExpr) {
1334e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper          CurrentToken->Type = TT_ObjCMethodExpr;
1344e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper          if (Contexts.back().FirstObjCSelectorName != NULL) {
1354e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper            Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
1364e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper                Contexts.back().LongestObjCSelectorName;
13763d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper          }
13863d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper        }
13932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
140c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper        if (!HasMultipleLines)
141c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper          Left->PackingKind = PPK_Inconclusive;
142c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper        else if (HasMultipleParametersOnALine)
143c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper          Left->PackingKind = PPK_BinPacked;
144c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper        else
145c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper          Left->PackingKind = PPK_OnePerLine;
146c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper
14732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        next();
14832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        return true;
14932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      }
150e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko      if (CurrentToken->isOneOf(tok::r_square, tok::r_brace))
15132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        return false;
152b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek      if (CurrentToken->Previous->Type == TT_PointerOrReference &&
153b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek          CurrentToken->Previous->Previous->isOneOf(tok::l_paren,
154b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek                                                    tok::coloncolon))
155431f5918281dd1f178bf838b7a47ab1d11c52961Daniel Jasper        MightBeFunctionType = true;
1569fc56f2636137fcde8acb38865555ed6c7b84dfdDaniel Jasper      updateParameterCount(Left, CurrentToken);
157c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper      if (CurrentToken->is(tok::comma) && CurrentToken->Next &&
158c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper          !CurrentToken->Next->HasUnescapedNewline &&
159c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper          !CurrentToken->Next->isTrailingComment())
160c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper        HasMultipleParametersOnALine = true;
16132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      if (!consumeToken())
16232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        return false;
163c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper      if (CurrentToken && CurrentToken->HasUnescapedNewline)
164c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper        HasMultipleLines = true;
16532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    }
16632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return false;
16732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  }
16832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
16932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  bool parseSquare() {
17032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    if (!CurrentToken)
17132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      return false;
17232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
173d71b15badeecdc049440103ef044f9cdf5e1359cAlexander Kornienko    // A '[' could be an index subscript (after an identifier or after
174051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber    // ')' or ']'), it could be the start of an Objective-C method
175051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber    // expression, or it could the the start of an Objective-C array literal.
176b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek    FormatToken *Left = CurrentToken->Previous;
1770bdc6434fa0fea933b6ab566eff751afdba40a2aAlexander Kornienko    FormatToken *Parent = Left->getPreviousNonComment();
17832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    bool StartsObjCMethodExpr =
1796f21a988990ff5872822dcb049bd8fc65ce3d236Daniel Jasper        Contexts.back().CanBeExpression &&
180e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko        (!Parent || Parent->isOneOf(tok::colon, tok::l_square, tok::l_paren,
181e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko                                    tok::kw_return, tok::kw_throw) ||
182ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper         Parent->isUnaryOperator() || Parent->Type == TT_ObjCForIn ||
183e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko         Parent->Type == TT_CastRParen ||
184b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek         getBinOpPrecedence(Parent->Tok.getKind(), true, true) > prec::Unknown);
185923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper    ScopedContextCreator ContextCreator(*this, tok::l_square, 10);
1866f21a988990ff5872822dcb049bd8fc65ce3d236Daniel Jasper    Contexts.back().IsExpression = true;
187051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber    bool StartsObjCArrayLiteral = Parent && Parent->is(tok::at);
18832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
1894e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper    if (StartsObjCMethodExpr) {
1904e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper      Contexts.back().ColonIsObjCMethodExpr = true;
1914e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper      Left->Type = TT_ObjCMethodExpr;
192051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber    } else if (StartsObjCArrayLiteral) {
193051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber      Left->Type = TT_ObjCArrayLiteral;
1944e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper    }
19532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
19632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    while (CurrentToken != NULL) {
19732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      if (CurrentToken->is(tok::r_square)) {
198b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek        if (CurrentToken->Next && CurrentToken->Next->is(tok::l_paren)) {
199e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber          // An ObjC method call is rarely followed by an open parenthesis.
20032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper          // FIXME: Do we incorrectly label ":" with this?
20132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper          StartsObjCMethodExpr = false;
20232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper          Left->Type = TT_Unknown;
20332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        }
2040178673f541685cf5067814dfeee2644078e39a9Daniel Jasper        if (StartsObjCMethodExpr) {
2054e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper          CurrentToken->Type = TT_ObjCMethodExpr;
206e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber          // determineStarAmpUsage() thinks that '*' '[' is allocating an
207e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber          // array of pointers, but if '[' starts a selector then '*' is a
208e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber          // binary operator.
2093fd9ccdd9f8d259bcf518e7056cfd419d992e984Alexander Kornienko          if (Parent != NULL && Parent->Type == TT_PointerOrReference)
2104ed7f3e003c906d9fdb92a9484feeb8ac6e28e2fNico Weber            Parent->Type = TT_BinaryOperator;
211051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber        } else if (StartsObjCArrayLiteral) {
212051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber          CurrentToken->Type = TT_ObjCArrayLiteral;
2130178673f541685cf5067814dfeee2644078e39a9Daniel Jasper        }
21432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        Left->MatchingParen = CurrentToken;
21532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        CurrentToken->MatchingParen = Left;
2164e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper        if (Contexts.back().FirstObjCSelectorName != NULL)
2174e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper          Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
2184e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper              Contexts.back().LongestObjCSelectorName;
21932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        next();
22032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        return true;
22132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      }
222e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko      if (CurrentToken->isOneOf(tok::r_paren, tok::r_brace))
22332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        return false;
2249fc56f2636137fcde8acb38865555ed6c7b84dfdDaniel Jasper      updateParameterCount(Left, CurrentToken);
22532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      if (!consumeToken())
22632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        return false;
22732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    }
22832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return false;
22932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  }
23032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
23132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  bool parseBrace() {
23253e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper    if (CurrentToken != NULL) {
23353e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper      ScopedContextCreator ContextCreator(*this, tok::l_brace, 1);
234b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek      FormatToken *Left = CurrentToken->Previous;
235f2ff8126e9e9df368f31b1f968d8fc80f99809b3Nico Weber
2360bdc6434fa0fea933b6ab566eff751afdba40a2aAlexander Kornienko      FormatToken *Parent = Left->getPreviousNonComment();
237f2ff8126e9e9df368f31b1f968d8fc80f99809b3Nico Weber      bool StartsObjCDictLiteral = Parent && Parent->is(tok::at);
238f2ff8126e9e9df368f31b1f968d8fc80f99809b3Nico Weber      if (StartsObjCDictLiteral) {
239f2ff8126e9e9df368f31b1f968d8fc80f99809b3Nico Weber        Contexts.back().ColonIsObjCDictLiteral = true;
240f2ff8126e9e9df368f31b1f968d8fc80f99809b3Nico Weber        Left->Type = TT_ObjCDictLiteral;
241f2ff8126e9e9df368f31b1f968d8fc80f99809b3Nico Weber      }
242f2ff8126e9e9df368f31b1f968d8fc80f99809b3Nico Weber
24353e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper      while (CurrentToken != NULL) {
24453e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper        if (CurrentToken->is(tok::r_brace)) {
245f2ff8126e9e9df368f31b1f968d8fc80f99809b3Nico Weber          if (StartsObjCDictLiteral)
246f2ff8126e9e9df368f31b1f968d8fc80f99809b3Nico Weber            CurrentToken->Type = TT_ObjCDictLiteral;
24753e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper          Left->MatchingParen = CurrentToken;
24853e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper          CurrentToken->MatchingParen = Left;
24953e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper          next();
25053e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper          return true;
25153e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper        }
25253e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper        if (CurrentToken->isOneOf(tok::r_paren, tok::r_square))
25353e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper          return false;
25453e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper        updateParameterCount(Left, CurrentToken);
25553e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper        if (!consumeToken())
25653e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper          return false;
25732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      }
25832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    }
25953e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper    // No closing "}" found, this probably starts a definition.
26053e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper    Line.StartsDefinition = true;
26132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return true;
26232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  }
263c4615b7aaf97e303a4fc675956f7f5572d492885Daniel Jasper
264b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  void updateParameterCount(FormatToken *Left, FormatToken *Current) {
265c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper    if (Current->is(tok::comma)) {
2669fc56f2636137fcde8acb38865555ed6c7b84dfdDaniel Jasper      ++Left->ParameterCount;
267c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper    } else if (Left->ParameterCount == 0 && Current->isNot(tok::comment)) {
2689fc56f2636137fcde8acb38865555ed6c7b84dfdDaniel Jasper      Left->ParameterCount = 1;
269c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper    }
2709fc56f2636137fcde8acb38865555ed6c7b84dfdDaniel Jasper  }
27132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
27232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  bool parseConditional() {
27332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    while (CurrentToken != NULL) {
27432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      if (CurrentToken->is(tok::colon)) {
27532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        CurrentToken->Type = TT_ConditionalExpr;
27632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        next();
27732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        return true;
27832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      }
27932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      if (!consumeToken())
28032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        return false;
28132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    }
28232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return false;
28332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  }
28432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
28532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  bool parseTemplateDeclaration() {
28632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    if (CurrentToken != NULL && CurrentToken->is(tok::less)) {
28732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      CurrentToken->Type = TT_TemplateOpener;
28832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      next();
28932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      if (!parseAngle())
29032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        return false;
29134511fb79201ba9ed39c97f3a7ea0f157a79436dDaniel Jasper      if (CurrentToken != NULL)
292b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek        CurrentToken->Previous->ClosesTemplateDeclaration = true;
29332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      return true;
29432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    }
29532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return false;
29632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  }
29732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
29832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  bool consumeToken() {
299b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek    FormatToken *Tok = CurrentToken;
30032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    next();
301b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek    switch (Tok->Tok.getKind()) {
30232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    case tok::plus:
30332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    case tok::minus:
304b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek      if (Tok->Previous == NULL && Line.MustBeDeclaration)
30532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        Tok->Type = TT_ObjCMethodSpecifier;
30632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      break;
30732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    case tok::colon:
308b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek      if (Tok->Previous == NULL)
309cf6d76af806f7e1ba97be7b72b31bc78b919e0f0Daniel Jasper        return false;
31032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      // Colons from ?: are handled in parseConditional().
311b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek      if (Tok->Previous->is(tok::r_paren) && Contexts.size() == 1) {
31232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        Tok->Type = TT_CtorInitializerColon;
313f2ff8126e9e9df368f31b1f968d8fc80f99809b3Nico Weber      } else if (Contexts.back().ColonIsObjCDictLiteral) {
314f2ff8126e9e9df368f31b1f968d8fc80f99809b3Nico Weber        Tok->Type = TT_ObjCDictLiteral;
3154e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper      } else if (Contexts.back().ColonIsObjCMethodExpr ||
316b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek                 Line.First->Type == TT_ObjCMethodSpecifier) {
31732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        Tok->Type = TT_ObjCMethodExpr;
318b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek        Tok->Previous->Type = TT_ObjCSelectorName;
31900895106f9ed602af67984ec4d225a0cdc8c12afAlexander Kornienko        if (Tok->Previous->CodePointCount >
32000895106f9ed602af67984ec4d225a0cdc8c12afAlexander Kornienko            Contexts.back().LongestObjCSelectorName) {
32100895106f9ed602af67984ec4d225a0cdc8c12afAlexander Kornienko          Contexts.back().LongestObjCSelectorName =
32200895106f9ed602af67984ec4d225a0cdc8c12afAlexander Kornienko              Tok->Previous->CodePointCount;
32300895106f9ed602af67984ec4d225a0cdc8c12afAlexander Kornienko        }
3244e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper        if (Contexts.back().FirstObjCSelectorName == NULL)
325b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek          Contexts.back().FirstObjCSelectorName = Tok->Previous;
3264e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper      } else if (Contexts.back().ColonIsForRangeExpr) {
32732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        Tok->Type = TT_RangeBasedForLoopColon;
3286cabab48dacc1317821f8f078ed2d4c603b67affDaniel Jasper      } else if (Contexts.size() == 1) {
3296cabab48dacc1317821f8f078ed2d4c603b67affDaniel Jasper        Tok->Type = TT_InheritanceColon;
330923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper      } else if (Contexts.back().ContextKind == tok::l_paren) {
331923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper        Tok->Type = TT_InlineASMColon;
33263d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper      }
33332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      break;
33432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    case tok::kw_if:
33532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    case tok::kw_while:
33632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      if (CurrentToken != NULL && CurrentToken->is(tok::l_paren)) {
33732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        next();
3382726877196b41b922f10f794801b313980e1a8adNico Weber        if (!parseParens(/*LookForDecls=*/true))
33932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper          return false;
34032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      }
34132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      break;
34232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    case tok::kw_for:
3434e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper      Contexts.back().ColonIsForRangeExpr = true;
34432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      next();
34532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      if (!parseParens())
34632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        return false;
34732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      break;
34832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    case tok::l_paren:
34932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      if (!parseParens())
35032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        return false;
3511407bee187d7b964d5293ac8bf4f7a490c78cec6Daniel Jasper      if (Line.MustBeDeclaration && NameFound && !Contexts.back().IsExpression)
3523c08a818a6ac9115fe8880af9bbf5a0a87bdffaaDaniel Jasper        Line.MightBeFunctionDecl = true;
35332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      break;
35432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    case tok::l_square:
35532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      if (!parseSquare())
35632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        return false;
35732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      break;
35832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    case tok::l_brace:
35932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      if (!parseBrace())
36032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        return false;
36132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      break;
36232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    case tok::less:
36332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      if (parseAngle())
36432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        Tok->Type = TT_TemplateOpener;
36532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      else {
36632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        Tok->Type = TT_BinaryOperator;
36732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        CurrentToken = Tok;
36832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        next();
36932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      }
37032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      break;
37132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    case tok::r_paren:
37232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    case tok::r_square:
37332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      return false;
37432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    case tok::r_brace:
37532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      // Lines can start with '}'.
376b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek      if (Tok->Previous != NULL)
37732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        return false;
37832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      break;
37932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    case tok::greater:
38032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      Tok->Type = TT_BinaryOperator;
38132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      break;
38232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    case tok::kw_operator:
3832b4c924f85e156d66c01b3f16c850892c47dcc7aDaniel Jasper      while (CurrentToken && CurrentToken->isNot(tok::l_paren)) {
384e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko        if (CurrentToken->isOneOf(tok::star, tok::amp))
3852b4c924f85e156d66c01b3f16c850892c47dcc7aDaniel Jasper          CurrentToken->Type = TT_PointerOrReference;
3862b4c924f85e156d66c01b3f16c850892c47dcc7aDaniel Jasper        consumeToken();
38732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      }
3886ea933c7e8f6988d5647af4a0eafd393a4c3685aDaniel Jasper      if (CurrentToken) {
3892b4c924f85e156d66c01b3f16c850892c47dcc7aDaniel Jasper        CurrentToken->Type = TT_OverloadedOperatorLParen;
390b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek        if (CurrentToken->Previous->Type == TT_BinaryOperator)
391b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek          CurrentToken->Previous->Type = TT_OverloadedOperator;
3926ea933c7e8f6988d5647af4a0eafd393a4c3685aDaniel Jasper      }
39332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      break;
39432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    case tok::question:
39532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      parseConditional();
39632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      break;
39732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    case tok::kw_template:
39832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      parseTemplateDeclaration();
39932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      break;
400c2e6d2a4a7fe9dfa7d52a38c6048b7b18e6b591aNico Weber    case tok::identifier:
401b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek      if (Line.First->is(tok::kw_for) &&
402b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek          Tok->Tok.getIdentifierInfo() == &Ident_in)
403c2e6d2a4a7fe9dfa7d52a38c6048b7b18e6b591aNico Weber        Tok->Type = TT_ObjCForIn;
404c2e6d2a4a7fe9dfa7d52a38c6048b7b18e6b591aNico Weber      break;
4058ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper    case tok::comma:
4068ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper      if (Contexts.back().FirstStartOfName)
4078ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper        Contexts.back().FirstStartOfName->PartOfMultiVariableDeclStmt = true;
4088ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper      break;
40932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    default:
41032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      break;
41132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    }
41232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return true;
41332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  }
41432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
41532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  void parseIncludeDirective() {
41632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    next();
41732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    if (CurrentToken != NULL && CurrentToken->is(tok::less)) {
41832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      next();
41932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      while (CurrentToken != NULL) {
420b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek        if (CurrentToken->isNot(tok::comment) || CurrentToken->Next)
42132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper          CurrentToken->Type = TT_ImplicitStringLiteral;
42232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        next();
42332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      }
42432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    } else {
42532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      while (CurrentToken != NULL) {
4263a204418482c9ae70ad482e781132c54306c3aa6Daniel Jasper        if (CurrentToken->is(tok::string_literal))
4273a204418482c9ae70ad482e781132c54306c3aa6Daniel Jasper          // Mark these string literals as "implicit" literals, too, so that
4283a204418482c9ae70ad482e781132c54306c3aa6Daniel Jasper          // they are not split or line-wrapped.
4293a204418482c9ae70ad482e781132c54306c3aa6Daniel Jasper          CurrentToken->Type = TT_ImplicitStringLiteral;
43032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        next();
43132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      }
43232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    }
43332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  }
43432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
43532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  void parseWarningOrError() {
43632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    next();
43732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    // We still want to format the whitespace left of the first token of the
43832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    // warning or error.
43932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    next();
44032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    while (CurrentToken != NULL) {
44132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      CurrentToken->Type = TT_ImplicitStringLiteral;
44232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      next();
44332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    }
44432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  }
44532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
44632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  void parsePreprocessorDirective() {
44732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    next();
44832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    if (CurrentToken == NULL)
44932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      return;
45032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    // Hashes in the middle of a line can lead to any strange token
45132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    // sequence.
452b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek    if (CurrentToken->Tok.getIdentifierInfo() == NULL)
45332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      return;
454b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek    switch (CurrentToken->Tok.getIdentifierInfo()->getPPKeywordID()) {
45532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    case tok::pp_include:
45632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    case tok::pp_import:
45732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      parseIncludeDirective();
45832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      break;
45932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    case tok::pp_error:
46032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    case tok::pp_warning:
46132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      parseWarningOrError();
46232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      break;
463aae7bad5cdd804cb88e918e9defbf5faf69f4cfdDaniel Jasper    case tok::pp_if:
464aae7bad5cdd804cb88e918e9defbf5faf69f4cfdDaniel Jasper    case tok::pp_elif:
465aae7bad5cdd804cb88e918e9defbf5faf69f4cfdDaniel Jasper      parseLine();
466aae7bad5cdd804cb88e918e9defbf5faf69f4cfdDaniel Jasper      break;
46732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    default:
46832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      break;
46932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    }
4705b7e7b0ec77f49c1b24deffc9b7032ca16ca9f0dDaniel Jasper    while (CurrentToken != NULL)
4715b7e7b0ec77f49c1b24deffc9b7032ca16ca9f0dDaniel Jasper      next();
47232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  }
47332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
47495e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weberpublic:
47532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  LineType parseLine() {
47632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    int PeriodsAndArrows = 0;
477b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek    FormatToken *LastPeriodOrArrow = NULL;
47832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    bool CanBeBuilderTypeStmt = true;
47932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    if (CurrentToken->is(tok::hash)) {
48032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      parsePreprocessorDirective();
48132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      return LT_PreprocessorDirective;
48232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    }
48332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    while (CurrentToken != NULL) {
48432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      if (CurrentToken->is(tok::kw_virtual))
48532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        KeywordVirtualFound = true;
486e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko      if (CurrentToken->isOneOf(tok::period, tok::arrow)) {
48732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        ++PeriodsAndArrows;
488248497199bc56e86d1c089beb9529f3b3d77abb1Daniel Jasper        LastPeriodOrArrow = CurrentToken;
489248497199bc56e86d1c089beb9529f3b3d77abb1Daniel Jasper      }
490b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek      FormatToken *TheToken = CurrentToken;
49132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      if (!consumeToken())
49232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        return LT_Invalid;
493b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek      if (TheToken->getPrecedence() > prec::Assignment &&
49482282dc907a04b1931f8f578693b035ad751fd3bDaniel Jasper          TheToken->Type == TT_BinaryOperator)
4954a544e5856ceadef1c095c7d1ae5c8d760851d59Daniel Jasper        CanBeBuilderTypeStmt = false;
49632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    }
49732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    if (KeywordVirtualFound)
49832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      return LT_VirtualFunctionDecl;
49932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
50032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    // Assume a builder-type call if there are 2 or more "." and "->".
501248497199bc56e86d1c089beb9529f3b3d77abb1Daniel Jasper    if (PeriodsAndArrows >= 2 && CanBeBuilderTypeStmt) {
502248497199bc56e86d1c089beb9529f3b3d77abb1Daniel Jasper      LastPeriodOrArrow->LastInChainOfCalls = true;
50332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      return LT_BuilderTypeCall;
504248497199bc56e86d1c089beb9529f3b3d77abb1Daniel Jasper    }
50532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
506b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek    if (Line.First->Type == TT_ObjCMethodSpecifier) {
5074e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper      if (Contexts.back().FirstObjCSelectorName != NULL)
5084e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper        Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
5094e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper            Contexts.back().LongestObjCSelectorName;
51063d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper      return LT_ObjCMethodDecl;
51163d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper    }
51263d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper
51332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return LT_Other;
51432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  }
51532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
51695e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weberprivate:
51732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  void next() {
5180178673f541685cf5067814dfeee2644078e39a9Daniel Jasper    if (CurrentToken != NULL) {
5190178673f541685cf5067814dfeee2644078e39a9Daniel Jasper      determineTokenType(*CurrentToken);
5204e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper      CurrentToken->BindingStrength = Contexts.back().BindingStrength;
5210178673f541685cf5067814dfeee2644078e39a9Daniel Jasper    }
5220178673f541685cf5067814dfeee2644078e39a9Daniel Jasper
523b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek    if (CurrentToken != NULL)
524b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek      CurrentToken = CurrentToken->Next;
525d0f349be1422a123fdb28d6dd556f7300e6d51e9Daniel Jasper
526d0f349be1422a123fdb28d6dd556f7300e6d51e9Daniel Jasper    // Reset token type in case we have already looked at it and then recovered
527d0f349be1422a123fdb28d6dd556f7300e6d51e9Daniel Jasper    // from an error (e.g. failure to find the matching >).
528d0f349be1422a123fdb28d6dd556f7300e6d51e9Daniel Jasper    if (CurrentToken != NULL)
529d0f349be1422a123fdb28d6dd556f7300e6d51e9Daniel Jasper      CurrentToken->Type = TT_Unknown;
53032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  }
53132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
5324e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper  /// \brief A struct to hold information valid in a specific context, e.g.
5334e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper  /// a pair of parenthesis.
5344e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper  struct Context {
535923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper    Context(tok::TokenKind ContextKind, unsigned BindingStrength,
536923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper            bool IsExpression)
537923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper        : ContextKind(ContextKind), BindingStrength(BindingStrength),
538923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper          LongestObjCSelectorName(0), ColonIsForRangeExpr(false),
539f2ff8126e9e9df368f31b1f968d8fc80f99809b3Nico Weber          ColonIsObjCDictLiteral(false), ColonIsObjCMethodExpr(false),
540f2ff8126e9e9df368f31b1f968d8fc80f99809b3Nico Weber          FirstObjCSelectorName(NULL), FirstStartOfName(NULL),
541f2ff8126e9e9df368f31b1f968d8fc80f99809b3Nico Weber          IsExpression(IsExpression), CanBeExpression(true) {}
542923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper
543923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper    tok::TokenKind ContextKind;
5444e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper    unsigned BindingStrength;
5454e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper    unsigned LongestObjCSelectorName;
5464e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper    bool ColonIsForRangeExpr;
547f2ff8126e9e9df368f31b1f968d8fc80f99809b3Nico Weber    bool ColonIsObjCDictLiteral;
5484e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper    bool ColonIsObjCMethodExpr;
549b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek    FormatToken *FirstObjCSelectorName;
550b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek    FormatToken *FirstStartOfName;
5514e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper    bool IsExpression;
5526f21a988990ff5872822dcb049bd8fc65ce3d236Daniel Jasper    bool CanBeExpression;
5534e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper  };
5544e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper
5554e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper  /// \brief Puts a new \c Context onto the stack \c Contexts for the lifetime
5564e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper  /// of each instance.
5574e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper  struct ScopedContextCreator {
5584e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper    AnnotatingParser &P;
5594e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper
560923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper    ScopedContextCreator(AnnotatingParser &P, tok::TokenKind ContextKind,
561923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper                         unsigned Increase)
562923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper        : P(P) {
5632a409b62126d8f0b8f5749d5ed435ad2b394b526Daniel Jasper      P.Contexts.push_back(Context(ContextKind,
5642a409b62126d8f0b8f5749d5ed435ad2b394b526Daniel Jasper                                   P.Contexts.back().BindingStrength + Increase,
5652a409b62126d8f0b8f5749d5ed435ad2b394b526Daniel Jasper                                   P.Contexts.back().IsExpression));
5664e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper    }
5674e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper
5684e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper    ~ScopedContextCreator() { P.Contexts.pop_back(); }
5694e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper  };
5700178673f541685cf5067814dfeee2644078e39a9Daniel Jasper
571b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  void determineTokenType(FormatToken &Current) {
572b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek    if (Current.getPrecedence() == prec::Assignment &&
573b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek        (!Current.Previous || Current.Previous->isNot(tok::kw_operator))) {
5744e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper      Contexts.back().IsExpression = true;
575b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek      for (FormatToken *Previous = Current.Previous;
57695e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weber           Previous && Previous->isNot(tok::comma);
577b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek           Previous = Previous->Previous) {
5789c65b069821b7de79427e291b006293a0f55ff8fDaniel Jasper        if (Previous->is(tok::r_square))
5799c65b069821b7de79427e291b006293a0f55ff8fDaniel Jasper          Previous = Previous->MatchingParen;
5800178673f541685cf5067814dfeee2644078e39a9Daniel Jasper        if (Previous->Type == TT_BinaryOperator &&
581e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko            Previous->isOneOf(tok::star, tok::amp)) {
5820178673f541685cf5067814dfeee2644078e39a9Daniel Jasper          Previous->Type = TT_PointerOrReference;
5830178673f541685cf5067814dfeee2644078e39a9Daniel Jasper        }
5840178673f541685cf5067814dfeee2644078e39a9Daniel Jasper      }
585e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko    } else if (Current.isOneOf(tok::kw_return, tok::kw_throw) ||
58695e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weber               (Current.is(tok::l_paren) && !Line.MustBeDeclaration &&
587378d93dcf7ec80661efc65642dc6266c9e13780aDaniel Jasper                !Line.InPPDirective &&
588b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek                (!Current.Previous || Current.Previous->isNot(tok::kw_for)))) {
5894e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper      Contexts.back().IsExpression = true;
590e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko    } else if (Current.isOneOf(tok::r_paren, tok::greater, tok::comma)) {
591b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek      for (FormatToken *Previous = Current.Previous;
592e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko           Previous && Previous->isOneOf(tok::star, tok::amp);
593b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek           Previous = Previous->Previous)
59495e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weber        Previous->Type = TT_PointerOrReference;
595b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek    } else if (Current.Previous &&
596b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek               Current.Previous->Type == TT_CtorInitializerColon) {
597d0f349be1422a123fdb28d6dd556f7300e6d51e9Daniel Jasper      Contexts.back().IsExpression = true;
5986f21a988990ff5872822dcb049bd8fc65ce3d236Daniel Jasper    } else if (Current.is(tok::kw_new)) {
5996f21a988990ff5872822dcb049bd8fc65ce3d236Daniel Jasper      Contexts.back().CanBeExpression = false;
60016a69ef481f4580c571b6c693a5d3dd64ea56b53Daniel Jasper    } else if (Current.is(tok::semi)) {
60116a69ef481f4580c571b6c693a5d3dd64ea56b53Daniel Jasper      // This should be the condition or increment in a for-loop.
60216a69ef481f4580c571b6c693a5d3dd64ea56b53Daniel Jasper      Contexts.back().IsExpression = true;
60395e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weber    }
6040178673f541685cf5067814dfeee2644078e39a9Daniel Jasper
6050178673f541685cf5067814dfeee2644078e39a9Daniel Jasper    if (Current.Type == TT_Unknown) {
6066ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper      if (isStartOfName(Current)) {
6078ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper        Contexts.back().FirstStartOfName = &Current;
6083c08a818a6ac9115fe8880af9bbf5a0a87bdffaaDaniel Jasper        Current.Type = TT_StartOfName;
6091407bee187d7b964d5293ac8bf4f7a490c78cec6Daniel Jasper        NameFound = true;
6102ca3741a962ded08866596577aaee2f4ab74c955Daniel Jasper      } else if (Current.is(tok::kw_auto)) {
6112ca3741a962ded08866596577aaee2f4ab74c955Daniel Jasper        AutoFound = true;
6123262f4c10520cf11acea4cf590cfbf055924a41eDaniel Jasper      } else if (Current.is(tok::arrow) && AutoFound &&
6133262f4c10520cf11acea4cf590cfbf055924a41eDaniel Jasper                 Line.MustBeDeclaration) {
6142ca3741a962ded08866596577aaee2f4ab74c955Daniel Jasper        Current.Type = TT_TrailingReturnArrow;
615e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko      } else if (Current.isOneOf(tok::star, tok::amp, tok::ampamp)) {
6164e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper        Current.Type =
617d6104f6c34639ebe66f83d955c5f32ea4a50c266Daniel Jasper            determineStarAmpUsage(Current, Contexts.back().CanBeExpression &&
618d6104f6c34639ebe66f83d955c5f32ea4a50c266Daniel Jasper                                               Contexts.back().IsExpression);
619e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko      } else if (Current.isOneOf(tok::minus, tok::plus, tok::caret)) {
6200178673f541685cf5067814dfeee2644078e39a9Daniel Jasper        Current.Type = determinePlusMinusCaretUsage(Current);
621e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko      } else if (Current.isOneOf(tok::minusminus, tok::plusplus)) {
6220178673f541685cf5067814dfeee2644078e39a9Daniel Jasper        Current.Type = determineIncrementUsage(Current);
6230178673f541685cf5067814dfeee2644078e39a9Daniel Jasper      } else if (Current.is(tok::exclaim)) {
6240178673f541685cf5067814dfeee2644078e39a9Daniel Jasper        Current.Type = TT_UnaryOperator;
625ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper      } else if (Current.isBinaryOperator()) {
6260178673f541685cf5067814dfeee2644078e39a9Daniel Jasper        Current.Type = TT_BinaryOperator;
6270178673f541685cf5067814dfeee2644078e39a9Daniel Jasper      } else if (Current.is(tok::comment)) {
62800895106f9ed602af67984ec4d225a0cdc8c12afAlexander Kornienko        if (Current.TokenText.startswith("//"))
6290178673f541685cf5067814dfeee2644078e39a9Daniel Jasper          Current.Type = TT_LineComment;
6300178673f541685cf5067814dfeee2644078e39a9Daniel Jasper        else
6310178673f541685cf5067814dfeee2644078e39a9Daniel Jasper          Current.Type = TT_BlockComment;
63237d693160eba22343e08d7bcf66cd132ace77e5cNico Weber      } else if (Current.is(tok::r_paren)) {
633b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper        FormatToken *LeftOfParens = NULL;
634b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper        if (Current.MatchingParen)
6350bdc6434fa0fea933b6ab566eff751afdba40a2aAlexander Kornienko          LeftOfParens = Current.MatchingParen->getPreviousNonComment();
636b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper        bool IsCast = false;
637b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper        bool ParensAreEmpty = Current.Previous == Current.MatchingParen;
638b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper        bool ParensAreType = !Current.Previous ||
639b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek                             Current.Previous->Type == TT_PointerOrReference ||
640b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper                             Current.Previous->Type == TT_TemplateCloser ||
641b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper                             isSimpleTypeSpecifier(*Current.Previous);
64237d693160eba22343e08d7bcf66cd132ace77e5cNico Weber        bool ParensCouldEndDecl =
643b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek            Current.Next &&
644b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek            Current.Next->isOneOf(tok::equal, tok::semi, tok::l_brace);
6456a365aaa057a8c445d25344c0433726c752b3e7dDaniel Jasper        bool IsSizeOfOrAlignOf =
646b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper            LeftOfParens &&
647b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper            LeftOfParens->isOneOf(tok::kw_sizeof, tok::kw_alignof);
648b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper        if (ParensAreType && !ParensCouldEndDecl && !IsSizeOfOrAlignOf &&
6490c368787d9d1f92a3408b71b3f074a06edaa6bdeDaniel Jasper            (Contexts.back().IsExpression ||
6500c368787d9d1f92a3408b71b3f074a06edaa6bdeDaniel Jasper             (Current.Next && Current.Next->isBinaryOperator())))
651b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper          IsCast = true;
6522a409b62126d8f0b8f5749d5ed435ad2b394b526Daniel Jasper        if (Current.Next && Current.Next->isNot(tok::string_literal) &&
653b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper            (Current.Next->Tok.isLiteral() ||
654b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper             Current.Next->isOneOf(tok::kw_sizeof, tok::kw_alignof)))
655b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper          IsCast = true;
656b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper        // If there is an identifier after the (), it is likely a cast, unless
657b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper        // there is also an identifier before the ().
658ff1a2e519ebcd6d7a060eac7ba8aca37b2bf89d0Daniel Jasper        if (LeftOfParens && (LeftOfParens->Tok.getIdentifierInfo() == NULL ||
659ff1a2e519ebcd6d7a060eac7ba8aca37b2bf89d0Daniel Jasper                             LeftOfParens->is(tok::kw_return)) &&
660526df0f3a8d436e9084bd12118a2e119aa0bd724Daniel Jasper            LeftOfParens->Type != TT_OverloadedOperator &&
661465e8615a153ebd70eb27785af79f7e82e4a81d4Nico Weber            LeftOfParens->Type != TT_TemplateCloser && Current.Next &&
662465e8615a153ebd70eb27785af79f7e82e4a81d4Nico Weber            Current.Next->is(tok::identifier))
663b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper          IsCast = true;
664b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper        if (IsCast && !ParensAreEmpty)
66537d693160eba22343e08d7bcf66cd132ace77e5cNico Weber          Current.Type = TT_CastRParen;
666b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek      } else if (Current.is(tok::at) && Current.Next) {
667b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek        switch (Current.Next->Tok.getObjCKeywordID()) {
6680178673f541685cf5067814dfeee2644078e39a9Daniel Jasper        case tok::objc_interface:
6690178673f541685cf5067814dfeee2644078e39a9Daniel Jasper        case tok::objc_implementation:
6700178673f541685cf5067814dfeee2644078e39a9Daniel Jasper        case tok::objc_protocol:
6710178673f541685cf5067814dfeee2644078e39a9Daniel Jasper          Current.Type = TT_ObjCDecl;
6720178673f541685cf5067814dfeee2644078e39a9Daniel Jasper          break;
6730178673f541685cf5067814dfeee2644078e39a9Daniel Jasper        case tok::objc_property:
6740178673f541685cf5067814dfeee2644078e39a9Daniel Jasper          Current.Type = TT_ObjCProperty;
6750178673f541685cf5067814dfeee2644078e39a9Daniel Jasper          break;
6760178673f541685cf5067814dfeee2644078e39a9Daniel Jasper        default:
6770178673f541685cf5067814dfeee2644078e39a9Daniel Jasper          break;
6780178673f541685cf5067814dfeee2644078e39a9Daniel Jasper        }
6795ad390d27f8f7cb6628bc2c32beba4d25bc2718bDaniel Jasper      } else if (Current.is(tok::period)) {
6800bdc6434fa0fea933b6ab566eff751afdba40a2aAlexander Kornienko        FormatToken *PreviousNoComment = Current.getPreviousNonComment();
6815ad390d27f8f7cb6628bc2c32beba4d25bc2718bDaniel Jasper        if (PreviousNoComment &&
6825ad390d27f8f7cb6628bc2c32beba4d25bc2718bDaniel Jasper            PreviousNoComment->isOneOf(tok::comma, tok::l_brace))
6835ad390d27f8f7cb6628bc2c32beba4d25bc2718bDaniel Jasper          Current.Type = TT_DesignatedInitializerPeriod;
6840178673f541685cf5067814dfeee2644078e39a9Daniel Jasper      }
6850178673f541685cf5067814dfeee2644078e39a9Daniel Jasper    }
6860178673f541685cf5067814dfeee2644078e39a9Daniel Jasper  }
6870178673f541685cf5067814dfeee2644078e39a9Daniel Jasper
6886ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper  /// \brief Take a guess at whether \p Tok starts a name of a function or
6896ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper  /// variable declaration.
6906ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper  ///
6916ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper  /// This is a heuristic based on whether \p Tok is an identifier following
6926ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper  /// something that is likely a type.
6936ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper  bool isStartOfName(const FormatToken &Tok) {
6946ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper    if (Tok.isNot(tok::identifier) || Tok.Previous == NULL)
6956ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper      return false;
6966ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper
6976ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper    // Skip "const" as it does not have an influence on whether this is a name.
6986ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper    FormatToken *PreviousNotConst = Tok.Previous;
6996ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper    while (PreviousNotConst != NULL && PreviousNotConst->is(tok::kw_const))
7006ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper      PreviousNotConst = PreviousNotConst->Previous;
7016ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper
7026ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper    if (PreviousNotConst == NULL)
7036ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper      return false;
7046ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper
7052a409b62126d8f0b8f5749d5ed435ad2b394b526Daniel Jasper    bool IsPPKeyword = PreviousNotConst->is(tok::identifier) &&
7062a409b62126d8f0b8f5749d5ed435ad2b394b526Daniel Jasper                       PreviousNotConst->Previous &&
7072a409b62126d8f0b8f5749d5ed435ad2b394b526Daniel Jasper                       PreviousNotConst->Previous->is(tok::hash);
7086ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper
7096ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper    return (!IsPPKeyword && PreviousNotConst->is(tok::identifier)) ||
7106ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper           PreviousNotConst->Type == TT_PointerOrReference ||
7116ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper           PreviousNotConst->Type == TT_TemplateCloser ||
7126ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper           isSimpleTypeSpecifier(*PreviousNotConst);
7136ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper  }
7146ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper
7150178673f541685cf5067814dfeee2644078e39a9Daniel Jasper  /// \brief Return the type of the given token assuming it is * or &.
716b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  TokenType determineStarAmpUsage(const FormatToken &Tok, bool IsExpression) {
7170bdc6434fa0fea933b6ab566eff751afdba40a2aAlexander Kornienko    const FormatToken *PrevToken = Tok.getPreviousNonComment();
7180178673f541685cf5067814dfeee2644078e39a9Daniel Jasper    if (PrevToken == NULL)
7190178673f541685cf5067814dfeee2644078e39a9Daniel Jasper      return TT_UnaryOperator;
7200178673f541685cf5067814dfeee2644078e39a9Daniel Jasper
7210bdc6434fa0fea933b6ab566eff751afdba40a2aAlexander Kornienko    const FormatToken *NextToken = Tok.getNextNonComment();
7220178673f541685cf5067814dfeee2644078e39a9Daniel Jasper    if (NextToken == NULL)
7230178673f541685cf5067814dfeee2644078e39a9Daniel Jasper      return TT_Unknown;
7240178673f541685cf5067814dfeee2644078e39a9Daniel Jasper
725431f5918281dd1f178bf838b7a47ab1d11c52961Daniel Jasper    if (PrevToken->is(tok::coloncolon) ||
726431f5918281dd1f178bf838b7a47ab1d11c52961Daniel Jasper        (PrevToken->is(tok::l_paren) && !IsExpression))
7278a5d7cd100ebfb8c6b353ee4ad5b14ab4105d32dDaniel Jasper      return TT_PointerOrReference;
7288a5d7cd100ebfb8c6b353ee4ad5b14ab4105d32dDaniel Jasper
729e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko    if (PrevToken->isOneOf(tok::l_paren, tok::l_square, tok::l_brace,
730d3cf17b5f1fed43dbd0cd35c43d15139803c9c84Daniel Jasper                           tok::comma, tok::semi, tok::kw_return, tok::colon,
731dbef71ebc66fe5553db01eb8e95b696c3223e737Daniel Jasper                           tok::equal, tok::kw_delete) ||
732e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko        PrevToken->Type == TT_BinaryOperator ||
7330178673f541685cf5067814dfeee2644078e39a9Daniel Jasper        PrevToken->Type == TT_UnaryOperator || PrevToken->Type == TT_CastRParen)
7340178673f541685cf5067814dfeee2644078e39a9Daniel Jasper      return TT_UnaryOperator;
7350178673f541685cf5067814dfeee2644078e39a9Daniel Jasper
736e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber    if (NextToken->is(tok::l_square))
737e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber      return TT_PointerOrReference;
738e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber
739b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek    if (PrevToken->Tok.isLiteral() ||
740e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko        PrevToken->isOneOf(tok::r_paren, tok::r_square) ||
741b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek        NextToken->Tok.isLiteral() || NextToken->isUnaryOperator())
7420178673f541685cf5067814dfeee2644078e39a9Daniel Jasper      return TT_BinaryOperator;
7430178673f541685cf5067814dfeee2644078e39a9Daniel Jasper
7440178673f541685cf5067814dfeee2644078e39a9Daniel Jasper    // It is very unlikely that we are going to find a pointer or reference type
7450178673f541685cf5067814dfeee2644078e39a9Daniel Jasper    // definition on the RHS of an assignment.
7460178673f541685cf5067814dfeee2644078e39a9Daniel Jasper    if (IsExpression)
7470178673f541685cf5067814dfeee2644078e39a9Daniel Jasper      return TT_BinaryOperator;
7480178673f541685cf5067814dfeee2644078e39a9Daniel Jasper
7490178673f541685cf5067814dfeee2644078e39a9Daniel Jasper    return TT_PointerOrReference;
7500178673f541685cf5067814dfeee2644078e39a9Daniel Jasper  }
7510178673f541685cf5067814dfeee2644078e39a9Daniel Jasper
752b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  TokenType determinePlusMinusCaretUsage(const FormatToken &Tok) {
7530bdc6434fa0fea933b6ab566eff751afdba40a2aAlexander Kornienko    const FormatToken *PrevToken = Tok.getPreviousNonComment();
754b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper    if (PrevToken == NULL || PrevToken->Type == TT_CastRParen)
7550178673f541685cf5067814dfeee2644078e39a9Daniel Jasper      return TT_UnaryOperator;
7560178673f541685cf5067814dfeee2644078e39a9Daniel Jasper
7570178673f541685cf5067814dfeee2644078e39a9Daniel Jasper    // Use heuristics to recognize unary operators.
758e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko    if (PrevToken->isOneOf(tok::equal, tok::l_paren, tok::comma, tok::l_square,
759e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko                           tok::question, tok::colon, tok::kw_return,
760e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko                           tok::kw_case, tok::at, tok::l_brace))
7610178673f541685cf5067814dfeee2644078e39a9Daniel Jasper      return TT_UnaryOperator;
7620178673f541685cf5067814dfeee2644078e39a9Daniel Jasper
763ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber    // There can't be two consecutive binary operators.
7640178673f541685cf5067814dfeee2644078e39a9Daniel Jasper    if (PrevToken->Type == TT_BinaryOperator)
7650178673f541685cf5067814dfeee2644078e39a9Daniel Jasper      return TT_UnaryOperator;
7660178673f541685cf5067814dfeee2644078e39a9Daniel Jasper
7670178673f541685cf5067814dfeee2644078e39a9Daniel Jasper    // Fall back to marking the token as binary operator.
7680178673f541685cf5067814dfeee2644078e39a9Daniel Jasper    return TT_BinaryOperator;
7690178673f541685cf5067814dfeee2644078e39a9Daniel Jasper  }
7700178673f541685cf5067814dfeee2644078e39a9Daniel Jasper
7710178673f541685cf5067814dfeee2644078e39a9Daniel Jasper  /// \brief Determine whether ++/-- are pre- or post-increments/-decrements.
772b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  TokenType determineIncrementUsage(const FormatToken &Tok) {
7730bdc6434fa0fea933b6ab566eff751afdba40a2aAlexander Kornienko    const FormatToken *PrevToken = Tok.getPreviousNonComment();
774b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper    if (PrevToken == NULL || PrevToken->Type == TT_CastRParen)
7750178673f541685cf5067814dfeee2644078e39a9Daniel Jasper      return TT_UnaryOperator;
776e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko    if (PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::identifier))
7770178673f541685cf5067814dfeee2644078e39a9Daniel Jasper      return TT_TrailingUnaryOperator;
7780178673f541685cf5067814dfeee2644078e39a9Daniel Jasper
7790178673f541685cf5067814dfeee2644078e39a9Daniel Jasper    return TT_UnaryOperator;
7800178673f541685cf5067814dfeee2644078e39a9Daniel Jasper  }
7814e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper
7828ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper  // FIXME: This is copy&pasted from Sema. Put it in a common place and remove
7838ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper  // duplication.
7848ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper  /// \brief Determine whether the token kind starts a simple-type-specifier.
785b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  bool isSimpleTypeSpecifier(const FormatToken &Tok) const {
786b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek    switch (Tok.Tok.getKind()) {
7878ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper    case tok::kw_short:
7888ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper    case tok::kw_long:
7898ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper    case tok::kw___int64:
7908ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper    case tok::kw___int128:
7918ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper    case tok::kw_signed:
7928ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper    case tok::kw_unsigned:
7938ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper    case tok::kw_void:
7948ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper    case tok::kw_char:
7958ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper    case tok::kw_int:
7968ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper    case tok::kw_half:
7978ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper    case tok::kw_float:
7988ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper    case tok::kw_double:
7998ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper    case tok::kw_wchar_t:
8008ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper    case tok::kw_bool:
8018ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper    case tok::kw___underlying_type:
8028ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper    case tok::annot_typename:
8038ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper    case tok::kw_char16_t:
8048ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper    case tok::kw_char32_t:
8058ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper    case tok::kw_typeof:
8068ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper    case tok::kw_decltype:
80700895106f9ed602af67984ec4d225a0cdc8c12afAlexander Kornienko      return true;
8088ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper    default:
80900895106f9ed602af67984ec4d225a0cdc8c12afAlexander Kornienko      return false;
8108ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper    }
8118ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper  }
8128ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper
8134e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper  SmallVector<Context, 8> Contexts;
8144e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper
8154e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper  AnnotatedLine &Line;
816b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  FormatToken *CurrentToken;
8174e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper  bool KeywordVirtualFound;
8181407bee187d7b964d5293ac8bf4f7a490c78cec6Daniel Jasper  bool NameFound;
8192ca3741a962ded08866596577aaee2f4ab74c955Daniel Jasper  bool AutoFound;
820c2e6d2a4a7fe9dfa7d52a38c6048b7b18e6b591aNico Weber  IdentifierInfo &Ident_in;
82132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper};
82232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
82329f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper/// \brief Parses binary expressions by inserting fake parenthesis based on
82429f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper/// operator precedence.
82529f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasperclass ExpressionParser {
82629f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasperpublic:
8279acb8b4355028887e8cc4aa8f683aceee021a62bDaniel Jasper  ExpressionParser(AnnotatedLine &Line) : Current(Line.First) {
8289acb8b4355028887e8cc4aa8f683aceee021a62bDaniel Jasper    // Skip leading "}", e.g. in "} else if (...) {".
8299acb8b4355028887e8cc4aa8f683aceee021a62bDaniel Jasper    if (Current->is(tok::r_brace))
8309acb8b4355028887e8cc4aa8f683aceee021a62bDaniel Jasper      next();
8319acb8b4355028887e8cc4aa8f683aceee021a62bDaniel Jasper  }
83229f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper
83329f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper  /// \brief Parse expressions with the given operatore precedence.
834237d4c1c785be13656bff6c09e5b7ccd066ff5baDaniel Jasper  void parse(int Precedence = 0) {
835c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper    // Conditional expressions need to be parsed separately for proper nesting.
836c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper    if (Precedence == prec::Conditional + 1) {
837c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper      parseConditionalExpr();
838c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper      return;
839c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper    }
84029f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper    if (Precedence > prec::PointerToMember || Current == NULL)
84129f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper      return;
84229f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper
843b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek    FormatToken *Start = Current;
84429f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper    bool OperatorFound = false;
84529f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper
846237d4c1c785be13656bff6c09e5b7ccd066ff5baDaniel Jasper    while (Current) {
84729f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper      // Consume operators with higher precedence.
848bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper      parse(Precedence + 1);
84929f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper
850237d4c1c785be13656bff6c09e5b7ccd066ff5baDaniel Jasper      int CurrentPrecedence = 0;
851237d4c1c785be13656bff6c09e5b7ccd066ff5baDaniel Jasper      if (Current) {
852237d4c1c785be13656bff6c09e5b7ccd066ff5baDaniel Jasper        if (Current->Type == TT_ConditionalExpr)
853b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper          CurrentPrecedence = 1 + (int)prec::Conditional;
854bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper        else if (Current->is(tok::semi) || Current->Type == TT_InlineASMColon)
855237d4c1c785be13656bff6c09e5b7ccd066ff5baDaniel Jasper          CurrentPrecedence = 1;
856237d4c1c785be13656bff6c09e5b7ccd066ff5baDaniel Jasper        else if (Current->Type == TT_BinaryOperator || Current->is(tok::comma))
857b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper          CurrentPrecedence = 1 + (int)Current->getPrecedence();
858237d4c1c785be13656bff6c09e5b7ccd066ff5baDaniel Jasper      }
859237d4c1c785be13656bff6c09e5b7ccd066ff5baDaniel Jasper
86029f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper      // At the end of the line or when an operator with higher precedence is
86129f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper      // found, insert fake parenthesis and return.
862ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper      if (Current == NULL || Current->closesScope() ||
863237d4c1c785be13656bff6c09e5b7ccd066ff5baDaniel Jasper          (CurrentPrecedence != 0 && CurrentPrecedence < Precedence)) {
864c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper        if (OperatorFound)
865c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper          addFakeParenthesis(Start, prec::Level(Precedence - 1));
86629f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper        return;
86729f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper      }
86829f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper
86929f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper      // Consume scopes: (), [], <> and {}
870ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper      if (Current->opensScope()) {
871ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper        while (Current && !Current->closesScope()) {
87229f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper          next();
87329f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper          parse();
87429f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper        }
87529f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper        next();
87629f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper      } else {
87729f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper        // Operator found.
878237d4c1c785be13656bff6c09e5b7ccd066ff5baDaniel Jasper        if (CurrentPrecedence == Precedence)
87929f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper          OperatorFound = true;
88029f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper
88129f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper        next();
88229f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper      }
88329f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper    }
88429f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper  }
88529f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper
88629f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasperprivate:
887c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper  void addFakeParenthesis(FormatToken *Start, prec::Level Precedence) {
888c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper    Start->FakeLParens.push_back(Precedence);
889c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper    if (Current)
890c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper      ++Current->Previous->FakeRParens;
891c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper  }
892c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper
893c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper  void parseConditionalExpr() {
894c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper    FormatToken *Start = Current;
895c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper    parse(prec::LogicalOr + 1);
896c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper    if (!Current || !Current->is(tok::question))
897c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper      return;
898c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper    next();
899c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper    parse(prec::LogicalOr + 1);
900c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper    if (!Current || Current->Type != TT_ConditionalExpr)
901c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper      return;
902c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper    next();
903c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper    parseConditionalExpr();
904c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper    addFakeParenthesis(Start, prec::Conditional);
905c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper  }
906c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper
90729f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper  void next() {
908d71b15badeecdc049440103ef044f9cdf5e1359cAlexander Kornienko    if (Current)
909d71b15badeecdc049440103ef044f9cdf5e1359cAlexander Kornienko      Current = Current->Next;
910d71b15badeecdc049440103ef044f9cdf5e1359cAlexander Kornienko    while (Current && Current->isTrailingComment())
911b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek      Current = Current->Next;
91229f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper  }
91329f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper
914b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  FormatToken *Current;
91529f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper};
91629f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper
91714e66498781b7d81639bdc48716e09700552ac21Craig Topper} // end anonymous namespace
91814e66498781b7d81639bdc48716e09700552ac21Craig Topper
9198ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jaspervoid TokenAnnotator::annotate(AnnotatedLine &Line) {
92000895106f9ed602af67984ec4d225a0cdc8c12afAlexander Kornienko  AnnotatingParser Parser(Line, Ident_in);
92132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  Line.Type = Parser.parseLine();
92232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  if (Line.Type == LT_Invalid)
92332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return;
92432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
92529f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper  ExpressionParser ExprParser(Line);
92629f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper  ExprParser.parse();
92729f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper
928b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  if (Line.First->Type == TT_ObjCMethodSpecifier)
92932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    Line.Type = LT_ObjCMethodDecl;
930b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  else if (Line.First->Type == TT_ObjCDecl)
93132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    Line.Type = LT_ObjCDecl;
932b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  else if (Line.First->Type == TT_ObjCProperty)
93332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    Line.Type = LT_ObjCProperty;
93432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
935b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  Line.First->SpacesRequiredBefore = 1;
936b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  Line.First->CanBreakBefore = Line.First->MustBreakBefore;
93732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper}
93832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
9398ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jaspervoid TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) {
94000895106f9ed602af67984ec4d225a0cdc8c12afAlexander Kornienko  Line.First->TotalLength = Line.First->CodePointCount;
941b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  if (!Line.First->Next)
9428ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper    return;
943b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  FormatToken *Current = Line.First->Next;
9448ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper  while (Current != NULL) {
945729a743b317d877df3978e88a4a247d2edbf2090Daniel Jasper    if (Current->Type == TT_LineComment)
946729a743b317d877df3978e88a4a247d2edbf2090Daniel Jasper      Current->SpacesRequiredBefore = Style.SpacesBeforeTrailingComments;
947729a743b317d877df3978e88a4a247d2edbf2090Daniel Jasper    else
948729a743b317d877df3978e88a4a247d2edbf2090Daniel Jasper      Current->SpacesRequiredBefore =
949729a743b317d877df3978e88a4a247d2edbf2090Daniel Jasper          spaceRequiredBefore(Line, *Current) ? 1 : 0;
9508ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper
951561211d35b5a2825fba6d0c017044f6896b204fdDaniel Jasper    if (Current->is(tok::comment)) {
952b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek      Current->MustBreakBefore = Current->NewlinesBefore > 0;
953b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek    } else if (Current->Previous->isTrailingComment() ||
9548ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper               (Current->is(tok::string_literal) &&
955b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek                Current->Previous->is(tok::string_literal))) {
9568ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper      Current->MustBreakBefore = true;
957561211d35b5a2825fba6d0c017044f6896b204fdDaniel Jasper    } else if (Current->Previous->IsUnterminatedLiteral) {
958561211d35b5a2825fba6d0c017044f6896b204fdDaniel Jasper      Current->MustBreakBefore = true;
959b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek    } else if (Current->is(tok::lessless) && Current->Next &&
960b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek               Current->Previous->is(tok::string_literal) &&
961b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek               Current->Next->is(tok::string_literal)) {
9628ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper      Current->MustBreakBefore = true;
963b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek    } else if (Current->Previous->ClosesTemplateDeclaration &&
964bbc8776493fc0176d925a5b528e61ee400895047Daniel Jasper               Style.AlwaysBreakTemplateDeclarations) {
965bbc8776493fc0176d925a5b528e61ee400895047Daniel Jasper      Current->MustBreakBefore = true;
96656312023bf62cb40d2e33ea5e14d55c1e42303a7Alexander Kornienko    } else if (Style.AlwaysBreakBeforeMultilineStrings &&
96756312023bf62cb40d2e33ea5e14d55c1e42303a7Alexander Kornienko               Current->is(tok::string_literal) &&
96856312023bf62cb40d2e33ea5e14d55c1e42303a7Alexander Kornienko               Current->Previous->isNot(tok::lessless) &&
96956312023bf62cb40d2e33ea5e14d55c1e42303a7Alexander Kornienko               Current->Previous->Type != TT_InlineASMColon &&
9700bdc6434fa0fea933b6ab566eff751afdba40a2aAlexander Kornienko               Current->getNextNonComment() &&
9710bdc6434fa0fea933b6ab566eff751afdba40a2aAlexander Kornienko               Current->getNextNonComment()->is(tok::string_literal)) {
97256312023bf62cb40d2e33ea5e14d55c1e42303a7Alexander Kornienko      Current->MustBreakBefore = true;
9738ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper    }
9748ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper    Current->CanBreakBefore =
9758ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper        Current->MustBreakBefore || canBreakBefore(Line, *Current);
9768ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper    if (Current->MustBreakBefore)
977b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek      Current->TotalLength = Current->Previous->TotalLength + Style.ColumnLimit;
9788ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper    else
9792a409b62126d8f0b8f5749d5ed435ad2b394b526Daniel Jasper      Current->TotalLength = Current->Previous->TotalLength +
9802a409b62126d8f0b8f5749d5ed435ad2b394b526Daniel Jasper                             Current->CodePointCount +
9812a409b62126d8f0b8f5749d5ed435ad2b394b526Daniel Jasper                             Current->SpacesRequiredBefore;
9828ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper    // FIXME: Only calculate this if CanBreakBefore is true once static
9838ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper    // initializers etc. are sorted out.
9848ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper    // FIXME: Move magic numbers to a better place.
9858ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper    Current->SplitPenalty =
9868ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper        20 * Current->BindingStrength + splitPenalty(Line, *Current);
9878ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper
988b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek    Current = Current->Next;
98932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  }
990bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper
991e573c3f7fc40e813559ab4ff1e7eec4f66f1a50fManuel Klimek  calculateUnbreakableTailLengths(Line);
992bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper  DEBUG({
993bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper    printDebugInfo(Line);
994bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper  });
99532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper}
99632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
997e573c3f7fc40e813559ab4ff1e7eec4f66f1a50fManuel Klimekvoid TokenAnnotator::calculateUnbreakableTailLengths(AnnotatedLine &Line) {
998e573c3f7fc40e813559ab4ff1e7eec4f66f1a50fManuel Klimek  unsigned UnbreakableTailLength = 0;
999b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  FormatToken *Current = Line.Last;
1000e573c3f7fc40e813559ab4ff1e7eec4f66f1a50fManuel Klimek  while (Current != NULL) {
1001e573c3f7fc40e813559ab4ff1e7eec4f66f1a50fManuel Klimek    Current->UnbreakableTailLength = UnbreakableTailLength;
1002e573c3f7fc40e813559ab4ff1e7eec4f66f1a50fManuel Klimek    if (Current->CanBreakBefore ||
1003e573c3f7fc40e813559ab4ff1e7eec4f66f1a50fManuel Klimek        Current->isOneOf(tok::comment, tok::string_literal)) {
1004e573c3f7fc40e813559ab4ff1e7eec4f66f1a50fManuel Klimek      UnbreakableTailLength = 0;
1005e573c3f7fc40e813559ab4ff1e7eec4f66f1a50fManuel Klimek    } else {
1006e573c3f7fc40e813559ab4ff1e7eec4f66f1a50fManuel Klimek      UnbreakableTailLength +=
100700895106f9ed602af67984ec4d225a0cdc8c12afAlexander Kornienko          Current->CodePointCount + Current->SpacesRequiredBefore;
1008e573c3f7fc40e813559ab4ff1e7eec4f66f1a50fManuel Klimek    }
1009b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek    Current = Current->Previous;
1010e573c3f7fc40e813559ab4ff1e7eec4f66f1a50fManuel Klimek  }
1011e573c3f7fc40e813559ab4ff1e7eec4f66f1a50fManuel Klimek}
1012e573c3f7fc40e813559ab4ff1e7eec4f66f1a50fManuel Klimek
10138ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasperunsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line,
1014b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek                                      const FormatToken &Tok) {
1015b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  const FormatToken &Left = *Tok.Previous;
1016b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  const FormatToken &Right = Tok;
101732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
10185ad390d27f8f7cb6628bc2c32beba4d25bc2718bDaniel Jasper  if (Left.is(tok::semi))
10195ad390d27f8f7cb6628bc2c32beba4d25bc2718bDaniel Jasper    return 0;
10205ad390d27f8f7cb6628bc2c32beba4d25bc2718bDaniel Jasper  if (Left.is(tok::comma))
10215ad390d27f8f7cb6628bc2c32beba4d25bc2718bDaniel Jasper    return 1;
1022011c35dabb4c8abcb7389d8fbc6316f8f23576abDaniel Jasper  if (Right.is(tok::l_square))
1023011c35dabb4c8abcb7389d8fbc6316f8f23576abDaniel Jasper    return 150;
10245ad390d27f8f7cb6628bc2c32beba4d25bc2718bDaniel Jasper
10256561f6a13b79ed752748ede590792191edf78ce8Daniel Jasper  if (Right.Type == TT_StartOfName || Right.is(tok::kw_operator)) {
1026b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek    if (Line.First->is(tok::kw_for) && Right.PartOfMultiVariableDeclStmt)
10273c08a818a6ac9115fe8880af9bbf5a0a87bdffaaDaniel Jasper      return 3;
1028c18cff311118fc6a30929468fc82b2b35cbd7fbfDaniel Jasper    if (Left.Type == TT_StartOfName)
1029c18cff311118fc6a30929468fc82b2b35cbd7fbfDaniel Jasper      return 20;
10303c08a818a6ac9115fe8880af9bbf5a0a87bdffaaDaniel Jasper    else if (Line.MightBeFunctionDecl && Right.BindingStrength == 1)
10313c08a818a6ac9115fe8880af9bbf5a0a87bdffaaDaniel Jasper      // FIXME: Clean up hack of using BindingStrength to find top-level names.
10323c08a818a6ac9115fe8880af9bbf5a0a87bdffaaDaniel Jasper      return Style.PenaltyReturnTypeOnItsOwnLine;
10333c08a818a6ac9115fe8880af9bbf5a0a87bdffaaDaniel Jasper    else
10341407bee187d7b964d5293ac8bf4f7a490c78cec6Daniel Jasper      return 200;
10353c08a818a6ac9115fe8880af9bbf5a0a87bdffaaDaniel Jasper  }
103632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  if (Left.is(tok::equal) && Right.is(tok::l_brace))
103732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return 150;
1038198c8bfee0b33ab0ed0c54224f460868f1c18e95Daniel Jasper  if (Left.Type == TT_CastRParen)
1039198c8bfee0b33ab0ed0c54224f460868f1c18e95Daniel Jasper    return 100;
104032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  if (Left.is(tok::coloncolon))
104132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return 500;
10426b119d63f5036344acd4e00a6ff2b3c72f26966fDaniel Jasper  if (Left.isOneOf(tok::kw_class, tok::kw_struct))
10436b119d63f5036344acd4e00a6ff2b3c72f26966fDaniel Jasper    return 5000;
104432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
10456cabab48dacc1317821f8f078ed2d4c603b67affDaniel Jasper  if (Left.Type == TT_RangeBasedForLoopColon ||
10466cabab48dacc1317821f8f078ed2d4c603b67affDaniel Jasper      Left.Type == TT_InheritanceColon)
104784a1a63b034744b68a27ec171dca5b1b7cf303f0Daniel Jasper    return 2;
104832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
10495ad390d27f8f7cb6628bc2c32beba4d25bc2718bDaniel Jasper  if (Right.isOneOf(tok::arrow, tok::period) &&
10505ad390d27f8f7cb6628bc2c32beba4d25bc2718bDaniel Jasper      Right.Type != TT_DesignatedInitializerPeriod) {
1051515f65df40624a767bc8763a0b6b678146b8e3c9Daniel Jasper    if (Line.Type == LT_BuilderTypeCall)
10526a365aaa057a8c445d25344c0433726c752b3e7dDaniel Jasper      return prec::PointerToMember;
1053e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko    if (Left.isOneOf(tok::r_paren, tok::r_square) && Left.MatchingParen &&
1054e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko        Left.MatchingParen->ParameterCount > 0)
1055518ee34467c0722e253a58efea20456e96aa5802Daniel Jasper      return 20; // Should be smaller than breaking at a nested comma.
105632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return 150;
105732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  }
105832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
105920a0f8cff96505abb65233a2eaf3af3cd8536cd2Daniel Jasper  // Breaking before a trailing 'const' or not-function-like annotation is bad.
106020a0f8cff96505abb65233a2eaf3af3cd8536cd2Daniel Jasper  if (Left.is(tok::r_paren) &&
106120a0f8cff96505abb65233a2eaf3af3cd8536cd2Daniel Jasper      (Right.is(tok::kw_const) || (Right.is(tok::identifier) && Right.Next &&
106220a0f8cff96505abb65233a2eaf3af3cd8536cd2Daniel Jasper                                   Right.Next->isNot(tok::l_paren))))
10635ad72bb8eb8e5cc4c061ccd28632295213d319dbDaniel Jasper    return 150;
10645ad72bb8eb8e5cc4c061ccd28632295213d319dbDaniel Jasper
106532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  // In for-loops, prefer breaking at ',' and ';'.
1066b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  if (Line.First->is(tok::kw_for) && Left.is(tok::equal))
10677d81281fc39f6d40d86be6600adba13c05b4a639Daniel Jasper    return 4;
106832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
106932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  // In Objective-C method expressions, prefer breaking before "param:" over
107032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  // breaking after it.
107163d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper  if (Right.Type == TT_ObjCSelectorName)
107232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return 0;
107363d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper  if (Left.is(tok::colon) && Left.Type == TT_ObjCMethodExpr)
107432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return 20;
107532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
10761407bee187d7b964d5293ac8bf4f7a490c78cec6Daniel Jasper  if (Left.is(tok::l_paren) && Line.MightBeFunctionDecl)
10771407bee187d7b964d5293ac8bf4f7a490c78cec6Daniel Jasper    return 100;
1078ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper  if (Left.opensScope())
107964f092865c01c72ecb9e380432e241f3af55c249Daniel Jasper    return Left.ParameterCount > 1 ? prec::Comma : 20;
108032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
10814e8a7b4a95962f63a938c0d21c9aca0a51b78345Daniel Jasper  if (Right.is(tok::lessless)) {
10824e8a7b4a95962f63a938c0d21c9aca0a51b78345Daniel Jasper    if (Left.is(tok::string_literal)) {
108300895106f9ed602af67984ec4d225a0cdc8c12afAlexander Kornienko      StringRef Content = Left.TokenText;
1084bfa1edd8247b80e951a570ff2486fe5fa9898c41Daniel Jasper      Content = Content.drop_back(1).drop_front(1).trim();
1085bfa1edd8247b80e951a570ff2486fe5fa9898c41Daniel Jasper      if (Content.size() > 1 &&
1086bfa1edd8247b80e951a570ff2486fe5fa9898c41Daniel Jasper          (Content.back() == ':' || Content.back() == '='))
10879637dda705e39110bfff66742542a58dd2470ad2Daniel Jasper        return 25;
10884e8a7b4a95962f63a938c0d21c9aca0a51b78345Daniel Jasper    }
10890c368787d9d1f92a3408b71b3f074a06edaa6bdeDaniel Jasper    return 1; // Breaking at a << is really cheap.
10904e8a7b4a95962f63a938c0d21c9aca0a51b78345Daniel Jasper  }
109132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  if (Left.Type == TT_ConditionalExpr)
1092518ee34467c0722e253a58efea20456e96aa5802Daniel Jasper    return prec::Conditional;
1093b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  prec::Level Level = Left.getPrecedence();
109432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
109532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  if (Level != prec::Unknown)
109632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return Level;
1097248497199bc56e86d1c089beb9529f3b3d77abb1Daniel Jasper
109832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  return 3;
109932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper}
110032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
11018ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasperbool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
1102b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek                                          const FormatToken &Left,
1103b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek                                          const FormatToken &Right) {
110432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  if (Right.is(tok::hashhash))
110532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return Left.is(tok::hash);
1106e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko  if (Left.isOneOf(tok::hashhash, tok::hash))
110732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return Right.is(tok::hash);
1108e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko  if (Right.isOneOf(tok::r_paren, tok::semi, tok::comma))
110932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return false;
111032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  if (Right.is(tok::less) &&
111132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      (Left.is(tok::kw_template) ||
111232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper       (Line.Type == LT_ObjCDecl && Style.ObjCSpaceBeforeProtocolList)))
111332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return true;
111432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  if (Left.is(tok::arrow) || Right.is(tok::arrow))
111532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return false;
1116e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko  if (Left.isOneOf(tok::exclaim, tok::tilde))
111732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return false;
111832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  if (Left.is(tok::at) &&
1119e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko      Right.isOneOf(tok::identifier, tok::string_literal, tok::char_constant,
1120e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko                    tok::numeric_constant, tok::l_paren, tok::l_brace,
1121e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko                    tok::kw_true, tok::kw_false))
112232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return false;
112332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  if (Left.is(tok::coloncolon))
112432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return false;
112532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  if (Right.is(tok::coloncolon))
1126e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko    return !Left.isOneOf(tok::identifier, tok::greater, tok::l_paren);
1127e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko  if (Left.is(tok::less) || Right.isOneOf(tok::greater, tok::less))
112832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return false;
1129c47d7f1237b022eabbbdcebf77506e8a81aa54bdDaniel Jasper  if (Right.is(tok::ellipsis))
1130c47d7f1237b022eabbbdcebf77506e8a81aa54bdDaniel Jasper    return false;
11313fd9ccdd9f8d259bcf518e7056cfd419d992e984Alexander Kornienko  if (Right.Type == TT_PointerOrReference)
1132b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek    return Left.Tok.isLiteral() ||
11333fd9ccdd9f8d259bcf518e7056cfd419d992e984Alexander Kornienko           ((Left.Type != TT_PointerOrReference) && Left.isNot(tok::l_paren) &&
11343fd9ccdd9f8d259bcf518e7056cfd419d992e984Alexander Kornienko            !Style.PointerBindsToType);
11353ff4a2fea4aa6e5182b7799ccb4352e56961a212Daniel Jasper  if (Right.Type == TT_FunctionTypeLParen && Left.isNot(tok::l_paren) &&
1136395228fdc343df39c2507e414dc1406a185c6d37Daniel Jasper      (Left.Type != TT_PointerOrReference || Style.PointerBindsToType))
1137395228fdc343df39c2507e414dc1406a185c6d37Daniel Jasper    return true;
11383fd9ccdd9f8d259bcf518e7056cfd419d992e984Alexander Kornienko  if (Left.Type == TT_PointerOrReference)
11393a1847e0a1810a0b1b963182abc59114cc5ff53dDaniel Jasper    return Right.Tok.isLiteral() || Right.Type == TT_BlockComment ||
11409322aaee900b872c98f8fc10b38a231cb1e9b57aDaniel Jasper           ((Right.Type != TT_PointerOrReference) &&
114181d2d38d2d774a2550fa0d2efffa707e7a53b39cDaniel Jasper            Right.isNot(tok::l_paren) && Style.PointerBindsToType &&
1142b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek            Left.Previous &&
1143b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek            !Left.Previous->isOneOf(tok::l_paren, tok::coloncolon));
114432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  if (Right.is(tok::star) && Left.is(tok::l_paren))
114532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return false;
1146051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber  if (Left.is(tok::l_square))
1147051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber    return Left.Type == TT_ObjCArrayLiteral && Right.isNot(tok::r_square);
1148051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber  if (Right.is(tok::r_square))
1149051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber    return Right.Type == TT_ObjCArrayLiteral;
115032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  if (Right.is(tok::l_square) && Right.Type != TT_ObjCMethodExpr)
115132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return false;
115232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  if (Left.is(tok::colon))
115332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return Left.Type != TT_ObjCMethodExpr;
115432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  if (Right.is(tok::colon))
115532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return Right.Type != TT_ObjCMethodExpr;
115632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  if (Left.is(tok::l_paren))
115732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return false;
115832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  if (Right.is(tok::l_paren)) {
1159e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko    return Line.Type == LT_ObjCDecl ||
1160e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko           Left.isOneOf(tok::kw_if, tok::kw_for, tok::kw_while, tok::kw_switch,
1161e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko                        tok::kw_return, tok::kw_catch, tok::kw_new,
1162454cb70f9470dc37d0c0646012877d64fb1e73d7Daniel Jasper                        tok::kw_delete, tok::semi);
116332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  }
1164b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  if (Left.is(tok::at) && Right.Tok.getObjCKeywordID() != tok::objc_not_keyword)
116532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return false;
116632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  if (Left.is(tok::l_brace) && Right.is(tok::r_brace))
11672424eefa6936ec2dc35188e19c99e2f85428b52eDaniel Jasper    return false; // No spaces in "{}".
11682424eefa6936ec2dc35188e19c99e2f85428b52eDaniel Jasper  if (Left.is(tok::l_brace) || Right.is(tok::r_brace))
1169b5dc3f4f53981b681a565cdf1d49f18e817541ffDaniel Jasper    return !Style.Cpp11BracedListStyle;
11701bee0738b67b784f08d5e2f8351920260c9cfb1dDaniel Jasper  if (Right.Type == TT_UnaryOperator)
11711bee0738b67b784f08d5e2f8351920260c9cfb1dDaniel Jasper    return !Left.isOneOf(tok::l_paren, tok::l_square, tok::at) &&
11721bee0738b67b784f08d5e2f8351920260c9cfb1dDaniel Jasper           (Left.isNot(tok::colon) || Left.Type != TT_ObjCMethodExpr);
1173ce93356e2719d2992763ea747b65beada99f4c9bDaniel Jasper  if (Left.isOneOf(tok::identifier, tok::greater, tok::r_square) &&
11740bdc6434fa0fea933b6ab566eff751afdba40a2aAlexander Kornienko      Right.is(tok::l_brace) && Right.getNextNonComment())
117532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return false;
11765ad390d27f8f7cb6628bc2c32beba4d25bc2718bDaniel Jasper  if (Left.is(tok::period) || Right.is(tok::period))
11775ad390d27f8f7cb6628bc2c32beba4d25bc2718bDaniel Jasper    return false;
1178861576b8019392f15c803ac14a4bc31fbd93aab2Nico Weber  if (Left.Type == TT_BlockComment && Left.TokenText.endswith("=*/"))
1179861576b8019392f15c803ac14a4bc31fbd93aab2Nico Weber    return false;
118032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  return true;
118132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper}
118232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
11838ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasperbool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
1184b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek                                         const FormatToken &Tok) {
1185b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  if (Tok.Tok.getIdentifierInfo() && Tok.Previous->Tok.getIdentifierInfo())
11862b4c924f85e156d66c01b3f16c850892c47dcc7aDaniel Jasper    return true; // Never ever merge two identifiers.
118732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  if (Line.Type == LT_ObjCMethodDecl) {
1188b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek    if (Tok.Previous->Type == TT_ObjCMethodSpecifier)
118932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      return true;
1190b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek    if (Tok.Previous->is(tok::r_paren) && Tok.is(tok::identifier))
119132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      // Don't space between ')' and <id>
119232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      return false;
119332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  }
119432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  if (Line.Type == LT_ObjCProperty &&
1195b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek      (Tok.is(tok::equal) || Tok.Previous->is(tok::equal)))
119632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return false;
119732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
11982ca3741a962ded08866596577aaee2f4ab74c955Daniel Jasper  if (Tok.Type == TT_TrailingReturnArrow ||
11992ca3741a962ded08866596577aaee2f4ab74c955Daniel Jasper      Tok.Previous->Type == TT_TrailingReturnArrow)
12002ca3741a962ded08866596577aaee2f4ab74c955Daniel Jasper    return true;
1201b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  if (Tok.Previous->is(tok::comma))
120232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return true;
12039c3c7b3130bc72b3f50703c11b85152b1264fc90Daniel Jasper  if (Tok.is(tok::comma))
12049c3c7b3130bc72b3f50703c11b85152b1264fc90Daniel Jasper    return false;
120532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  if (Tok.Type == TT_CtorInitializerColon || Tok.Type == TT_ObjCBlockLParen)
120632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return true;
1207b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  if (Tok.Previous->Tok.is(tok::kw_operator))
12082b4c924f85e156d66c01b3f16c850892c47dcc7aDaniel Jasper    return false;
12092b4c924f85e156d66c01b3f16c850892c47dcc7aDaniel Jasper  if (Tok.Type == TT_OverloadedOperatorLParen)
121032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return false;
121132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  if (Tok.is(tok::colon))
1212b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek    return !Line.First->isOneOf(tok::kw_case, tok::kw_default) &&
12130bdc6434fa0fea933b6ab566eff751afdba40a2aAlexander Kornienko           Tok.getNextNonComment() != NULL && Tok.Type != TT_ObjCMethodExpr;
1214b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  if (Tok.Previous->Type == TT_UnaryOperator ||
1215b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek      Tok.Previous->Type == TT_CastRParen)
121632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return false;
1217b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  if (Tok.Previous->is(tok::greater) && Tok.is(tok::greater)) {
121829f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper    return Tok.Type == TT_TemplateCloser &&
1219b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek           Tok.Previous->Type == TT_TemplateCloser &&
122029f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper           Style.Standard != FormatStyle::LS_Cpp11;
122132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  }
122254a38bd5cf243310290f34b43fc940a498a00f90Alexander Kornienko  if (Tok.isOneOf(tok::arrowstar, tok::periodstar) ||
1223b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek      Tok.Previous->isOneOf(tok::arrowstar, tok::periodstar))
12249c3c7b3130bc72b3f50703c11b85152b1264fc90Daniel Jasper    return false;
1225b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  if (Tok.Type == TT_BinaryOperator || Tok.Previous->Type == TT_BinaryOperator)
122632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return true;
1227b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  if (Tok.Previous->Type == TT_TemplateCloser && Tok.is(tok::l_paren))
122832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return false;
1229b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  if (Tok.is(tok::less) && Line.First->is(tok::hash))
123032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return true;
123132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  if (Tok.Type == TT_TrailingUnaryOperator)
123232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return false;
1233b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  return spaceRequiredBetween(Line, *Tok.Previous, Tok);
123432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper}
123532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
12368ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasperbool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
1237b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek                                    const FormatToken &Right) {
1238b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  const FormatToken &Left = *Right.Previous;
12396561f6a13b79ed752748ede590792191edf78ce8Daniel Jasper  if (Right.Type == TT_StartOfName || Right.is(tok::kw_operator))
124032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return true;
1241f2ff8126e9e9df368f31b1f968d8fc80f99809b3Nico Weber  if (Right.is(tok::colon) &&
1242f2ff8126e9e9df368f31b1f968d8fc80f99809b3Nico Weber      (Right.Type == TT_ObjCDictLiteral || Right.Type == TT_ObjCMethodExpr))
124332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return false;
1244f2ff8126e9e9df368f31b1f968d8fc80f99809b3Nico Weber  if (Left.is(tok::colon) &&
1245f2ff8126e9e9df368f31b1f968d8fc80f99809b3Nico Weber      (Left.Type == TT_ObjCDictLiteral || Left.Type == TT_ObjCMethodExpr))
124632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return true;
124763d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper  if (Right.Type == TT_ObjCSelectorName)
124832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return true;
124932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  if (Left.ClosesTemplateDeclaration)
125032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return true;
125132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  if (Right.Type == TT_ConditionalExpr || Right.is(tok::question))
125232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return true;
12536cabab48dacc1317821f8f078ed2d4c603b67affDaniel Jasper  if (Right.Type == TT_RangeBasedForLoopColon ||
125427b91cc046f580fbe825f15b3e27f1b6407ee3e3Daniel Jasper      Right.Type == TT_OverloadedOperatorLParen)
12556cabab48dacc1317821f8f078ed2d4c603b67affDaniel Jasper    return false;
1256c194c95036b7bf1281a6f2ed683f7c85ee5d2c20Daniel Jasper  if (Left.Type == TT_RangeBasedForLoopColon)
125732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return true;
12587d81281fc39f6d40d86be6600adba13c05b4a639Daniel Jasper  if (Right.Type == TT_RangeBasedForLoopColon)
12597d81281fc39f6d40d86be6600adba13c05b4a639Daniel Jasper    return false;
126032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  if (Left.Type == TT_PointerOrReference || Left.Type == TT_TemplateCloser ||
126132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      Left.Type == TT_UnaryOperator || Left.Type == TT_ConditionalExpr ||
1262e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko      Left.isOneOf(tok::question, tok::kw_operator))
126332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return false;
126432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  if (Left.is(tok::equal) && Line.Type == LT_VirtualFunctionDecl)
126532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return false;
1266198c8bfee0b33ab0ed0c54224f460868f1c18e95Daniel Jasper  if (Left.Previous) {
1267198c8bfee0b33ab0ed0c54224f460868f1c18e95Daniel Jasper    if (Left.is(tok::l_paren) && Right.is(tok::l_paren) &&
1268198c8bfee0b33ab0ed0c54224f460868f1c18e95Daniel Jasper        Left.Previous->is(tok::kw___attribute))
1269198c8bfee0b33ab0ed0c54224f460868f1c18e95Daniel Jasper      return false;
12702ca3741a962ded08866596577aaee2f4ab74c955Daniel Jasper    if (Left.is(tok::l_paren) && (Left.Previous->Type == TT_BinaryOperator ||
12712ca3741a962ded08866596577aaee2f4ab74c955Daniel Jasper                                  Left.Previous->is(tok::r_paren)))
1272198c8bfee0b33ab0ed0c54224f460868f1c18e95Daniel Jasper      return false;
1273198c8bfee0b33ab0ed0c54224f460868f1c18e95Daniel Jasper  }
127432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
127565d2c3829494d254039683c73f95843c29c661b4Daniel Jasper  if (Right.isTrailingComment())
127632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    // We rely on MustBreakBefore being set correctly here as we should not
127732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    // change the "binding" behavior of a comment.
127832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return false;
127932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
12805ad72bb8eb8e5cc4c061ccd28632295213d319dbDaniel Jasper  // We only break before r_brace if there was a corresponding break before
12815ad72bb8eb8e5cc4c061ccd28632295213d319dbDaniel Jasper  // the l_brace, which is tracked by BreakBeforeClosingBrace.
12825ad72bb8eb8e5cc4c061ccd28632295213d319dbDaniel Jasper  if (Right.isOneOf(tok::r_brace, tok::r_paren, tok::greater))
12835ad72bb8eb8e5cc4c061ccd28632295213d319dbDaniel Jasper    return false;
12845ad72bb8eb8e5cc4c061ccd28632295213d319dbDaniel Jasper
128532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  // Allow breaking after a trailing 'const', e.g. after a method declaration,
128632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  // unless it is follow by ';', '{' or '='.
1287b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  if (Left.is(tok::kw_const) && Left.Previous != NULL &&
1288b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek      Left.Previous->is(tok::r_paren))
1289e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko    return !Right.isOneOf(tok::l_brace, tok::semi, tok::equal);
129032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
12918ef19a22956defa392df46c79e2d499ab7b16647Daniel Jasper  if (Right.is(tok::kw___attribute))
12928ef19a22956defa392df46c79e2d499ab7b16647Daniel Jasper    return true;
12938ef19a22956defa392df46c79e2d499ab7b16647Daniel Jasper
12943a204418482c9ae70ad482e781132c54306c3aa6Daniel Jasper  if (Left.is(tok::identifier) && Right.is(tok::string_literal))
12953a204418482c9ae70ad482e781132c54306c3aa6Daniel Jasper    return true;
1296ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper  return (Left.isBinaryOperator() && Left.isNot(tok::lessless)) ||
12976b119d63f5036344acd4e00a6ff2b3c72f26966fDaniel Jasper         Left.isOneOf(tok::comma, tok::coloncolon, tok::semi, tok::l_brace,
12986b119d63f5036344acd4e00a6ff2b3c72f26966fDaniel Jasper                      tok::kw_class, tok::kw_struct) ||
1299e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko         Right.isOneOf(tok::lessless, tok::arrow, tok::period, tok::colon) ||
1300198c8bfee0b33ab0ed0c54224f460868f1c18e95Daniel Jasper         (Left.is(tok::r_paren) &&
1301e033e87cbe77341777100093f8066167888d4440Daniel Jasper          Right.isOneOf(tok::identifier, tok::kw_const, tok::kw___attribute)) ||
130232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper         (Left.is(tok::l_paren) && !Right.is(tok::r_paren)) ||
1303011c35dabb4c8abcb7389d8fbc6316f8f23576abDaniel Jasper         Right.is(tok::l_square);
130432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper}
130532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
1306bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jaspervoid TokenAnnotator::printDebugInfo(const AnnotatedLine &Line) {
1307bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper  llvm::errs() << "AnnotatedTokens:\n";
1308b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  const FormatToken *Tok = Line.First;
1309bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper  while (Tok) {
1310b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek    llvm::errs() << " M=" << Tok->MustBreakBefore
1311c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper                 << " C=" << Tok->CanBreakBefore << " T=" << Tok->Type
1312c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper                 << " S=" << Tok->SpacesRequiredBefore
1313c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper                 << " P=" << Tok->SplitPenalty << " Name=" << Tok->Tok.getName()
1314c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper                 << " PPK=" << Tok->PackingKind << " FakeLParens=";
1315bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper    for (unsigned i = 0, e = Tok->FakeLParens.size(); i != e; ++i)
1316bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper      llvm::errs() << Tok->FakeLParens[i] << "/";
1317bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper    llvm::errs() << " FakeRParens=" << Tok->FakeRParens << "\n";
1318b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek    Tok = Tok->Next;
1319bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper  }
1320bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper  llvm::errs() << "----\n";
1321bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper}
1322bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper
132332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} // namespace format
132432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} // namespace clang
1325