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