TokenAnnotator.cpp revision 3c6aea7ac63265c769b5fe09e213ab1c4cee111e
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: 32d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper AnnotatingParser(const FormatStyle &Style, AnnotatedLine &Line, 33d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper IdentifierInfo &Ident_in) 34d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper : Style(Style), Line(Line), CurrentToken(Line.First), 35d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper KeywordVirtualFound(false), NameFound(false), AutoFound(false), 36d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper Ident_in(Ident_in) { 372726877196b41b922f10f794801b313980e1a8adNico Weber Contexts.push_back(Context(tok::unknown, 1, /*IsExpression=*/false)); 3832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 3932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 4095e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weberprivate: 4132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool parseAngle() { 4232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken == NULL) 4332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 44923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper ScopedContextCreator ContextCreator(*this, tok::less, 10); 45b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek FormatToken *Left = CurrentToken->Previous; 464e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().IsExpression = false; 4732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper while (CurrentToken != NULL) { 4832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::greater)) { 4932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left->MatchingParen = CurrentToken; 5032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->MatchingParen = Left; 5132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->Type = TT_TemplateCloser; 5232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 5332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 5432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 55e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko if (CurrentToken->isOneOf(tok::r_paren, tok::r_square, tok::r_brace, 565d823e3a00a3e21a0823288e6dee26a93758332bDaniel Jasper tok::question, tok::colon)) 575d823e3a00a3e21a0823288e6dee26a93758332bDaniel Jasper return false; 580348be0c78781c5ddb8c271976812705410c731aDaniel Jasper // If a && or || is found and interpreted as a binary operator, this set 5915f33f03e742fb6567e4789996fa0391a8e18068Daniel Jasper // of angles is likely part of something like "a < b && c > d". If the 600348be0c78781c5ddb8c271976812705410c731aDaniel Jasper // angles are inside an expression, the ||/&& might also be a binary 610348be0c78781c5ddb8c271976812705410c731aDaniel Jasper // operator that was misinterpreted because we are parsing template 620348be0c78781c5ddb8c271976812705410c731aDaniel Jasper // parameters. 630348be0c78781c5ddb8c271976812705410c731aDaniel Jasper // FIXME: This is getting out of hand, write a decent parser. 64b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek if (CurrentToken->Previous->isOneOf(tok::pipepipe, tok::ampamp) && 650348be0c78781c5ddb8c271976812705410c731aDaniel Jasper (CurrentToken->Previous->Type == TT_BinaryOperator || 660348be0c78781c5ddb8c271976812705410c731aDaniel Jasper Contexts[Contexts.size() - 2].IsExpression) && 67b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek Line.First->isNot(tok::kw_template)) 6832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 699fc56f2636137fcde8acb38865555ed6c7b84dfdDaniel Jasper updateParameterCount(Left, CurrentToken); 7032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!consumeToken()) 7132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 7232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 7332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 7432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 7532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 7632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool parseParens(bool LookForDecls = false) { 7732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken == NULL) 7832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 79923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper ScopedContextCreator ContextCreator(*this, tok::l_paren, 1); 804e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper 814e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper // FIXME: This is a bit of a hack. Do better. 824e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().ColonIsForRangeExpr = 834e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.size() == 2 && Contexts[0].ColonIsForRangeExpr; 844e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper 8532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool StartsObjCMethodExpr = false; 86b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek FormatToken *Left = CurrentToken->Previous; 8732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::caret)) { 8832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // ^( starts a block. 8932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left->Type = TT_ObjCBlockLParen; 90b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek } else if (FormatToken *MaybeSel = Left->Previous) { 9132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // @selector( starts a selector. 92b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek if (MaybeSel->isObjCAtKeyword(tok::objc_selector) && MaybeSel->Previous && 93b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek MaybeSel->Previous->is(tok::at)) { 9432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper StartsObjCMethodExpr = true; 9532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 9632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 9732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 98b644dd68d3d7261ceb8823595290439dc65530b1Daniel Jasper if (Left->Previous && Left->Previous->isOneOf(tok::kw_static_assert, 99363193b1bd4d9e0f07d361113157b9d4f229f212Daniel Jasper tok::kw_if, tok::kw_while)) { 100363193b1bd4d9e0f07d361113157b9d4f229f212Daniel Jasper // static_assert, if and while usually contain expressions. 101b7000ca629da16164f0073f5a7f9459ddf5ba281Daniel Jasper Contexts.back().IsExpression = true; 102363193b1bd4d9e0f07d361113157b9d4f229f212Daniel Jasper } else if (Left->Previous && Left->Previous->is(tok::r_square) && 103363193b1bd4d9e0f07d361113157b9d4f229f212Daniel Jasper Left->Previous->MatchingParen && 104363193b1bd4d9e0f07d361113157b9d4f229f212Daniel Jasper Left->Previous->MatchingParen->Type == TT_LambdaLSquare) { 105363193b1bd4d9e0f07d361113157b9d4f229f212Daniel Jasper // This is a parameter list of a lambda expression. 106363193b1bd4d9e0f07d361113157b9d4f229f212Daniel Jasper Contexts.back().IsExpression = false; 107363193b1bd4d9e0f07d361113157b9d4f229f212Daniel Jasper } 108b7000ca629da16164f0073f5a7f9459ddf5ba281Daniel Jasper 1094e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper if (StartsObjCMethodExpr) { 1104e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().ColonIsObjCMethodExpr = true; 1114e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Left->Type = TT_ObjCMethodExpr; 1124e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper } 11332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 114431f5918281dd1f178bf838b7a47ab1d11c52961Daniel Jasper bool MightBeFunctionType = CurrentToken->is(tok::star); 115c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper bool HasMultipleLines = false; 116c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper bool HasMultipleParametersOnALine = false; 11732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper while (CurrentToken != NULL) { 11832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // LookForDecls is set when "if (" has been seen. Check for 11932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // 'identifier' '*' 'identifier' followed by not '=' -- this 12032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // '*' has to be a binary operator but determineStarAmpUsage() will 12132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // categorize it as an unary operator, so set the right type here. 122b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek if (LookForDecls && CurrentToken->Next) { 1230bdc6434fa0fea933b6ab566eff751afdba40a2aAlexander Kornienko FormatToken *Prev = CurrentToken->getPreviousNonComment(); 1242785b9aabcb2c3fd6f7dd8b63d3cd3d4b9bca284Alexander Kornienko if (Prev) { 1250bdc6434fa0fea933b6ab566eff751afdba40a2aAlexander Kornienko FormatToken *PrevPrev = Prev->getPreviousNonComment(); 1262785b9aabcb2c3fd6f7dd8b63d3cd3d4b9bca284Alexander Kornienko FormatToken *Next = CurrentToken->Next; 1272785b9aabcb2c3fd6f7dd8b63d3cd3d4b9bca284Alexander Kornienko if (PrevPrev && PrevPrev->is(tok::identifier) && 1282785b9aabcb2c3fd6f7dd8b63d3cd3d4b9bca284Alexander Kornienko Prev->isOneOf(tok::star, tok::amp, tok::ampamp) && 1292785b9aabcb2c3fd6f7dd8b63d3cd3d4b9bca284Alexander Kornienko CurrentToken->is(tok::identifier) && Next->isNot(tok::equal)) { 1302785b9aabcb2c3fd6f7dd8b63d3cd3d4b9bca284Alexander Kornienko Prev->Type = TT_BinaryOperator; 1312785b9aabcb2c3fd6f7dd8b63d3cd3d4b9bca284Alexander Kornienko LookForDecls = false; 1322785b9aabcb2c3fd6f7dd8b63d3cd3d4b9bca284Alexander Kornienko } 13332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 13432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 13532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 13653352600b7370b1d33b9fde1adda207fd9d7dcd1Daniel Jasper if (CurrentToken->Previous->Type == TT_PointerOrReference && 13753352600b7370b1d33b9fde1adda207fd9d7dcd1Daniel Jasper CurrentToken->Previous->Previous->isOneOf(tok::l_paren, 13853352600b7370b1d33b9fde1adda207fd9d7dcd1Daniel Jasper tok::coloncolon)) 13953352600b7370b1d33b9fde1adda207fd9d7dcd1Daniel Jasper MightBeFunctionType = true; 14032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::r_paren)) { 141b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek if (MightBeFunctionType && CurrentToken->Next && 142e7d3bff31e3ef4fea1e2a5a7cd5441b6b0752e3fDaniel Jasper (CurrentToken->Next->is(tok::l_paren) || 143e7d3bff31e3ef4fea1e2a5a7cd5441b6b0752e3fDaniel Jasper (CurrentToken->Next->is(tok::l_square) && 144e7d3bff31e3ef4fea1e2a5a7cd5441b6b0752e3fDaniel Jasper !Contexts.back().IsExpression))) 145431f5918281dd1f178bf838b7a47ab1d11c52961Daniel Jasper Left->Type = TT_FunctionTypeLParen; 14632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left->MatchingParen = CurrentToken; 14732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->MatchingParen = Left; 14832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 14963d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper if (StartsObjCMethodExpr) { 1504e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper CurrentToken->Type = TT_ObjCMethodExpr; 1514e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper if (Contexts.back().FirstObjCSelectorName != NULL) { 1524e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 1534e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().LongestObjCSelectorName; 15463d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper } 15563d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper } 15632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 157c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper if (!HasMultipleLines) 158c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper Left->PackingKind = PPK_Inconclusive; 159c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper else if (HasMultipleParametersOnALine) 160c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper Left->PackingKind = PPK_BinPacked; 161c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper else 162c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper Left->PackingKind = PPK_OnePerLine; 163c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper 16432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 16532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 16632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 167e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko if (CurrentToken->isOneOf(tok::r_square, tok::r_brace)) 16832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 1699fc56f2636137fcde8acb38865555ed6c7b84dfdDaniel Jasper updateParameterCount(Left, CurrentToken); 170c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper if (CurrentToken->is(tok::comma) && CurrentToken->Next && 171c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper !CurrentToken->Next->HasUnescapedNewline && 172c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper !CurrentToken->Next->isTrailingComment()) 173c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper HasMultipleParametersOnALine = true; 17432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!consumeToken()) 17532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 176c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper if (CurrentToken && CurrentToken->HasUnescapedNewline) 177c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper HasMultipleLines = true; 17832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 17932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 18032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 18132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 18232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool parseSquare() { 18332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!CurrentToken) 18432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 18532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 186d71b15badeecdc049440103ef044f9cdf5e1359cAlexander Kornienko // A '[' could be an index subscript (after an identifier or after 187051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber // ')' or ']'), it could be the start of an Objective-C method 188051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber // expression, or it could the the start of an Objective-C array literal. 189b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek FormatToken *Left = CurrentToken->Previous; 1900bdc6434fa0fea933b6ab566eff751afdba40a2aAlexander Kornienko FormatToken *Parent = Left->getPreviousNonComment(); 19132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool StartsObjCMethodExpr = 192567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper Contexts.back().CanBeExpression && Left->Type != TT_LambdaLSquare && 193e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko (!Parent || Parent->isOneOf(tok::colon, tok::l_square, tok::l_paren, 194e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko tok::kw_return, tok::kw_throw) || 195ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper Parent->isUnaryOperator() || Parent->Type == TT_ObjCForIn || 196e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko Parent->Type == TT_CastRParen || 197b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek getBinOpPrecedence(Parent->Tok.getKind(), true, true) > prec::Unknown); 198923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper ScopedContextCreator ContextCreator(*this, tok::l_square, 10); 1996f21a988990ff5872822dcb049bd8fc65ce3d236Daniel Jasper Contexts.back().IsExpression = true; 20032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 2014e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper if (StartsObjCMethodExpr) { 2024e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().ColonIsObjCMethodExpr = true; 2034e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Left->Type = TT_ObjCMethodExpr; 204a07aa665a12ab23bef7aa4aedfe113dd8b13da57Daniel Jasper } else if (Parent && Parent->is(tok::at)) { 205a07aa665a12ab23bef7aa4aedfe113dd8b13da57Daniel Jasper Left->Type = TT_ArrayInitializerLSquare; 206a07aa665a12ab23bef7aa4aedfe113dd8b13da57Daniel Jasper } else if (Left->Type == TT_Unknown) { 207a07aa665a12ab23bef7aa4aedfe113dd8b13da57Daniel Jasper Left->Type = TT_ArraySubscriptLSquare; 2084e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper } 20932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 21032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper while (CurrentToken != NULL) { 21132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::r_square)) { 212ac2c974bc64d3767ad5e39451a874c50b3004b3aDaniel Jasper if (CurrentToken->Next && CurrentToken->Next->is(tok::l_paren) && 213ac2c974bc64d3767ad5e39451a874c50b3004b3aDaniel Jasper Left->Type == TT_ObjCMethodExpr) { 214e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber // An ObjC method call is rarely followed by an open parenthesis. 21532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // FIXME: Do we incorrectly label ":" with this? 21632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper StartsObjCMethodExpr = false; 21732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left->Type = TT_Unknown; 21832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 2190178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (StartsObjCMethodExpr) { 2204e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper CurrentToken->Type = TT_ObjCMethodExpr; 221e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber // determineStarAmpUsage() thinks that '*' '[' is allocating an 222e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber // array of pointers, but if '[' starts a selector then '*' is a 223e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber // binary operator. 2243fd9ccdd9f8d259bcf518e7056cfd419d992e984Alexander Kornienko if (Parent != NULL && Parent->Type == TT_PointerOrReference) 2254ed7f3e003c906d9fdb92a9484feeb8ac6e28e2fNico Weber Parent->Type = TT_BinaryOperator; 2260178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 22732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left->MatchingParen = CurrentToken; 22832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->MatchingParen = Left; 2294e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper if (Contexts.back().FirstObjCSelectorName != NULL) 2304e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 2314e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().LongestObjCSelectorName; 23232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 23332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 23432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 235e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko if (CurrentToken->isOneOf(tok::r_paren, tok::r_brace)) 23632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 237a07aa665a12ab23bef7aa4aedfe113dd8b13da57Daniel Jasper if (CurrentToken->is(tok::comma) && 2383c6aea7ac63265c769b5fe09e213ab1c4cee111eDaniel Jasper (Left->Type == TT_ArraySubscriptLSquare || 2393c6aea7ac63265c769b5fe09e213ab1c4cee111eDaniel Jasper Left->Type == TT_ObjCMethodExpr)) 240a07aa665a12ab23bef7aa4aedfe113dd8b13da57Daniel Jasper Left->Type = TT_ArrayInitializerLSquare; 2419fc56f2636137fcde8acb38865555ed6c7b84dfdDaniel Jasper updateParameterCount(Left, CurrentToken); 24232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!consumeToken()) 24332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 24432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 24532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 24632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 24732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 24832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool parseBrace() { 24953e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper if (CurrentToken != NULL) { 250b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek FormatToken *Left = CurrentToken->Previous; 2513c6aea7ac63265c769b5fe09e213ab1c4cee111eDaniel Jasper ScopedContextCreator ContextCreator(*this, tok::l_brace, 1); 2523c6aea7ac63265c769b5fe09e213ab1c4cee111eDaniel Jasper Contexts.back().ColonIsDictLiteral = true; 253f2ff8126e9e9df368f31b1f968d8fc80f99809b3Nico Weber 25453e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper while (CurrentToken != NULL) { 25553e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper if (CurrentToken->is(tok::r_brace)) { 25653e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper Left->MatchingParen = CurrentToken; 25753e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper CurrentToken->MatchingParen = Left; 25853e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper next(); 25953e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper return true; 26053e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper } 26153e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper if (CurrentToken->isOneOf(tok::r_paren, tok::r_square)) 26253e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper return false; 26353e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper updateParameterCount(Left, CurrentToken); 2643c6aea7ac63265c769b5fe09e213ab1c4cee111eDaniel Jasper if (CurrentToken->is(tok::colon)) 2653c6aea7ac63265c769b5fe09e213ab1c4cee111eDaniel Jasper Left->Type = TT_DictLiteral; 26653e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper if (!consumeToken()) 26753e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper return false; 26832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 26932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 27053e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper // No closing "}" found, this probably starts a definition. 27153e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper Line.StartsDefinition = true; 27232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 27332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 274c4615b7aaf97e303a4fc675956f7f5572d492885Daniel Jasper 275b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek void updateParameterCount(FormatToken *Left, FormatToken *Current) { 276c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper if (Current->is(tok::comma)) { 2779fc56f2636137fcde8acb38865555ed6c7b84dfdDaniel Jasper ++Left->ParameterCount; 278d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper if (!Left->Role) 279d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper Left->Role.reset(new CommaSeparatedList(Style)); 280d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper Left->Role->CommaFound(Current); 281c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper } else if (Left->ParameterCount == 0 && Current->isNot(tok::comment)) { 2829fc56f2636137fcde8acb38865555ed6c7b84dfdDaniel Jasper Left->ParameterCount = 1; 283c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper } 2849fc56f2636137fcde8acb38865555ed6c7b84dfdDaniel Jasper } 28532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 28632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool parseConditional() { 28732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper while (CurrentToken != NULL) { 28832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::colon)) { 28932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->Type = TT_ConditionalExpr; 29032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 29132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 29232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 29332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!consumeToken()) 29432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 29532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 29632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 29732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 29832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 29932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool parseTemplateDeclaration() { 30032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken != NULL && CurrentToken->is(tok::less)) { 30132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->Type = TT_TemplateOpener; 30232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 30332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!parseAngle()) 30432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 30534511fb79201ba9ed39c97f3a7ea0f157a79436dDaniel Jasper if (CurrentToken != NULL) 306b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek CurrentToken->Previous->ClosesTemplateDeclaration = true; 30732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 30832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 30932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 31032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 31132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 31232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool consumeToken() { 313b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek FormatToken *Tok = CurrentToken; 31432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 315b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek switch (Tok->Tok.getKind()) { 31632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::plus: 31732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::minus: 318b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek if (Tok->Previous == NULL && Line.MustBeDeclaration) 31932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Tok->Type = TT_ObjCMethodSpecifier; 32032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 32132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::colon: 322b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek if (Tok->Previous == NULL) 323cf6d76af806f7e1ba97be7b72b31bc78b919e0f0Daniel Jasper return false; 32432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // Colons from ?: are handled in parseConditional(). 325b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek if (Tok->Previous->is(tok::r_paren) && Contexts.size() == 1) { 32632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Tok->Type = TT_CtorInitializerColon; 3273c6aea7ac63265c769b5fe09e213ab1c4cee111eDaniel Jasper } else if (Contexts.back().ColonIsDictLiteral) { 3283c6aea7ac63265c769b5fe09e213ab1c4cee111eDaniel Jasper Tok->Type = TT_DictLiteral; 3294e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper } else if (Contexts.back().ColonIsObjCMethodExpr || 330b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek Line.First->Type == TT_ObjCMethodSpecifier) { 33132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Tok->Type = TT_ObjCMethodExpr; 332b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek Tok->Previous->Type = TT_ObjCSelectorName; 33383a7dcdf5fce1bdf74ce985419d77a41a51abfa2Alexander Kornienko if (Tok->Previous->ColumnWidth > 33400895106f9ed602af67984ec4d225a0cdc8c12afAlexander Kornienko Contexts.back().LongestObjCSelectorName) { 33501fe9f9f320dd4342664376f24eb1a0d004d03c8Alexander Kornienko Contexts.back().LongestObjCSelectorName = Tok->Previous->ColumnWidth; 33600895106f9ed602af67984ec4d225a0cdc8c12afAlexander Kornienko } 3374e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper if (Contexts.back().FirstObjCSelectorName == NULL) 338b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek Contexts.back().FirstObjCSelectorName = Tok->Previous; 3394e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper } else if (Contexts.back().ColonIsForRangeExpr) { 34032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Tok->Type = TT_RangeBasedForLoopColon; 34101fe9f9f320dd4342664376f24eb1a0d004d03c8Alexander Kornienko } else if (CurrentToken != NULL && 34201fe9f9f320dd4342664376f24eb1a0d004d03c8Alexander Kornienko CurrentToken->is(tok::numeric_constant)) { 34301fe9f9f320dd4342664376f24eb1a0d004d03c8Alexander Kornienko Tok->Type = TT_BitFieldColon; 344cea014bd8d280070caeb27e4e6e33e5723b4226fDaniel Jasper } else if (Contexts.size() == 1 && Line.First->isNot(tok::kw_enum)) { 3456cabab48dacc1317821f8f078ed2d4c603b67affDaniel Jasper Tok->Type = TT_InheritanceColon; 346923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper } else if (Contexts.back().ContextKind == tok::l_paren) { 347923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper Tok->Type = TT_InlineASMColon; 34863d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper } 34932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 35032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::kw_if: 35132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::kw_while: 35232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken != NULL && CurrentToken->is(tok::l_paren)) { 35332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 3542726877196b41b922f10f794801b313980e1a8adNico Weber if (!parseParens(/*LookForDecls=*/true)) 35532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 35632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 35732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 35832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::kw_for: 3594e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().ColonIsForRangeExpr = true; 36032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 36132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!parseParens()) 36232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 36332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 36432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::l_paren: 36532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!parseParens()) 36632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 3671407bee187d7b964d5293ac8bf4f7a490c78cec6Daniel Jasper if (Line.MustBeDeclaration && NameFound && !Contexts.back().IsExpression) 3683c08a818a6ac9115fe8880af9bbf5a0a87bdffaaDaniel Jasper Line.MightBeFunctionDecl = true; 36932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 37032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::l_square: 37132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!parseSquare()) 37232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 37332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 37432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::l_brace: 37532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!parseBrace()) 37632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 37732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 37832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::less: 3790236dd09c040f2e6124654d620dde94a595c5ab0Daniel Jasper if (Tok->Previous && !Tok->Previous->Tok.isLiteral() && parseAngle()) 38032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Tok->Type = TT_TemplateOpener; 38132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper else { 38232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Tok->Type = TT_BinaryOperator; 38332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken = Tok; 38432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 38532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 38632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 38732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::r_paren: 38832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::r_square: 38932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 39032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::r_brace: 39132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // Lines can start with '}'. 392b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek if (Tok->Previous != NULL) 39332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 39432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 39532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::greater: 39632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Tok->Type = TT_BinaryOperator; 39732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 39832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::kw_operator: 399174f60f005167984d00682d1d38a2927b9c04684Daniel Jasper while (CurrentToken && 400174f60f005167984d00682d1d38a2927b9c04684Daniel Jasper !CurrentToken->isOneOf(tok::l_paren, tok::semi, tok::r_paren)) { 401e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko if (CurrentToken->isOneOf(tok::star, tok::amp)) 4022b4c924f85e156d66c01b3f16c850892c47dcc7aDaniel Jasper CurrentToken->Type = TT_PointerOrReference; 4032b4c924f85e156d66c01b3f16c850892c47dcc7aDaniel Jasper consumeToken(); 404174f60f005167984d00682d1d38a2927b9c04684Daniel Jasper if (CurrentToken && CurrentToken->Previous->Type == TT_BinaryOperator) 405c476ea976badd316e3afd0f34afe1f030a710117Daniel Jasper CurrentToken->Previous->Type = TT_OverloadedOperator; 40632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 4076ea933c7e8f6988d5647af4a0eafd393a4c3685aDaniel Jasper if (CurrentToken) { 4082b4c924f85e156d66c01b3f16c850892c47dcc7aDaniel Jasper CurrentToken->Type = TT_OverloadedOperatorLParen; 409b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek if (CurrentToken->Previous->Type == TT_BinaryOperator) 410b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek CurrentToken->Previous->Type = TT_OverloadedOperator; 4116ea933c7e8f6988d5647af4a0eafd393a4c3685aDaniel Jasper } 41232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 41332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::question: 41432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper parseConditional(); 41532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 41632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::kw_template: 41732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper parseTemplateDeclaration(); 41832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 419c2e6d2a4a7fe9dfa7d52a38c6048b7b18e6b591aNico Weber case tok::identifier: 420b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek if (Line.First->is(tok::kw_for) && 421b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek Tok->Tok.getIdentifierInfo() == &Ident_in) 422c2e6d2a4a7fe9dfa7d52a38c6048b7b18e6b591aNico Weber Tok->Type = TT_ObjCForIn; 423c2e6d2a4a7fe9dfa7d52a38c6048b7b18e6b591aNico Weber break; 4248ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::comma: 4258ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper if (Contexts.back().FirstStartOfName) 4268ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper Contexts.back().FirstStartOfName->PartOfMultiVariableDeclStmt = true; 427e8b10d3d5b90efaf60ad89e96f6500f971ceec41Daniel Jasper if (Contexts.back().InCtorInitializer) 428e8b10d3d5b90efaf60ad89e96f6500f971ceec41Daniel Jasper Tok->Type = TT_CtorInitializerComma; 4298ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper break; 43032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper default: 43132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 43232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 43332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 43432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 43532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 43632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper void parseIncludeDirective() { 43732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 43832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken != NULL && CurrentToken->is(tok::less)) { 43932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 44032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper while (CurrentToken != NULL) { 441b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek if (CurrentToken->isNot(tok::comment) || CurrentToken->Next) 44232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->Type = TT_ImplicitStringLiteral; 44332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 44432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 44532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } else { 44632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper while (CurrentToken != NULL) { 4473a204418482c9ae70ad482e781132c54306c3aa6Daniel Jasper if (CurrentToken->is(tok::string_literal)) 4483a204418482c9ae70ad482e781132c54306c3aa6Daniel Jasper // Mark these string literals as "implicit" literals, too, so that 4493a204418482c9ae70ad482e781132c54306c3aa6Daniel Jasper // they are not split or line-wrapped. 4503a204418482c9ae70ad482e781132c54306c3aa6Daniel Jasper CurrentToken->Type = TT_ImplicitStringLiteral; 45132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 45232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 45332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 45432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 45532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 45632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper void parseWarningOrError() { 45732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 45832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // We still want to format the whitespace left of the first token of the 45932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // warning or error. 46032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 46132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper while (CurrentToken != NULL) { 46232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->Type = TT_ImplicitStringLiteral; 46332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 46432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 46532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 46632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 46732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper void parsePreprocessorDirective() { 46832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 46932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken == NULL) 47032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return; 471b18c258390f794d8803ef5ebbb56fb77bfea7ba4Alexander Kornienko if (CurrentToken->Tok.is(tok::numeric_constant)) { 472b18c258390f794d8803ef5ebbb56fb77bfea7ba4Alexander Kornienko CurrentToken->SpacesRequiredBefore = 1; 473b18c258390f794d8803ef5ebbb56fb77bfea7ba4Alexander Kornienko return; 474b18c258390f794d8803ef5ebbb56fb77bfea7ba4Alexander Kornienko } 47532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // Hashes in the middle of a line can lead to any strange token 47632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // sequence. 477b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek if (CurrentToken->Tok.getIdentifierInfo() == NULL) 47832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return; 479b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek switch (CurrentToken->Tok.getIdentifierInfo()->getPPKeywordID()) { 48032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::pp_include: 48132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::pp_import: 48232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper parseIncludeDirective(); 48332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 48432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::pp_error: 48532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::pp_warning: 48632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper parseWarningOrError(); 48732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 488aae7bad5cdd804cb88e918e9defbf5faf69f4cfdDaniel Jasper case tok::pp_if: 489aae7bad5cdd804cb88e918e9defbf5faf69f4cfdDaniel Jasper case tok::pp_elif: 490aae7bad5cdd804cb88e918e9defbf5faf69f4cfdDaniel Jasper parseLine(); 491aae7bad5cdd804cb88e918e9defbf5faf69f4cfdDaniel Jasper break; 49232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper default: 49332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 49432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 4955b7e7b0ec77f49c1b24deffc9b7032ca16ca9f0dDaniel Jasper while (CurrentToken != NULL) 4965b7e7b0ec77f49c1b24deffc9b7032ca16ca9f0dDaniel Jasper next(); 49732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 49832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 49995e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weberpublic: 50032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper LineType parseLine() { 50132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::hash)) { 50232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper parsePreprocessorDirective(); 50332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return LT_PreprocessorDirective; 50432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 50532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper while (CurrentToken != NULL) { 50632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::kw_virtual)) 50732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper KeywordVirtualFound = true; 50832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!consumeToken()) 50932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return LT_Invalid; 51032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 51132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (KeywordVirtualFound) 51232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return LT_VirtualFunctionDecl; 51332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 514b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek if (Line.First->Type == TT_ObjCMethodSpecifier) { 5154e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper if (Contexts.back().FirstObjCSelectorName != NULL) 5164e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 5174e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().LongestObjCSelectorName; 51863d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper return LT_ObjCMethodDecl; 51963d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper } 52063d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper 52132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return LT_Other; 52232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 52332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 52495e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weberprivate: 52532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper void next() { 5260178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (CurrentToken != NULL) { 5270178673f541685cf5067814dfeee2644078e39a9Daniel Jasper determineTokenType(*CurrentToken); 5284e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper CurrentToken->BindingStrength = Contexts.back().BindingStrength; 5290178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 5300178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 531b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek if (CurrentToken != NULL) 532b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek CurrentToken = CurrentToken->Next; 533d0f349be1422a123fdb28d6dd556f7300e6d51e9Daniel Jasper 534ae76f7f850a9101a20191b10241ca72c23dc40ddManuel Klimek if (CurrentToken != NULL) { 535ae76f7f850a9101a20191b10241ca72c23dc40ddManuel Klimek // Reset token type in case we have already looked at it and then 536ae76f7f850a9101a20191b10241ca72c23dc40ddManuel Klimek // recovered from an error (e.g. failure to find the matching >). 537ae76f7f850a9101a20191b10241ca72c23dc40ddManuel Klimek if (CurrentToken->Type != TT_LambdaLSquare && 538ae76f7f850a9101a20191b10241ca72c23dc40ddManuel Klimek CurrentToken->Type != TT_ImplicitStringLiteral) 539ae76f7f850a9101a20191b10241ca72c23dc40ddManuel Klimek CurrentToken->Type = TT_Unknown; 540ae76f7f850a9101a20191b10241ca72c23dc40ddManuel Klimek if (CurrentToken->Role) 541ae76f7f850a9101a20191b10241ca72c23dc40ddManuel Klimek CurrentToken->Role.reset(NULL); 542ae76f7f850a9101a20191b10241ca72c23dc40ddManuel Klimek CurrentToken->FakeLParens.clear(); 543ae76f7f850a9101a20191b10241ca72c23dc40ddManuel Klimek CurrentToken->FakeRParens = 0; 544ae76f7f850a9101a20191b10241ca72c23dc40ddManuel Klimek } 54532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 54632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 5474e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper /// \brief A struct to hold information valid in a specific context, e.g. 5484e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper /// a pair of parenthesis. 5494e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper struct Context { 550923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper Context(tok::TokenKind ContextKind, unsigned BindingStrength, 551923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper bool IsExpression) 552923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper : ContextKind(ContextKind), BindingStrength(BindingStrength), 553923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper LongestObjCSelectorName(0), ColonIsForRangeExpr(false), 5543c6aea7ac63265c769b5fe09e213ab1c4cee111eDaniel Jasper ColonIsDictLiteral(false), ColonIsObjCMethodExpr(false), 555f2ff8126e9e9df368f31b1f968d8fc80f99809b3Nico Weber FirstObjCSelectorName(NULL), FirstStartOfName(NULL), 556e8b10d3d5b90efaf60ad89e96f6500f971ceec41Daniel Jasper IsExpression(IsExpression), CanBeExpression(true), 557e8b10d3d5b90efaf60ad89e96f6500f971ceec41Daniel Jasper InCtorInitializer(false) {} 558923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper 559923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper tok::TokenKind ContextKind; 5604e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper unsigned BindingStrength; 5614e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper unsigned LongestObjCSelectorName; 5624e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper bool ColonIsForRangeExpr; 5633c6aea7ac63265c769b5fe09e213ab1c4cee111eDaniel Jasper bool ColonIsDictLiteral; 5644e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper bool ColonIsObjCMethodExpr; 565b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek FormatToken *FirstObjCSelectorName; 566b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek FormatToken *FirstStartOfName; 5674e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper bool IsExpression; 5686f21a988990ff5872822dcb049bd8fc65ce3d236Daniel Jasper bool CanBeExpression; 569e8b10d3d5b90efaf60ad89e96f6500f971ceec41Daniel Jasper bool InCtorInitializer; 5704e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper }; 5714e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper 5724e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper /// \brief Puts a new \c Context onto the stack \c Contexts for the lifetime 5734e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper /// of each instance. 5744e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper struct ScopedContextCreator { 5754e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper AnnotatingParser &P; 5764e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper 577923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper ScopedContextCreator(AnnotatingParser &P, tok::TokenKind ContextKind, 578923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper unsigned Increase) 579923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper : P(P) { 5802a409b62126d8f0b8f5749d5ed435ad2b394b526Daniel Jasper P.Contexts.push_back(Context(ContextKind, 5812a409b62126d8f0b8f5749d5ed435ad2b394b526Daniel Jasper P.Contexts.back().BindingStrength + Increase, 5822a409b62126d8f0b8f5749d5ed435ad2b394b526Daniel Jasper P.Contexts.back().IsExpression)); 5834e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper } 5844e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper 5854e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper ~ScopedContextCreator() { P.Contexts.pop_back(); } 5864e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper }; 5870178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 588b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek void determineTokenType(FormatToken &Current) { 589b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek if (Current.getPrecedence() == prec::Assignment && 59053352600b7370b1d33b9fde1adda207fd9d7dcd1Daniel Jasper !Line.First->isOneOf(tok::kw_template, tok::kw_using) && 591b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek (!Current.Previous || Current.Previous->isNot(tok::kw_operator))) { 5924e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().IsExpression = true; 593b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek for (FormatToken *Previous = Current.Previous; 5947e27400c90e9e295bcf5857eebf2d60c4b32106eDaniel Jasper Previous && !Previous->isOneOf(tok::comma, tok::semi); 595b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek Previous = Previous->Previous) { 5969c65b069821b7de79427e291b006293a0f55ff8fDaniel Jasper if (Previous->is(tok::r_square)) 5979c65b069821b7de79427e291b006293a0f55ff8fDaniel Jasper Previous = Previous->MatchingParen; 5980178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (Previous->Type == TT_BinaryOperator && 599e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko Previous->isOneOf(tok::star, tok::amp)) { 6000178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Previous->Type = TT_PointerOrReference; 6010178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 6020178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 603e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko } else if (Current.isOneOf(tok::kw_return, tok::kw_throw) || 60495e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weber (Current.is(tok::l_paren) && !Line.MustBeDeclaration && 605378d93dcf7ec80661efc65642dc6266c9e13780aDaniel Jasper !Line.InPPDirective && 6062530fd5a235c1e57f8ebef2eae9b365042501009Manuel Klimek (!Current.Previous || 60753352600b7370b1d33b9fde1adda207fd9d7dcd1Daniel Jasper !Current.Previous->isOneOf(tok::kw_for, tok::kw_catch)))) { 6084e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().IsExpression = true; 609e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko } else if (Current.isOneOf(tok::r_paren, tok::greater, tok::comma)) { 610b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek for (FormatToken *Previous = Current.Previous; 611e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko Previous && Previous->isOneOf(tok::star, tok::amp); 612b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek Previous = Previous->Previous) 61395e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weber Previous->Type = TT_PointerOrReference; 614b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek } else if (Current.Previous && 615b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek Current.Previous->Type == TT_CtorInitializerColon) { 616d0f349be1422a123fdb28d6dd556f7300e6d51e9Daniel Jasper Contexts.back().IsExpression = true; 617e8b10d3d5b90efaf60ad89e96f6500f971ceec41Daniel Jasper Contexts.back().InCtorInitializer = true; 6186f21a988990ff5872822dcb049bd8fc65ce3d236Daniel Jasper } else if (Current.is(tok::kw_new)) { 6196f21a988990ff5872822dcb049bd8fc65ce3d236Daniel Jasper Contexts.back().CanBeExpression = false; 62016a69ef481f4580c571b6c693a5d3dd64ea56b53Daniel Jasper } else if (Current.is(tok::semi)) { 62116a69ef481f4580c571b6c693a5d3dd64ea56b53Daniel Jasper // This should be the condition or increment in a for-loop. 62216a69ef481f4580c571b6c693a5d3dd64ea56b53Daniel Jasper Contexts.back().IsExpression = true; 62395e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weber } 6240178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 6250178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (Current.Type == TT_Unknown) { 6266b3ff8c4caaa6782289a780e096fe56ad6434bb7Daniel Jasper // Line.MightBeFunctionDecl can only be true after the parentheses of a 6276b3ff8c4caaa6782289a780e096fe56ad6434bb7Daniel Jasper // function declaration have been found. In this case, 'Current' is a 6286b3ff8c4caaa6782289a780e096fe56ad6434bb7Daniel Jasper // trailing token of this declaration and thus cannot be a name. 6296b3ff8c4caaa6782289a780e096fe56ad6434bb7Daniel Jasper if (isStartOfName(Current) && !Line.MightBeFunctionDecl) { 6308ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper Contexts.back().FirstStartOfName = &Current; 6313c08a818a6ac9115fe8880af9bbf5a0a87bdffaaDaniel Jasper Current.Type = TT_StartOfName; 6321407bee187d7b964d5293ac8bf4f7a490c78cec6Daniel Jasper NameFound = true; 6332ca3741a962ded08866596577aaee2f4ab74c955Daniel Jasper } else if (Current.is(tok::kw_auto)) { 6342ca3741a962ded08866596577aaee2f4ab74c955Daniel Jasper AutoFound = true; 6353262f4c10520cf11acea4cf590cfbf055924a41eDaniel Jasper } else if (Current.is(tok::arrow) && AutoFound && 6363262f4c10520cf11acea4cf590cfbf055924a41eDaniel Jasper Line.MustBeDeclaration) { 6372ca3741a962ded08866596577aaee2f4ab74c955Daniel Jasper Current.Type = TT_TrailingReturnArrow; 638e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko } else if (Current.isOneOf(tok::star, tok::amp, tok::ampamp)) { 6394e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Current.Type = 640d6104f6c34639ebe66f83d955c5f32ea4a50c266Daniel Jasper determineStarAmpUsage(Current, Contexts.back().CanBeExpression && 641d6104f6c34639ebe66f83d955c5f32ea4a50c266Daniel Jasper Contexts.back().IsExpression); 642e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko } else if (Current.isOneOf(tok::minus, tok::plus, tok::caret)) { 6430178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.Type = determinePlusMinusCaretUsage(Current); 644e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko } else if (Current.isOneOf(tok::minusminus, tok::plusplus)) { 6450178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.Type = determineIncrementUsage(Current); 6460178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } else if (Current.is(tok::exclaim)) { 6470178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.Type = TT_UnaryOperator; 64831e44f7a5d50ab8f7f623a7d2e18d5d877ef400dManuel Klimek } else if (Current.isBinaryOperator() && 64931e44f7a5d50ab8f7f623a7d2e18d5d877ef400dManuel Klimek (!Current.Previous || 65031e44f7a5d50ab8f7f623a7d2e18d5d877ef400dManuel Klimek Current.Previous->isNot(tok::l_square))) { 6510178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.Type = TT_BinaryOperator; 6520178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } else if (Current.is(tok::comment)) { 65300895106f9ed602af67984ec4d225a0cdc8c12afAlexander Kornienko if (Current.TokenText.startswith("//")) 6540178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.Type = TT_LineComment; 6550178673f541685cf5067814dfeee2644078e39a9Daniel Jasper else 6560178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.Type = TT_BlockComment; 65737d693160eba22343e08d7bcf66cd132ace77e5cNico Weber } else if (Current.is(tok::r_paren)) { 658b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper FormatToken *LeftOfParens = NULL; 659b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper if (Current.MatchingParen) 6600bdc6434fa0fea933b6ab566eff751afdba40a2aAlexander Kornienko LeftOfParens = Current.MatchingParen->getPreviousNonComment(); 661b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper bool IsCast = false; 662b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper bool ParensAreEmpty = Current.Previous == Current.MatchingParen; 663b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper bool ParensAreType = !Current.Previous || 664b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek Current.Previous->Type == TT_PointerOrReference || 665b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper Current.Previous->Type == TT_TemplateCloser || 666b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper isSimpleTypeSpecifier(*Current.Previous); 66737d693160eba22343e08d7bcf66cd132ace77e5cNico Weber bool ParensCouldEndDecl = 668b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek Current.Next && 669b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek Current.Next->isOneOf(tok::equal, tok::semi, tok::l_brace); 6706a365aaa057a8c445d25344c0433726c752b3e7dDaniel Jasper bool IsSizeOfOrAlignOf = 671b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper LeftOfParens && 672b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper LeftOfParens->isOneOf(tok::kw_sizeof, tok::kw_alignof); 673b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper if (ParensAreType && !ParensCouldEndDecl && !IsSizeOfOrAlignOf && 6740c368787d9d1f92a3408b71b3f074a06edaa6bdeDaniel Jasper (Contexts.back().IsExpression || 6750c368787d9d1f92a3408b71b3f074a06edaa6bdeDaniel Jasper (Current.Next && Current.Next->isBinaryOperator()))) 676b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper IsCast = true; 6772a409b62126d8f0b8f5749d5ed435ad2b394b526Daniel Jasper if (Current.Next && Current.Next->isNot(tok::string_literal) && 678b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper (Current.Next->Tok.isLiteral() || 679b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper Current.Next->isOneOf(tok::kw_sizeof, tok::kw_alignof))) 680b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper IsCast = true; 681b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper // If there is an identifier after the (), it is likely a cast, unless 682b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper // there is also an identifier before the (). 683ff1a2e519ebcd6d7a060eac7ba8aca37b2bf89d0Daniel Jasper if (LeftOfParens && (LeftOfParens->Tok.getIdentifierInfo() == NULL || 684ff1a2e519ebcd6d7a060eac7ba8aca37b2bf89d0Daniel Jasper LeftOfParens->is(tok::kw_return)) && 685526df0f3a8d436e9084bd12118a2e119aa0bd724Daniel Jasper LeftOfParens->Type != TT_OverloadedOperator && 686465e8615a153ebd70eb27785af79f7e82e4a81d4Nico Weber LeftOfParens->Type != TT_TemplateCloser && Current.Next && 687465e8615a153ebd70eb27785af79f7e82e4a81d4Nico Weber Current.Next->is(tok::identifier)) 688b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper IsCast = true; 689b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper if (IsCast && !ParensAreEmpty) 69037d693160eba22343e08d7bcf66cd132ace77e5cNico Weber Current.Type = TT_CastRParen; 691b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek } else if (Current.is(tok::at) && Current.Next) { 692b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek switch (Current.Next->Tok.getObjCKeywordID()) { 6930178673f541685cf5067814dfeee2644078e39a9Daniel Jasper case tok::objc_interface: 6940178673f541685cf5067814dfeee2644078e39a9Daniel Jasper case tok::objc_implementation: 6950178673f541685cf5067814dfeee2644078e39a9Daniel Jasper case tok::objc_protocol: 6960178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.Type = TT_ObjCDecl; 6970178673f541685cf5067814dfeee2644078e39a9Daniel Jasper break; 6980178673f541685cf5067814dfeee2644078e39a9Daniel Jasper case tok::objc_property: 6990178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.Type = TT_ObjCProperty; 7000178673f541685cf5067814dfeee2644078e39a9Daniel Jasper break; 7010178673f541685cf5067814dfeee2644078e39a9Daniel Jasper default: 7020178673f541685cf5067814dfeee2644078e39a9Daniel Jasper break; 7030178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 7045ad390d27f8f7cb6628bc2c32beba4d25bc2718bDaniel Jasper } else if (Current.is(tok::period)) { 7050bdc6434fa0fea933b6ab566eff751afdba40a2aAlexander Kornienko FormatToken *PreviousNoComment = Current.getPreviousNonComment(); 7065ad390d27f8f7cb6628bc2c32beba4d25bc2718bDaniel Jasper if (PreviousNoComment && 7075ad390d27f8f7cb6628bc2c32beba4d25bc2718bDaniel Jasper PreviousNoComment->isOneOf(tok::comma, tok::l_brace)) 7085ad390d27f8f7cb6628bc2c32beba4d25bc2718bDaniel Jasper Current.Type = TT_DesignatedInitializerPeriod; 7090178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 7100178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 7110178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 7120178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 7136ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper /// \brief Take a guess at whether \p Tok starts a name of a function or 7146ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper /// variable declaration. 7156ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper /// 7166ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper /// This is a heuristic based on whether \p Tok is an identifier following 7176ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper /// something that is likely a type. 7186ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper bool isStartOfName(const FormatToken &Tok) { 7196ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper if (Tok.isNot(tok::identifier) || Tok.Previous == NULL) 7206ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper return false; 7216ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper 7226ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper // Skip "const" as it does not have an influence on whether this is a name. 7236ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper FormatToken *PreviousNotConst = Tok.Previous; 7246ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper while (PreviousNotConst != NULL && PreviousNotConst->is(tok::kw_const)) 7256ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper PreviousNotConst = PreviousNotConst->Previous; 7266ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper 7276ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper if (PreviousNotConst == NULL) 7286ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper return false; 7296ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper 7302a409b62126d8f0b8f5749d5ed435ad2b394b526Daniel Jasper bool IsPPKeyword = PreviousNotConst->is(tok::identifier) && 7312a409b62126d8f0b8f5749d5ed435ad2b394b526Daniel Jasper PreviousNotConst->Previous && 7322a409b62126d8f0b8f5749d5ed435ad2b394b526Daniel Jasper PreviousNotConst->Previous->is(tok::hash); 7336ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper 73492495a8032d8624495a0ce769d5a6cdeba2dc8d8Daniel Jasper if (PreviousNotConst->Type == TT_TemplateCloser) 73592495a8032d8624495a0ce769d5a6cdeba2dc8d8Daniel Jasper return PreviousNotConst && PreviousNotConst->MatchingParen && 73692495a8032d8624495a0ce769d5a6cdeba2dc8d8Daniel Jasper PreviousNotConst->MatchingParen->Previous && 73792495a8032d8624495a0ce769d5a6cdeba2dc8d8Daniel Jasper PreviousNotConst->MatchingParen->Previous->isNot(tok::kw_template); 73892495a8032d8624495a0ce769d5a6cdeba2dc8d8Daniel Jasper 7396ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper return (!IsPPKeyword && PreviousNotConst->is(tok::identifier)) || 7406ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper PreviousNotConst->Type == TT_PointerOrReference || 7416ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper isSimpleTypeSpecifier(*PreviousNotConst); 7426ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper } 7436ac431c7bae27a42351d2c2ad03dddd5b005ffd5Daniel Jasper 7440178673f541685cf5067814dfeee2644078e39a9Daniel Jasper /// \brief Return the type of the given token assuming it is * or &. 745b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek TokenType determineStarAmpUsage(const FormatToken &Tok, bool IsExpression) { 7460bdc6434fa0fea933b6ab566eff751afdba40a2aAlexander Kornienko const FormatToken *PrevToken = Tok.getPreviousNonComment(); 7470178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (PrevToken == NULL) 7480178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_UnaryOperator; 7490178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 7500bdc6434fa0fea933b6ab566eff751afdba40a2aAlexander Kornienko const FormatToken *NextToken = Tok.getNextNonComment(); 7510178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (NextToken == NULL) 7520178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_Unknown; 7530178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 754431f5918281dd1f178bf838b7a47ab1d11c52961Daniel Jasper if (PrevToken->is(tok::coloncolon) || 755431f5918281dd1f178bf838b7a47ab1d11c52961Daniel Jasper (PrevToken->is(tok::l_paren) && !IsExpression)) 7568a5d7cd100ebfb8c6b353ee4ad5b14ab4105d32dDaniel Jasper return TT_PointerOrReference; 7578a5d7cd100ebfb8c6b353ee4ad5b14ab4105d32dDaniel Jasper 758e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko if (PrevToken->isOneOf(tok::l_paren, tok::l_square, tok::l_brace, 759d3cf17b5f1fed43dbd0cd35c43d15139803c9c84Daniel Jasper tok::comma, tok::semi, tok::kw_return, tok::colon, 76065da8e952da32730202356290bb889c8839bbef5Daniel Jasper tok::equal, tok::kw_delete, tok::kw_sizeof) || 761e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko PrevToken->Type == TT_BinaryOperator || 7620178673f541685cf5067814dfeee2644078e39a9Daniel Jasper PrevToken->Type == TT_UnaryOperator || PrevToken->Type == TT_CastRParen) 7630178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_UnaryOperator; 7640178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 765e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber if (NextToken->is(tok::l_square)) 766e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber return TT_PointerOrReference; 767e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber 768db8afe424991b34884afb13ecf97ac458e41da9eDaniel Jasper if (PrevToken->is(tok::r_paren) && PrevToken->MatchingParen && 769db8afe424991b34884afb13ecf97ac458e41da9eDaniel Jasper PrevToken->MatchingParen->Previous && 770db8afe424991b34884afb13ecf97ac458e41da9eDaniel Jasper PrevToken->MatchingParen->Previous->is(tok::kw_typeof)) 771db8afe424991b34884afb13ecf97ac458e41da9eDaniel Jasper return TT_PointerOrReference; 772db8afe424991b34884afb13ecf97ac458e41da9eDaniel Jasper 773b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek if (PrevToken->Tok.isLiteral() || 774e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko PrevToken->isOneOf(tok::r_paren, tok::r_square) || 775b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek NextToken->Tok.isLiteral() || NextToken->isUnaryOperator()) 7760178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_BinaryOperator; 7770178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 7780178673f541685cf5067814dfeee2644078e39a9Daniel Jasper // It is very unlikely that we are going to find a pointer or reference type 7790178673f541685cf5067814dfeee2644078e39a9Daniel Jasper // definition on the RHS of an assignment. 7800178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (IsExpression) 7810178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_BinaryOperator; 7820178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 7830178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_PointerOrReference; 7840178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 7850178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 786b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek TokenType determinePlusMinusCaretUsage(const FormatToken &Tok) { 7870bdc6434fa0fea933b6ab566eff751afdba40a2aAlexander Kornienko const FormatToken *PrevToken = Tok.getPreviousNonComment(); 788b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper if (PrevToken == NULL || PrevToken->Type == TT_CastRParen) 7890178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_UnaryOperator; 7900178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 7910178673f541685cf5067814dfeee2644078e39a9Daniel Jasper // Use heuristics to recognize unary operators. 792e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko if (PrevToken->isOneOf(tok::equal, tok::l_paren, tok::comma, tok::l_square, 793e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko tok::question, tok::colon, tok::kw_return, 794e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko tok::kw_case, tok::at, tok::l_brace)) 7950178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_UnaryOperator; 7960178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 797ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber // There can't be two consecutive binary operators. 7980178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (PrevToken->Type == TT_BinaryOperator) 7990178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_UnaryOperator; 8000178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 8010178673f541685cf5067814dfeee2644078e39a9Daniel Jasper // Fall back to marking the token as binary operator. 8020178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_BinaryOperator; 8030178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 8040178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 8050178673f541685cf5067814dfeee2644078e39a9Daniel Jasper /// \brief Determine whether ++/-- are pre- or post-increments/-decrements. 806b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek TokenType determineIncrementUsage(const FormatToken &Tok) { 8070bdc6434fa0fea933b6ab566eff751afdba40a2aAlexander Kornienko const FormatToken *PrevToken = Tok.getPreviousNonComment(); 808b8b4295b4ee161bfb76ff7b0ec1007bfd959553bDaniel Jasper if (PrevToken == NULL || PrevToken->Type == TT_CastRParen) 8090178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_UnaryOperator; 810e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko if (PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::identifier)) 8110178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_TrailingUnaryOperator; 8120178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 8130178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_UnaryOperator; 8140178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 8154e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper 8168ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper // FIXME: This is copy&pasted from Sema. Put it in a common place and remove 8178ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper // duplication. 8188ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper /// \brief Determine whether the token kind starts a simple-type-specifier. 819b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek bool isSimpleTypeSpecifier(const FormatToken &Tok) const { 820b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek switch (Tok.Tok.getKind()) { 8218ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw_short: 8228ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw_long: 8238ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw___int64: 8248ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw___int128: 8258ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw_signed: 8268ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw_unsigned: 8278ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw_void: 8288ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw_char: 8298ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw_int: 8308ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw_half: 8318ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw_float: 8328ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw_double: 8338ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw_wchar_t: 8348ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw_bool: 8358ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw___underlying_type: 8368ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::annot_typename: 8378ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw_char16_t: 8388ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw_char32_t: 8398ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw_typeof: 8408ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw_decltype: 84100895106f9ed602af67984ec4d225a0cdc8c12afAlexander Kornienko return true; 8428ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper default: 84300895106f9ed602af67984ec4d225a0cdc8c12afAlexander Kornienko return false; 8448ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper } 8458ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper } 8468ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper 8474e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper SmallVector<Context, 8> Contexts; 8484e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper 849d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper const FormatStyle &Style; 8504e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper AnnotatedLine &Line; 851b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek FormatToken *CurrentToken; 8524e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper bool KeywordVirtualFound; 8531407bee187d7b964d5293ac8bf4f7a490c78cec6Daniel Jasper bool NameFound; 8542ca3741a962ded08866596577aaee2f4ab74c955Daniel Jasper bool AutoFound; 855c2e6d2a4a7fe9dfa7d52a38c6048b7b18e6b591aNico Weber IdentifierInfo &Ident_in; 85632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper}; 85732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 858d489f8ceb735458b0e1f814e3f952b154f49c025Daniel Jasperstatic int PrecedenceUnaryOperator = prec::PointerToMember + 1; 859d489f8ceb735458b0e1f814e3f952b154f49c025Daniel Jasperstatic int PrecedenceArrowAndPeriod = prec::PointerToMember + 2; 860d489f8ceb735458b0e1f814e3f952b154f49c025Daniel Jasper 86129f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper/// \brief Parses binary expressions by inserting fake parenthesis based on 86229f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper/// operator precedence. 86329f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasperclass ExpressionParser { 86429f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasperpublic: 8659acb8b4355028887e8cc4aa8f683aceee021a62bDaniel Jasper ExpressionParser(AnnotatedLine &Line) : Current(Line.First) { 8669acb8b4355028887e8cc4aa8f683aceee021a62bDaniel Jasper // Skip leading "}", e.g. in "} else if (...) {". 8679acb8b4355028887e8cc4aa8f683aceee021a62bDaniel Jasper if (Current->is(tok::r_brace)) 8689acb8b4355028887e8cc4aa8f683aceee021a62bDaniel Jasper next(); 8699acb8b4355028887e8cc4aa8f683aceee021a62bDaniel Jasper } 87029f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 87129f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper /// \brief Parse expressions with the given operatore precedence. 872237d4c1c785be13656bff6c09e5b7ccd066ff5baDaniel Jasper void parse(int Precedence = 0) { 873f78bf4a0132a3ea366ba3baadd9d6af26c617d11Daniel Jasper // Skip 'return' as it is not part of a binary expression. 874f78bf4a0132a3ea366ba3baadd9d6af26c617d11Daniel Jasper while (Current && Current->is(tok::kw_return)) 875f78bf4a0132a3ea366ba3baadd9d6af26c617d11Daniel Jasper next(); 876f78bf4a0132a3ea366ba3baadd9d6af26c617d11Daniel Jasper 877d489f8ceb735458b0e1f814e3f952b154f49c025Daniel Jasper if (Current == NULL || Precedence > PrecedenceArrowAndPeriod) 8783618e6fae8b734ad94221d941417c12d4bd1e3a8Daniel Jasper return; 8793618e6fae8b734ad94221d941417c12d4bd1e3a8Daniel Jasper 880c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper // Conditional expressions need to be parsed separately for proper nesting. 881d489f8ceb735458b0e1f814e3f952b154f49c025Daniel Jasper if (Precedence == prec::Conditional) { 882c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper parseConditionalExpr(); 883c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper return; 884c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper } 8853618e6fae8b734ad94221d941417c12d4bd1e3a8Daniel Jasper 8863618e6fae8b734ad94221d941417c12d4bd1e3a8Daniel Jasper // Parse unary operators, which all have a higher precedence than binary 8873618e6fae8b734ad94221d941417c12d4bd1e3a8Daniel Jasper // operators. 888d489f8ceb735458b0e1f814e3f952b154f49c025Daniel Jasper if (Precedence == PrecedenceUnaryOperator) { 8893618e6fae8b734ad94221d941417c12d4bd1e3a8Daniel Jasper parseUnaryOperator(); 89029f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper return; 8913618e6fae8b734ad94221d941417c12d4bd1e3a8Daniel Jasper } 89229f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 893b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek FormatToken *Start = Current; 894d489f8ceb735458b0e1f814e3f952b154f49c025Daniel Jasper FormatToken *LatestOperator = NULL; 89529f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 896237d4c1c785be13656bff6c09e5b7ccd066ff5baDaniel Jasper while (Current) { 89729f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper // Consume operators with higher precedence. 898bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper parse(Precedence + 1); 89929f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 9003618e6fae8b734ad94221d941417c12d4bd1e3a8Daniel Jasper int CurrentPrecedence = getCurrentPrecedence(); 9013618e6fae8b734ad94221d941417c12d4bd1e3a8Daniel Jasper 9023618e6fae8b734ad94221d941417c12d4bd1e3a8Daniel Jasper if (Current && Current->Type == TT_ObjCSelectorName && 9033618e6fae8b734ad94221d941417c12d4bd1e3a8Daniel Jasper Precedence == CurrentPrecedence) 9043618e6fae8b734ad94221d941417c12d4bd1e3a8Daniel Jasper Start = Current; 905237d4c1c785be13656bff6c09e5b7ccd066ff5baDaniel Jasper 90629f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper // At the end of the line or when an operator with higher precedence is 90729f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper // found, insert fake parenthesis and return. 908ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper if (Current == NULL || Current->closesScope() || 909d489f8ceb735458b0e1f814e3f952b154f49c025Daniel Jasper (CurrentPrecedence != -1 && CurrentPrecedence < Precedence)) { 910d489f8ceb735458b0e1f814e3f952b154f49c025Daniel Jasper if (LatestOperator) { 911d489f8ceb735458b0e1f814e3f952b154f49c025Daniel Jasper if (Precedence == PrecedenceArrowAndPeriod) { 912d489f8ceb735458b0e1f814e3f952b154f49c025Daniel Jasper LatestOperator->LastInChainOfCalls = true; 913d489f8ceb735458b0e1f814e3f952b154f49c025Daniel Jasper // Call expressions don't have a binary operator precedence. 914d489f8ceb735458b0e1f814e3f952b154f49c025Daniel Jasper addFakeParenthesis(Start, prec::Unknown); 915d489f8ceb735458b0e1f814e3f952b154f49c025Daniel Jasper } else { 916d489f8ceb735458b0e1f814e3f952b154f49c025Daniel Jasper addFakeParenthesis(Start, prec::Level(Precedence)); 917d489f8ceb735458b0e1f814e3f952b154f49c025Daniel Jasper } 918d489f8ceb735458b0e1f814e3f952b154f49c025Daniel Jasper } 91929f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper return; 92029f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper } 92129f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 92229f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper // Consume scopes: (), [], <> and {} 923ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper if (Current->opensScope()) { 924ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper while (Current && !Current->closesScope()) { 92529f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper next(); 92629f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper parse(); 92729f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper } 92829f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper next(); 92929f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper } else { 93029f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper // Operator found. 931237d4c1c785be13656bff6c09e5b7ccd066ff5baDaniel Jasper if (CurrentPrecedence == Precedence) 932d489f8ceb735458b0e1f814e3f952b154f49c025Daniel Jasper LatestOperator = Current; 93329f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 93429f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper next(); 93529f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper } 93629f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper } 93729f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper } 93829f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 93929f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasperprivate: 9403618e6fae8b734ad94221d941417c12d4bd1e3a8Daniel Jasper /// \brief Gets the precedence (+1) of the given token for binary operators 9413618e6fae8b734ad94221d941417c12d4bd1e3a8Daniel Jasper /// and other tokens that we treat like binary operators. 9423618e6fae8b734ad94221d941417c12d4bd1e3a8Daniel Jasper int getCurrentPrecedence() { 9433618e6fae8b734ad94221d941417c12d4bd1e3a8Daniel Jasper if (Current) { 9443618e6fae8b734ad94221d941417c12d4bd1e3a8Daniel Jasper if (Current->Type == TT_ConditionalExpr) 945d489f8ceb735458b0e1f814e3f952b154f49c025Daniel Jasper return prec::Conditional; 9463618e6fae8b734ad94221d941417c12d4bd1e3a8Daniel Jasper else if (Current->is(tok::semi) || Current->Type == TT_InlineASMColon) 947d489f8ceb735458b0e1f814e3f952b154f49c025Daniel Jasper return 0; 9483618e6fae8b734ad94221d941417c12d4bd1e3a8Daniel Jasper else if (Current->Type == TT_BinaryOperator || Current->is(tok::comma)) 949d489f8ceb735458b0e1f814e3f952b154f49c025Daniel Jasper return Current->getPrecedence(); 9503618e6fae8b734ad94221d941417c12d4bd1e3a8Daniel Jasper else if (Current->Type == TT_ObjCSelectorName) 951d489f8ceb735458b0e1f814e3f952b154f49c025Daniel Jasper return prec::Assignment; 952d489f8ceb735458b0e1f814e3f952b154f49c025Daniel Jasper else if (Current->isOneOf(tok::period, tok::arrow)) 953d489f8ceb735458b0e1f814e3f952b154f49c025Daniel Jasper return PrecedenceArrowAndPeriod; 9543618e6fae8b734ad94221d941417c12d4bd1e3a8Daniel Jasper } 955d489f8ceb735458b0e1f814e3f952b154f49c025Daniel Jasper return -1; 9563618e6fae8b734ad94221d941417c12d4bd1e3a8Daniel Jasper } 9573618e6fae8b734ad94221d941417c12d4bd1e3a8Daniel Jasper 958c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper void addFakeParenthesis(FormatToken *Start, prec::Level Precedence) { 959c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper Start->FakeLParens.push_back(Precedence); 960db4813a3997fcf3864d1190f8021ef68e42cc057Daniel Jasper if (Precedence > prec::Unknown) 961db4813a3997fcf3864d1190f8021ef68e42cc057Daniel Jasper Start->StartsBinaryExpression = true; 962db4813a3997fcf3864d1190f8021ef68e42cc057Daniel Jasper if (Current) { 963c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper ++Current->Previous->FakeRParens; 964db4813a3997fcf3864d1190f8021ef68e42cc057Daniel Jasper if (Precedence > prec::Unknown) 965db4813a3997fcf3864d1190f8021ef68e42cc057Daniel Jasper Current->Previous->EndsBinaryExpression = true; 966db4813a3997fcf3864d1190f8021ef68e42cc057Daniel Jasper } 967c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper } 968c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper 9693618e6fae8b734ad94221d941417c12d4bd1e3a8Daniel Jasper /// \brief Parse unary operator expressions and surround them with fake 9703618e6fae8b734ad94221d941417c12d4bd1e3a8Daniel Jasper /// parentheses if appropriate. 9713618e6fae8b734ad94221d941417c12d4bd1e3a8Daniel Jasper void parseUnaryOperator() { 972d489f8ceb735458b0e1f814e3f952b154f49c025Daniel Jasper if (Current == NULL || Current->Type != TT_UnaryOperator) { 973d489f8ceb735458b0e1f814e3f952b154f49c025Daniel Jasper parse(PrecedenceArrowAndPeriod); 9743618e6fae8b734ad94221d941417c12d4bd1e3a8Daniel Jasper return; 975d489f8ceb735458b0e1f814e3f952b154f49c025Daniel Jasper } 9763618e6fae8b734ad94221d941417c12d4bd1e3a8Daniel Jasper 9773618e6fae8b734ad94221d941417c12d4bd1e3a8Daniel Jasper FormatToken *Start = Current; 9783618e6fae8b734ad94221d941417c12d4bd1e3a8Daniel Jasper next(); 979d489f8ceb735458b0e1f814e3f952b154f49c025Daniel Jasper parseUnaryOperator(); 9803618e6fae8b734ad94221d941417c12d4bd1e3a8Daniel Jasper 9813618e6fae8b734ad94221d941417c12d4bd1e3a8Daniel Jasper // The actual precedence doesn't matter. 982d489f8ceb735458b0e1f814e3f952b154f49c025Daniel Jasper addFakeParenthesis(Start, prec::Unknown); 9833618e6fae8b734ad94221d941417c12d4bd1e3a8Daniel Jasper } 9843618e6fae8b734ad94221d941417c12d4bd1e3a8Daniel Jasper 985c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper void parseConditionalExpr() { 986c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper FormatToken *Start = Current; 987d489f8ceb735458b0e1f814e3f952b154f49c025Daniel Jasper parse(prec::LogicalOr); 988c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper if (!Current || !Current->is(tok::question)) 989c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper return; 990c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper next(); 991d489f8ceb735458b0e1f814e3f952b154f49c025Daniel Jasper parse(prec::LogicalOr); 992c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper if (!Current || Current->Type != TT_ConditionalExpr) 993c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper return; 994c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper next(); 995c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper parseConditionalExpr(); 996c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper addFakeParenthesis(Start, prec::Conditional); 997c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper } 998c01897c3f6139304ed25e3f673bef77be209617fDaniel Jasper 99929f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper void next() { 1000d71b15badeecdc049440103ef044f9cdf5e1359cAlexander Kornienko if (Current) 1001d71b15badeecdc049440103ef044f9cdf5e1359cAlexander Kornienko Current = Current->Next; 1002d71b15badeecdc049440103ef044f9cdf5e1359cAlexander Kornienko while (Current && Current->isTrailingComment()) 1003b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek Current = Current->Next; 100429f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper } 100529f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 1006b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek FormatToken *Current; 100729f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper}; 100829f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 100914e66498781b7d81639bdc48716e09700552ac21Craig Topper} // end anonymous namespace 101014e66498781b7d81639bdc48716e09700552ac21Craig Topper 1011b77d741691a2775b5c31e29f021203cc659c26dfDaniel Jaspervoid 1012b77d741691a2775b5c31e29f021203cc659c26dfDaniel JasperTokenAnnotator::setCommentLineLevels(SmallVectorImpl<AnnotatedLine *> &Lines) { 1013b77d741691a2775b5c31e29f021203cc659c26dfDaniel Jasper if (Lines.empty()) 1014b77d741691a2775b5c31e29f021203cc659c26dfDaniel Jasper return; 1015b77d741691a2775b5c31e29f021203cc659c26dfDaniel Jasper 1016b77d741691a2775b5c31e29f021203cc659c26dfDaniel Jasper const AnnotatedLine *NextNonCommentLine = NULL; 1017b77d741691a2775b5c31e29f021203cc659c26dfDaniel Jasper for (unsigned i = Lines.size() - 1; i > 0; --i) { 1018b77d741691a2775b5c31e29f021203cc659c26dfDaniel Jasper if (NextNonCommentLine && Lines[i]->First->is(tok::comment) && 1019b77d741691a2775b5c31e29f021203cc659c26dfDaniel Jasper !Lines[i]->First->Next) 1020b77d741691a2775b5c31e29f021203cc659c26dfDaniel Jasper Lines[i]->Level = NextNonCommentLine->Level; 1021b77d741691a2775b5c31e29f021203cc659c26dfDaniel Jasper else 1022b77d741691a2775b5c31e29f021203cc659c26dfDaniel Jasper NextNonCommentLine = 1023b77d741691a2775b5c31e29f021203cc659c26dfDaniel Jasper Lines[i]->First->isNot(tok::r_brace) ? Lines[i] : NULL; 1024b77d741691a2775b5c31e29f021203cc659c26dfDaniel Jasper } 1025b77d741691a2775b5c31e29f021203cc659c26dfDaniel Jasper} 1026b77d741691a2775b5c31e29f021203cc659c26dfDaniel Jasper 10278ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jaspervoid TokenAnnotator::annotate(AnnotatedLine &Line) { 1028b77d741691a2775b5c31e29f021203cc659c26dfDaniel Jasper setCommentLineLevels(Line.Children); 1029b77d741691a2775b5c31e29f021203cc659c26dfDaniel Jasper for (SmallVectorImpl<AnnotatedLine *>::iterator I = Line.Children.begin(), 1030b77d741691a2775b5c31e29f021203cc659c26dfDaniel Jasper E = Line.Children.end(); 1031567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper I != E; ++I) { 1032567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper annotate(**I); 1033567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper } 1034d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper AnnotatingParser Parser(Style, Line, Ident_in); 103532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Line.Type = Parser.parseLine(); 103632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Line.Type == LT_Invalid) 103732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return; 103832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 103929f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper ExpressionParser ExprParser(Line); 104029f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper ExprParser.parse(); 104129f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 1042b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek if (Line.First->Type == TT_ObjCMethodSpecifier) 104332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Line.Type = LT_ObjCMethodDecl; 1044b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek else if (Line.First->Type == TT_ObjCDecl) 104532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Line.Type = LT_ObjCDecl; 1046b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek else if (Line.First->Type == TT_ObjCProperty) 104732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Line.Type = LT_ObjCProperty; 104832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 1049b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek Line.First->SpacesRequiredBefore = 1; 1050b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek Line.First->CanBreakBefore = Line.First->MustBreakBefore; 105132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} 105232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 10538ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jaspervoid TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) { 105483a7dcdf5fce1bdf74ce985419d77a41a51abfa2Alexander Kornienko Line.First->TotalLength = 105583a7dcdf5fce1bdf74ce985419d77a41a51abfa2Alexander Kornienko Line.First->IsMultiline ? Style.ColumnLimit : Line.First->ColumnWidth; 1056b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek if (!Line.First->Next) 10578ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper return; 1058b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek FormatToken *Current = Line.First->Next; 10598ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper while (Current != NULL) { 1060729a743b317d877df3978e88a4a247d2edbf2090Daniel Jasper if (Current->Type == TT_LineComment) 1061729a743b317d877df3978e88a4a247d2edbf2090Daniel Jasper Current->SpacesRequiredBefore = Style.SpacesBeforeTrailingComments; 1062b18c258390f794d8803ef5ebbb56fb77bfea7ba4Alexander Kornienko else if (Current->SpacesRequiredBefore == 0 && 1063b18c258390f794d8803ef5ebbb56fb77bfea7ba4Alexander Kornienko spaceRequiredBefore(Line, *Current)) 1064b18c258390f794d8803ef5ebbb56fb77bfea7ba4Alexander Kornienko Current->SpacesRequiredBefore = 1; 10658ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper 1066ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasper Current->MustBreakBefore = 1067ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasper Current->MustBreakBefore || mustBreakBefore(Line, *Current); 1068ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasper 10698ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->CanBreakBefore = 10708ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->MustBreakBefore || canBreakBefore(Line, *Current); 1071567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper if (Current->MustBreakBefore || !Current->Children.empty() || 107283a7dcdf5fce1bdf74ce985419d77a41a51abfa2Alexander Kornienko Current->IsMultiline) 1073b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek Current->TotalLength = Current->Previous->TotalLength + Style.ColumnLimit; 10748ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper else 10752a409b62126d8f0b8f5749d5ed435ad2b394b526Daniel Jasper Current->TotalLength = Current->Previous->TotalLength + 107683a7dcdf5fce1bdf74ce985419d77a41a51abfa2Alexander Kornienko Current->ColumnWidth + 10772a409b62126d8f0b8f5749d5ed435ad2b394b526Daniel Jasper Current->SpacesRequiredBefore; 10788ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper // FIXME: Only calculate this if CanBreakBefore is true once static 10798ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper // initializers etc. are sorted out. 10808ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper // FIXME: Move magic numbers to a better place. 10818ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->SplitPenalty = 10828ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper 20 * Current->BindingStrength + splitPenalty(Line, *Current); 10838ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper 1084b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek Current = Current->Next; 108532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 1086bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper 1087e573c3f7fc40e813559ab4ff1e7eec4f66f1a50fManuel Klimek calculateUnbreakableTailLengths(Line); 1088d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper for (Current = Line.First; Current != NULL; Current = Current->Next) { 1089d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper if (Current->Role) 1090d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper Current->Role->precomputeFormattingInfos(Current); 1091d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper } 1092d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper 1093567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper DEBUG({ printDebugInfo(Line); }); 1094567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper 1095b77d741691a2775b5c31e29f021203cc659c26dfDaniel Jasper for (SmallVectorImpl<AnnotatedLine *>::iterator I = Line.Children.begin(), 1096b77d741691a2775b5c31e29f021203cc659c26dfDaniel Jasper E = Line.Children.end(); 1097567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper I != E; ++I) { 1098567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper calculateFormattingInformation(**I); 1099567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper } 110032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} 110132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 1102e573c3f7fc40e813559ab4ff1e7eec4f66f1a50fManuel Klimekvoid TokenAnnotator::calculateUnbreakableTailLengths(AnnotatedLine &Line) { 1103e573c3f7fc40e813559ab4ff1e7eec4f66f1a50fManuel Klimek unsigned UnbreakableTailLength = 0; 1104b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek FormatToken *Current = Line.Last; 1105e573c3f7fc40e813559ab4ff1e7eec4f66f1a50fManuel Klimek while (Current != NULL) { 1106e573c3f7fc40e813559ab4ff1e7eec4f66f1a50fManuel Klimek Current->UnbreakableTailLength = UnbreakableTailLength; 1107e573c3f7fc40e813559ab4ff1e7eec4f66f1a50fManuel Klimek if (Current->CanBreakBefore || 1108e573c3f7fc40e813559ab4ff1e7eec4f66f1a50fManuel Klimek Current->isOneOf(tok::comment, tok::string_literal)) { 1109e573c3f7fc40e813559ab4ff1e7eec4f66f1a50fManuel Klimek UnbreakableTailLength = 0; 1110e573c3f7fc40e813559ab4ff1e7eec4f66f1a50fManuel Klimek } else { 1111e573c3f7fc40e813559ab4ff1e7eec4f66f1a50fManuel Klimek UnbreakableTailLength += 111283a7dcdf5fce1bdf74ce985419d77a41a51abfa2Alexander Kornienko Current->ColumnWidth + Current->SpacesRequiredBefore; 1113e573c3f7fc40e813559ab4ff1e7eec4f66f1a50fManuel Klimek } 1114b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek Current = Current->Previous; 1115e573c3f7fc40e813559ab4ff1e7eec4f66f1a50fManuel Klimek } 1116e573c3f7fc40e813559ab4ff1e7eec4f66f1a50fManuel Klimek} 1117e573c3f7fc40e813559ab4ff1e7eec4f66f1a50fManuel Klimek 11188ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasperunsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line, 1119b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek const FormatToken &Tok) { 1120b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek const FormatToken &Left = *Tok.Previous; 1121b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek const FormatToken &Right = Tok; 112232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 11235ad390d27f8f7cb6628bc2c32beba4d25bc2718bDaniel Jasper if (Left.is(tok::semi)) 11245ad390d27f8f7cb6628bc2c32beba4d25bc2718bDaniel Jasper return 0; 11255ad390d27f8f7cb6628bc2c32beba4d25bc2718bDaniel Jasper if (Left.is(tok::comma)) 11265ad390d27f8f7cb6628bc2c32beba4d25bc2718bDaniel Jasper return 1; 1127011c35dabb4c8abcb7389d8fbc6316f8f23576abDaniel Jasper if (Right.is(tok::l_square)) 1128011c35dabb4c8abcb7389d8fbc6316f8f23576abDaniel Jasper return 150; 11295ad390d27f8f7cb6628bc2c32beba4d25bc2718bDaniel Jasper 11306561f6a13b79ed752748ede590792191edf78ce8Daniel Jasper if (Right.Type == TT_StartOfName || Right.is(tok::kw_operator)) { 1131b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek if (Line.First->is(tok::kw_for) && Right.PartOfMultiVariableDeclStmt) 11323c08a818a6ac9115fe8880af9bbf5a0a87bdffaaDaniel Jasper return 3; 1133c18cff311118fc6a30929468fc82b2b35cbd7fbfDaniel Jasper if (Left.Type == TT_StartOfName) 1134c18cff311118fc6a30929468fc82b2b35cbd7fbfDaniel Jasper return 20; 113592495a8032d8624495a0ce769d5a6cdeba2dc8d8Daniel Jasper if (Line.MightBeFunctionDecl && Right.BindingStrength == 1) 11363c08a818a6ac9115fe8880af9bbf5a0a87bdffaaDaniel Jasper // FIXME: Clean up hack of using BindingStrength to find top-level names. 11373c08a818a6ac9115fe8880af9bbf5a0a87bdffaaDaniel Jasper return Style.PenaltyReturnTypeOnItsOwnLine; 113892495a8032d8624495a0ce769d5a6cdeba2dc8d8Daniel Jasper return 200; 11393c08a818a6ac9115fe8880af9bbf5a0a87bdffaaDaniel Jasper } 114032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::equal) && Right.is(tok::l_brace)) 114132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return 150; 1142198c8bfee0b33ab0ed0c54224f460868f1c18e95Daniel Jasper if (Left.Type == TT_CastRParen) 1143198c8bfee0b33ab0ed0c54224f460868f1c18e95Daniel Jasper return 100; 114432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::coloncolon)) 114532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return 500; 11466b119d63f5036344acd4e00a6ff2b3c72f26966fDaniel Jasper if (Left.isOneOf(tok::kw_class, tok::kw_struct)) 11476b119d63f5036344acd4e00a6ff2b3c72f26966fDaniel Jasper return 5000; 114832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 11496cabab48dacc1317821f8f078ed2d4c603b67affDaniel Jasper if (Left.Type == TT_RangeBasedForLoopColon || 11506cabab48dacc1317821f8f078ed2d4c603b67affDaniel Jasper Left.Type == TT_InheritanceColon) 115184a1a63b034744b68a27ec171dca5b1b7cf303f0Daniel Jasper return 2; 115232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 1153d3fef0fe26da19685bdec6a1bd844505f604d593Daniel Jasper if (Right.isMemberAccess()) { 11542f0a020d29286805e48b74b127fbf153af2c4ce7Daniel Jasper if (Left.isOneOf(tok::r_paren, tok::r_square) && Left.MatchingParen && 11552f0a020d29286805e48b74b127fbf153af2c4ce7Daniel Jasper Left.MatchingParen->ParameterCount > 0) 1156518ee34467c0722e253a58efea20456e96aa5802Daniel Jasper return 20; // Should be smaller than breaking at a nested comma. 115732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return 150; 115832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 115932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 116020a0f8cff96505abb65233a2eaf3af3cd8536cd2Daniel Jasper // Breaking before a trailing 'const' or not-function-like annotation is bad. 1161aa9e7b18a88d715b63e7b65d1b26a1759decc177Daniel Jasper if (Left.is(tok::r_paren) && Line.Type != LT_ObjCProperty && 116220a0f8cff96505abb65233a2eaf3af3cd8536cd2Daniel Jasper (Right.is(tok::kw_const) || (Right.is(tok::identifier) && Right.Next && 116320a0f8cff96505abb65233a2eaf3af3cd8536cd2Daniel Jasper Right.Next->isNot(tok::l_paren)))) 116453eb05ac6a00b95baf5680d9378ae8819dd09471Daniel Jasper return 100; 11655ad72bb8eb8e5cc4c061ccd28632295213d319dbDaniel Jasper 116632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // In for-loops, prefer breaking at ',' and ';'. 1167b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek if (Line.First->is(tok::kw_for) && Left.is(tok::equal)) 11687d81281fc39f6d40d86be6600adba13c05b4a639Daniel Jasper return 4; 116932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 117032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // In Objective-C method expressions, prefer breaking before "param:" over 117132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // breaking after it. 117263d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper if (Right.Type == TT_ObjCSelectorName) 117332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return 0; 117463d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper if (Left.is(tok::colon) && Left.Type == TT_ObjCMethodExpr) 117532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return 20; 117632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 11771407bee187d7b964d5293ac8bf4f7a490c78cec6Daniel Jasper if (Left.is(tok::l_paren) && Line.MightBeFunctionDecl) 11781407bee187d7b964d5293ac8bf4f7a490c78cec6Daniel Jasper return 100; 1179ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper if (Left.opensScope()) 1180e60084d1e8a62716b80872f10e9828fbbb3cadfcDaniel Jasper return Left.ParameterCount > 1 ? prec::Comma : 19; 118132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 11824e8a7b4a95962f63a938c0d21c9aca0a51b78345Daniel Jasper if (Right.is(tok::lessless)) { 11834e8a7b4a95962f63a938c0d21c9aca0a51b78345Daniel Jasper if (Left.is(tok::string_literal)) { 118400895106f9ed602af67984ec4d225a0cdc8c12afAlexander Kornienko StringRef Content = Left.TokenText; 118520376989402fb187c0bc48209f46560b9e402ea2Daniel Jasper if (Content.startswith("\"")) 118620376989402fb187c0bc48209f46560b9e402ea2Daniel Jasper Content = Content.drop_front(1); 118720376989402fb187c0bc48209f46560b9e402ea2Daniel Jasper if (Content.endswith("\"")) 118820376989402fb187c0bc48209f46560b9e402ea2Daniel Jasper Content = Content.drop_back(1); 118920376989402fb187c0bc48209f46560b9e402ea2Daniel Jasper Content = Content.trim(); 1190bfa1edd8247b80e951a570ff2486fe5fa9898c41Daniel Jasper if (Content.size() > 1 && 1191bfa1edd8247b80e951a570ff2486fe5fa9898c41Daniel Jasper (Content.back() == ':' || Content.back() == '=')) 11929637dda705e39110bfff66742542a58dd2470ad2Daniel Jasper return 25; 11934e8a7b4a95962f63a938c0d21c9aca0a51b78345Daniel Jasper } 11940c368787d9d1f92a3408b71b3f074a06edaa6bdeDaniel Jasper return 1; // Breaking at a << is really cheap. 11954e8a7b4a95962f63a938c0d21c9aca0a51b78345Daniel Jasper } 119632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.Type == TT_ConditionalExpr) 1197518ee34467c0722e253a58efea20456e96aa5802Daniel Jasper return prec::Conditional; 1198b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek prec::Level Level = Left.getPrecedence(); 119932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 120032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Level != prec::Unknown) 120132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return Level; 1202248497199bc56e86d1c089beb9529f3b3d77abb1Daniel Jasper 120332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return 3; 120432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} 120532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 12068ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasperbool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, 1207b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek const FormatToken &Left, 1208b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek const FormatToken &Right) { 120932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::hashhash)) 121032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return Left.is(tok::hash); 1211e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko if (Left.isOneOf(tok::hashhash, tok::hash)) 121232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return Right.is(tok::hash); 12137df56bfcf7186f73c99564cd54216f07a8db7352Daniel Jasper if (Left.is(tok::l_paren) && Right.is(tok::r_paren)) 12147df56bfcf7186f73c99564cd54216f07a8db7352Daniel Jasper return Style.SpaceInEmptyParentheses; 12157df56bfcf7186f73c99564cd54216f07a8db7352Daniel Jasper if (Left.is(tok::l_paren) || Right.is(tok::r_paren)) 121634f3d05d0ee625dfcac951e2851f212c4c1a8b83Daniel Jasper return (Right.Type == TT_CastRParen || 121734f3d05d0ee625dfcac951e2851f212c4c1a8b83Daniel Jasper (Left.MatchingParen && Left.MatchingParen->Type == TT_CastRParen)) 12187df56bfcf7186f73c99564cd54216f07a8db7352Daniel Jasper ? Style.SpacesInCStyleCastParentheses 12197df56bfcf7186f73c99564cd54216f07a8db7352Daniel Jasper : Style.SpacesInParentheses; 12207df56bfcf7186f73c99564cd54216f07a8db7352Daniel Jasper if (Right.isOneOf(tok::semi, tok::comma)) 122132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 122232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::less) && 122332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper (Left.is(tok::kw_template) || 122432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper (Line.Type == LT_ObjCDecl && Style.ObjCSpaceBeforeProtocolList))) 122532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 122632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::arrow) || Right.is(tok::arrow)) 122732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 1228e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko if (Left.isOneOf(tok::exclaim, tok::tilde)) 122932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 123032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::at) && 1231e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko Right.isOneOf(tok::identifier, tok::string_literal, tok::char_constant, 1232e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko tok::numeric_constant, tok::l_paren, tok::l_brace, 1233e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko tok::kw_true, tok::kw_false)) 123432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 123532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::coloncolon)) 123632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 123732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::coloncolon)) 123878a4e619e775b0dbaa10c9feaea0adf1d3dfe507Daniel Jasper return (Left.is(tok::less) && Style.Standard == FormatStyle::LS_Cpp03) || 123978a4e619e775b0dbaa10c9feaea0adf1d3dfe507Daniel Jasper !Left.isOneOf(tok::identifier, tok::greater, tok::l_paren, 124078a4e619e775b0dbaa10c9feaea0adf1d3dfe507Daniel Jasper tok::r_paren, tok::less); 1241e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko if (Left.is(tok::less) || Right.isOneOf(tok::greater, tok::less)) 124232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 1243c47d7f1237b022eabbbdcebf77506e8a81aa54bdDaniel Jasper if (Right.is(tok::ellipsis)) 1244b3c887dcb70220eced72935725cd94d7e8325912Daniel Jasper return Left.Tok.isLiteral(); 124531e44f7a5d50ab8f7f623a7d2e18d5d877ef400dManuel Klimek if (Left.is(tok::l_square) && Right.is(tok::amp)) 124631e44f7a5d50ab8f7f623a7d2e18d5d877ef400dManuel Klimek return false; 12473fd9ccdd9f8d259bcf518e7056cfd419d992e984Alexander Kornienko if (Right.Type == TT_PointerOrReference) 1248b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek return Left.Tok.isLiteral() || 12493fd9ccdd9f8d259bcf518e7056cfd419d992e984Alexander Kornienko ((Left.Type != TT_PointerOrReference) && Left.isNot(tok::l_paren) && 12503fd9ccdd9f8d259bcf518e7056cfd419d992e984Alexander Kornienko !Style.PointerBindsToType); 12513ff4a2fea4aa6e5182b7799ccb4352e56961a212Daniel Jasper if (Right.Type == TT_FunctionTypeLParen && Left.isNot(tok::l_paren) && 1252395228fdc343df39c2507e414dc1406a185c6d37Daniel Jasper (Left.Type != TT_PointerOrReference || Style.PointerBindsToType)) 1253395228fdc343df39c2507e414dc1406a185c6d37Daniel Jasper return true; 12543fd9ccdd9f8d259bcf518e7056cfd419d992e984Alexander Kornienko if (Left.Type == TT_PointerOrReference) 12553a1847e0a1810a0b1b963182abc59114cc5ff53dDaniel Jasper return Right.Tok.isLiteral() || Right.Type == TT_BlockComment || 12569322aaee900b872c98f8fc10b38a231cb1e9b57aDaniel Jasper ((Right.Type != TT_PointerOrReference) && 125781d2d38d2d774a2550fa0d2efffa707e7a53b39cDaniel Jasper Right.isNot(tok::l_paren) && Style.PointerBindsToType && 1258b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek Left.Previous && 1259b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek !Left.Previous->isOneOf(tok::l_paren, tok::coloncolon)); 126032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::star) && Left.is(tok::l_paren)) 126132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 1262051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber if (Left.is(tok::l_square)) 1263a07aa665a12ab23bef7aa4aedfe113dd8b13da57Daniel Jasper return Left.Type == TT_ArrayInitializerLSquare && 1264a07aa665a12ab23bef7aa4aedfe113dd8b13da57Daniel Jasper Right.isNot(tok::r_square); 1265051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber if (Right.is(tok::r_square)) 1266a07aa665a12ab23bef7aa4aedfe113dd8b13da57Daniel Jasper return Right.MatchingParen && 1267a07aa665a12ab23bef7aa4aedfe113dd8b13da57Daniel Jasper Right.MatchingParen->Type == TT_ArrayInitializerLSquare; 1268ec17226e82979592c16c7815d2368240201d18feDaniel Jasper if (Right.is(tok::l_square) && Right.Type != TT_ObjCMethodExpr && 1269567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper Right.Type != TT_LambdaLSquare && Left.isNot(tok::numeric_constant)) 127032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 127132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::colon)) 127232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return Left.Type != TT_ObjCMethodExpr; 127332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::colon)) 1274ab3ce592d027e3a10fb21e703cab1507f8d9bb03Daniel Jasper return Right.Type != TT_ObjCMethodExpr && !Left.is(tok::question); 127532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::l_paren)) { 1276e0fa4c55a4bc6d2bbe0d9d657287c037158d5357Daniel Jasper if (Left.is(tok::r_paren) && Left.MatchingParen && 1277e0fa4c55a4bc6d2bbe0d9d657287c037158d5357Daniel Jasper Left.MatchingParen->Previous && 1278e0fa4c55a4bc6d2bbe0d9d657287c037158d5357Daniel Jasper Left.MatchingParen->Previous->is(tok::kw___attribute)) 1279e0fa4c55a4bc6d2bbe0d9d657287c037158d5357Daniel Jasper return true; 1280e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko return Line.Type == LT_ObjCDecl || 128134f3d05d0ee625dfcac951e2851f212c4c1a8b83Daniel Jasper Left.isOneOf(tok::kw_return, tok::kw_new, tok::kw_delete, 128234f3d05d0ee625dfcac951e2851f212c4c1a8b83Daniel Jasper tok::semi) || 128334f3d05d0ee625dfcac951e2851f212c4c1a8b83Daniel Jasper (Style.SpaceAfterControlStatementKeyword && 128434f3d05d0ee625dfcac951e2851f212c4c1a8b83Daniel Jasper Left.isOneOf(tok::kw_if, tok::kw_for, tok::kw_while, tok::kw_switch, 128534f3d05d0ee625dfcac951e2851f212c4c1a8b83Daniel Jasper tok::kw_catch)); 128632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 1287b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek if (Left.is(tok::at) && Right.Tok.getObjCKeywordID() != tok::objc_not_keyword) 128832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 128932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::l_brace) && Right.is(tok::r_brace)) 1290567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper return !Left.Children.empty(); // No spaces in "{}". 12912424eefa6936ec2dc35188e19c99e2f85428b52eDaniel Jasper if (Left.is(tok::l_brace) || Right.is(tok::r_brace)) 1292b5dc3f4f53981b681a565cdf1d49f18e817541ffDaniel Jasper return !Style.Cpp11BracedListStyle; 12931bee0738b67b784f08d5e2f8351920260c9cfb1dDaniel Jasper if (Right.Type == TT_UnaryOperator) 12941bee0738b67b784f08d5e2f8351920260c9cfb1dDaniel Jasper return !Left.isOneOf(tok::l_paren, tok::l_square, tok::at) && 12951bee0738b67b784f08d5e2f8351920260c9cfb1dDaniel Jasper (Left.isNot(tok::colon) || Left.Type != TT_ObjCMethodExpr); 1296ce93356e2719d2992763ea747b65beada99f4c9bDaniel Jasper if (Left.isOneOf(tok::identifier, tok::greater, tok::r_square) && 129731e44f7a5d50ab8f7f623a7d2e18d5d877ef400dManuel Klimek Right.is(tok::l_brace) && Right.getNextNonComment() && 129831e44f7a5d50ab8f7f623a7d2e18d5d877ef400dManuel Klimek Right.BlockKind != BK_Block) 129932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 13005ad390d27f8f7cb6628bc2c32beba4d25bc2718bDaniel Jasper if (Left.is(tok::period) || Right.is(tok::period)) 13015ad390d27f8f7cb6628bc2c32beba4d25bc2718bDaniel Jasper return false; 1302861576b8019392f15c803ac14a4bc31fbd93aab2Nico Weber if (Left.Type == TT_BlockComment && Left.TokenText.endswith("=*/")) 1303861576b8019392f15c803ac14a4bc31fbd93aab2Nico Weber return false; 1304daa07e9ee76d438efa3c7e2c54b4d3d3ed19ea27Alexander Kornienko if (Right.is(tok::hash) && Left.is(tok::identifier) && Left.TokenText == "L") 1305daa07e9ee76d438efa3c7e2c54b4d3d3ed19ea27Alexander Kornienko return false; 130632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 130732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} 130832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 13098ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasperbool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, 1310b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek const FormatToken &Tok) { 1311b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek if (Tok.Tok.getIdentifierInfo() && Tok.Previous->Tok.getIdentifierInfo()) 13122b4c924f85e156d66c01b3f16c850892c47dcc7aDaniel Jasper return true; // Never ever merge two identifiers. 13131d82b1a33bcfe85f4834fb6920517ed07e9355d3Daniel Jasper if (Tok.Previous->Type == TT_ImplicitStringLiteral) 13141d82b1a33bcfe85f4834fb6920517ed07e9355d3Daniel Jasper return Tok.WhitespaceRange.getBegin() != Tok.WhitespaceRange.getEnd(); 131532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Line.Type == LT_ObjCMethodDecl) { 1316b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek if (Tok.Previous->Type == TT_ObjCMethodSpecifier) 131732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 1318b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek if (Tok.Previous->is(tok::r_paren) && Tok.is(tok::identifier)) 131932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // Don't space between ')' and <id> 132032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 132132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 132232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Line.Type == LT_ObjCProperty && 1323b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek (Tok.is(tok::equal) || Tok.Previous->is(tok::equal))) 132432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 132532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 13262ca3741a962ded08866596577aaee2f4ab74c955Daniel Jasper if (Tok.Type == TT_TrailingReturnArrow || 13272ca3741a962ded08866596577aaee2f4ab74c955Daniel Jasper Tok.Previous->Type == TT_TrailingReturnArrow) 13282ca3741a962ded08866596577aaee2f4ab74c955Daniel Jasper return true; 1329b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek if (Tok.Previous->is(tok::comma)) 133032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 13319c3c7b3130bc72b3f50703c11b85152b1264fc90Daniel Jasper if (Tok.is(tok::comma)) 13329c3c7b3130bc72b3f50703c11b85152b1264fc90Daniel Jasper return false; 133332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.Type == TT_CtorInitializerColon || Tok.Type == TT_ObjCBlockLParen) 133432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 1335b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek if (Tok.Previous->Tok.is(tok::kw_operator)) 13362b4c924f85e156d66c01b3f16c850892c47dcc7aDaniel Jasper return false; 13372b4c924f85e156d66c01b3f16c850892c47dcc7aDaniel Jasper if (Tok.Type == TT_OverloadedOperatorLParen) 133832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 133932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.is(tok::colon)) 1340b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek return !Line.First->isOneOf(tok::kw_case, tok::kw_default) && 1341ab3ce592d027e3a10fb21e703cab1507f8d9bb03Daniel Jasper Tok.getNextNonComment() != NULL && Tok.Type != TT_ObjCMethodExpr && 1342ab3ce592d027e3a10fb21e703cab1507f8d9bb03Daniel Jasper !Tok.Previous->is(tok::question); 1343b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek if (Tok.Previous->Type == TT_UnaryOperator || 1344b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek Tok.Previous->Type == TT_CastRParen) 134532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 1346b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek if (Tok.Previous->is(tok::greater) && Tok.is(tok::greater)) { 134729f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper return Tok.Type == TT_TemplateCloser && 1348b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek Tok.Previous->Type == TT_TemplateCloser && 134929f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper Style.Standard != FormatStyle::LS_Cpp11; 135032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 135154a38bd5cf243310290f34b43fc940a498a00f90Alexander Kornienko if (Tok.isOneOf(tok::arrowstar, tok::periodstar) || 1352b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek Tok.Previous->isOneOf(tok::arrowstar, tok::periodstar)) 13539c3c7b3130bc72b3f50703c11b85152b1264fc90Daniel Jasper return false; 13549b4de85e2f47a01974f451d21fed0276ff912e32Daniel Jasper if (!Style.SpaceBeforeAssignmentOperators && 13559b4de85e2f47a01974f451d21fed0276ff912e32Daniel Jasper Tok.getPrecedence() == prec::Assignment) 13569b4de85e2f47a01974f451d21fed0276ff912e32Daniel Jasper return false; 13571dc6f745eb19c94527503012d798dc9b9b5ba6daDaniel Jasper if ((Tok.Type == TT_BinaryOperator && !Tok.Previous->is(tok::l_paren)) || 13581dc6f745eb19c94527503012d798dc9b9b5ba6daDaniel Jasper Tok.Previous->Type == TT_BinaryOperator) 135932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 1360b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek if (Tok.Previous->Type == TT_TemplateCloser && Tok.is(tok::l_paren)) 136132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 1362a4dd982805e89a37a080350bf8de9069135c5a60Daniel Jasper if (Tok.is(tok::less) && Tok.Previous->isNot(tok::l_paren) && 1363a4dd982805e89a37a080350bf8de9069135c5a60Daniel Jasper Line.First->is(tok::hash)) 136432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 136532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.Type == TT_TrailingUnaryOperator) 136632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 1367b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek return spaceRequiredBetween(Line, *Tok.Previous, Tok); 136832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} 136932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 1370ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasperbool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line, 1371ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasper const FormatToken &Right) { 1372ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasper if (Right.is(tok::comment)) { 1373ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasper return Right.NewlinesBefore > 0; 1374ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasper } else if (Right.Previous->isTrailingComment() || 1375ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasper (Right.is(tok::string_literal) && 1376ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasper Right.Previous->is(tok::string_literal))) { 1377ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasper return true; 1378ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasper } else if (Right.Previous->IsUnterminatedLiteral) { 1379ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasper return true; 1380ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasper } else if (Right.is(tok::lessless) && Right.Next && 1381ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasper Right.Previous->is(tok::string_literal) && 1382ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasper Right.Next->is(tok::string_literal)) { 1383ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasper return true; 1384ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasper } else if (Right.Previous->ClosesTemplateDeclaration && 1385ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasper Right.Previous->MatchingParen && 1386ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasper Right.Previous->MatchingParen->BindingStrength == 1 && 1387ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasper Style.AlwaysBreakTemplateDeclarations) { 1388ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasper // FIXME: Fix horrible hack of using BindingStrength to find top-level <>. 1389ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasper return true; 1390ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasper } else if (Right.Type == TT_CtorInitializerComma && 139119ccb1227f5dc338d4b2d9dbbaeaa973c293f8d0Daniel Jasper Style.BreakConstructorInitializersBeforeComma && 139219ccb1227f5dc338d4b2d9dbbaeaa973c293f8d0Daniel Jasper !Style.ConstructorInitializerAllOnOneLineOrOnePerLine) { 1393ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasper return true; 1394ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasper } else if (Right.Previous->BlockKind == BK_Block && 139501fe9f9f320dd4342664376f24eb1a0d004d03c8Alexander Kornienko Right.Previous->isNot(tok::r_brace) && Right.isNot(tok::r_brace)) { 1396ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasper return true; 1397ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasper } else if (Right.is(tok::l_brace) && (Right.BlockKind == BK_Block)) { 1398ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasper return Style.BreakBeforeBraces == FormatStyle::BS_Allman; 1399ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasper } 1400ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasper return false; 1401ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasper} 1402ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasper 14038ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasperbool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, 1404b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek const FormatToken &Right) { 1405b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek const FormatToken &Left = *Right.Previous; 14066561f6a13b79ed752748ede590792191edf78ce8Daniel Jasper if (Right.Type == TT_StartOfName || Right.is(tok::kw_operator)) 140732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 1408f2ff8126e9e9df368f31b1f968d8fc80f99809b3Nico Weber if (Right.is(tok::colon) && 14093c6aea7ac63265c769b5fe09e213ab1c4cee111eDaniel Jasper (Right.Type == TT_DictLiteral || Right.Type == TT_ObjCMethodExpr)) 141032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 1411f2ff8126e9e9df368f31b1f968d8fc80f99809b3Nico Weber if (Left.is(tok::colon) && 14123c6aea7ac63265c769b5fe09e213ab1c4cee111eDaniel Jasper (Left.Type == TT_DictLiteral || Left.Type == TT_ObjCMethodExpr)) 141332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 141463d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper if (Right.Type == TT_ObjCSelectorName) 141532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 1416aa9e7b18a88d715b63e7b65d1b26a1759decc177Daniel Jasper if (Left.is(tok::r_paren) && Line.Type == LT_ObjCProperty) 1417aa9e7b18a88d715b63e7b65d1b26a1759decc177Daniel Jasper return true; 141832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.ClosesTemplateDeclaration) 141932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 1420ab3ce592d027e3a10fb21e703cab1507f8d9bb03Daniel Jasper if ((Right.Type == TT_ConditionalExpr && 1421ab3ce592d027e3a10fb21e703cab1507f8d9bb03Daniel Jasper !(Right.is(tok::colon) && Left.is(tok::question))) || 1422ab3ce592d027e3a10fb21e703cab1507f8d9bb03Daniel Jasper Right.is(tok::question)) 142332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 14246cabab48dacc1317821f8f078ed2d4c603b67affDaniel Jasper if (Right.Type == TT_RangeBasedForLoopColon || 1425c476ea976badd316e3afd0f34afe1f030a710117Daniel Jasper Right.Type == TT_OverloadedOperatorLParen || 1426c476ea976badd316e3afd0f34afe1f030a710117Daniel Jasper Right.Type == TT_OverloadedOperator) 14276cabab48dacc1317821f8f078ed2d4c603b67affDaniel Jasper return false; 1428c194c95036b7bf1281a6f2ed683f7c85ee5d2c20Daniel Jasper if (Left.Type == TT_RangeBasedForLoopColon) 142932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 14307d81281fc39f6d40d86be6600adba13c05b4a639Daniel Jasper if (Right.Type == TT_RangeBasedForLoopColon) 14317d81281fc39f6d40d86be6600adba13c05b4a639Daniel Jasper return false; 143232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.Type == TT_PointerOrReference || Left.Type == TT_TemplateCloser || 143332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left.Type == TT_UnaryOperator || Left.Type == TT_ConditionalExpr || 1434e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko Left.isOneOf(tok::question, tok::kw_operator)) 143532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 143632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::equal) && Line.Type == LT_VirtualFunctionDecl) 143732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 1438198c8bfee0b33ab0ed0c54224f460868f1c18e95Daniel Jasper if (Left.Previous) { 1439198c8bfee0b33ab0ed0c54224f460868f1c18e95Daniel Jasper if (Left.is(tok::l_paren) && Right.is(tok::l_paren) && 1440198c8bfee0b33ab0ed0c54224f460868f1c18e95Daniel Jasper Left.Previous->is(tok::kw___attribute)) 1441198c8bfee0b33ab0ed0c54224f460868f1c18e95Daniel Jasper return false; 14422ca3741a962ded08866596577aaee2f4ab74c955Daniel Jasper if (Left.is(tok::l_paren) && (Left.Previous->Type == TT_BinaryOperator || 14435e2169f94fca20bbfda317c222b156751a431c13Daniel Jasper Left.Previous->Type == TT_CastRParen)) 1444198c8bfee0b33ab0ed0c54224f460868f1c18e95Daniel Jasper return false; 1445198c8bfee0b33ab0ed0c54224f460868f1c18e95Daniel Jasper } 144632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 144765d2c3829494d254039683c73f95843c29c661b4Daniel Jasper if (Right.isTrailingComment()) 144832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // We rely on MustBreakBefore being set correctly here as we should not 144932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // change the "binding" behavior of a comment. 145032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 145132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 1452567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper if (Right.is(tok::r_paren) || Right.Type == TT_TemplateCloser) 1453567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper return false; 1454567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper 14555ad72bb8eb8e5cc4c061ccd28632295213d319dbDaniel Jasper // We only break before r_brace if there was a corresponding break before 14565ad72bb8eb8e5cc4c061ccd28632295213d319dbDaniel Jasper // the l_brace, which is tracked by BreakBeforeClosingBrace. 1457567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper if (Right.is(tok::r_brace)) 1458567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper return Right.MatchingParen && Right.MatchingParen->BlockKind == BK_Block; 14595ad72bb8eb8e5cc4c061ccd28632295213d319dbDaniel Jasper 146032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // Allow breaking after a trailing 'const', e.g. after a method declaration, 146132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // unless it is follow by ';', '{' or '='. 1462b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek if (Left.is(tok::kw_const) && Left.Previous != NULL && 1463b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek Left.Previous->is(tok::r_paren)) 1464e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko return !Right.isOneOf(tok::l_brace, tok::semi, tok::equal); 146532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 14668ef19a22956defa392df46c79e2d499ab7b16647Daniel Jasper if (Right.is(tok::kw___attribute)) 14678ef19a22956defa392df46c79e2d499ab7b16647Daniel Jasper return true; 14688ef19a22956defa392df46c79e2d499ab7b16647Daniel Jasper 14693a204418482c9ae70ad482e781132c54306c3aa6Daniel Jasper if (Left.is(tok::identifier) && Right.is(tok::string_literal)) 14703a204418482c9ae70ad482e781132c54306c3aa6Daniel Jasper return true; 1471e8b10d3d5b90efaf60ad89e96f6500f971ceec41Daniel Jasper 1472e8b10d3d5b90efaf60ad89e96f6500f971ceec41Daniel Jasper if (Left.Type == TT_CtorInitializerComma && 1473e8b10d3d5b90efaf60ad89e96f6500f971ceec41Daniel Jasper Style.BreakConstructorInitializersBeforeComma) 1474e8b10d3d5b90efaf60ad89e96f6500f971ceec41Daniel Jasper return false; 147519ccb1227f5dc338d4b2d9dbbaeaa973c293f8d0Daniel Jasper if (Right.Type == TT_CtorInitializerComma && 147619ccb1227f5dc338d4b2d9dbbaeaa973c293f8d0Daniel Jasper Style.BreakConstructorInitializersBeforeComma) 147719ccb1227f5dc338d4b2d9dbbaeaa973c293f8d0Daniel Jasper return true; 1478e8b10d3d5b90efaf60ad89e96f6500f971ceec41Daniel Jasper if (Right.isBinaryOperator() && Style.BreakBeforeBinaryOperators) 1479e8b10d3d5b90efaf60ad89e96f6500f971ceec41Daniel Jasper return true; 148026356ccf00f813cf358d420b55939fc737eb2cfaDaniel Jasper if (Left.is(tok::greater) && Right.is(tok::greater) && 148126356ccf00f813cf358d420b55939fc737eb2cfaDaniel Jasper Left.Type != TT_TemplateCloser) 148226356ccf00f813cf358d420b55939fc737eb2cfaDaniel Jasper return false; 1483a07aa665a12ab23bef7aa4aedfe113dd8b13da57Daniel Jasper if (Left.Type == TT_ArrayInitializerLSquare) 1484a07aa665a12ab23bef7aa4aedfe113dd8b13da57Daniel Jasper return true; 1485e8b10d3d5b90efaf60ad89e96f6500f971ceec41Daniel Jasper return (Left.isBinaryOperator() && Left.isNot(tok::lessless) && 1486e8b10d3d5b90efaf60ad89e96f6500f971ceec41Daniel Jasper !Style.BreakBeforeBinaryOperators) || 14876b119d63f5036344acd4e00a6ff2b3c72f26966fDaniel Jasper Left.isOneOf(tok::comma, tok::coloncolon, tok::semi, tok::l_brace, 14886b119d63f5036344acd4e00a6ff2b3c72f26966fDaniel Jasper tok::kw_class, tok::kw_struct) || 1489a07aa665a12ab23bef7aa4aedfe113dd8b13da57Daniel Jasper Right.isOneOf(tok::lessless, tok::arrow, tok::period, tok::colon, 1490a07aa665a12ab23bef7aa4aedfe113dd8b13da57Daniel Jasper tok::l_square, tok::at) || 1491198c8bfee0b33ab0ed0c54224f460868f1c18e95Daniel Jasper (Left.is(tok::r_paren) && 1492e033e87cbe77341777100093f8066167888d4440Daniel Jasper Right.isOneOf(tok::identifier, tok::kw_const, tok::kw___attribute)) || 1493a07aa665a12ab23bef7aa4aedfe113dd8b13da57Daniel Jasper (Left.is(tok::l_paren) && !Right.is(tok::r_paren)); 149432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} 149532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 1496bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jaspervoid TokenAnnotator::printDebugInfo(const AnnotatedLine &Line) { 1497bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper llvm::errs() << "AnnotatedTokens:\n"; 1498b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek const FormatToken *Tok = Line.First; 1499bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper while (Tok) { 1500b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek llvm::errs() << " M=" << Tok->MustBreakBefore 1501c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper << " C=" << Tok->CanBreakBefore << " T=" << Tok->Type 1502c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper << " S=" << Tok->SpacesRequiredBefore 1503c7bd68f9edcbca95e882d0ab18d09371f0bdb82cDaniel Jasper << " P=" << Tok->SplitPenalty << " Name=" << Tok->Tok.getName() 1504ae76f7f850a9101a20191b10241ca72c23dc40ddManuel Klimek << " L=" << Tok->TotalLength << " PPK=" << Tok->PackingKind 1505ae76f7f850a9101a20191b10241ca72c23dc40ddManuel Klimek << " FakeLParens="; 1506bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper for (unsigned i = 0, e = Tok->FakeLParens.size(); i != e; ++i) 1507bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper llvm::errs() << Tok->FakeLParens[i] << "/"; 1508bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper llvm::errs() << " FakeRParens=" << Tok->FakeRParens << "\n"; 1509ae76f7f850a9101a20191b10241ca72c23dc40ddManuel Klimek if (Tok->Next == NULL) 1510ae76f7f850a9101a20191b10241ca72c23dc40ddManuel Klimek assert(Tok == Line.Last); 1511b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek Tok = Tok->Next; 1512bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper } 1513bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper llvm::errs() << "----\n"; 1514bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper} 1515bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper 151632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} // namespace format 151732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} // namespace clang 1518