TokenAnnotator.cpp revision dbef71ebc66fe5553db01eb8e95b696c3223e737
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" 1832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper#include "clang/Lex/Lexer.h" 19bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper#include "llvm/Support/Debug.h" 2032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 2132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jaspernamespace clang { 2232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jaspernamespace format { 2332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 24ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasperbool AnnotatedToken::isUnaryOperator() const { 25ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper switch (FormatTok.Tok.getKind()) { 26ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber case tok::plus: 27ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber case tok::plusplus: 28ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber case tok::minus: 29ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber case tok::minusminus: 30ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber case tok::exclaim: 31ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber case tok::tilde: 32ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber case tok::kw_sizeof: 33ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber case tok::kw_alignof: 34ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber return true; 35ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber default: 36ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber return false; 37ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber } 38ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber} 39ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber 40ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasperbool AnnotatedToken::isBinaryOperator() const { 4132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // Comma is a binary operator, but does not behave as such wrt. formatting. 42ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper return getPrecedence(*this) > prec::Comma; 4332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} 4432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 45ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasperbool AnnotatedToken::isTrailingComment() const { 46ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper return is(tok::comment) && 47ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper (Children.empty() || Children[0].FormatTok.NewlinesBefore > 0); 484ed7f3e003c906d9fdb92a9484feeb8ac6e28e2fNico Weber} 490178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 50ac3223e45e7d17c65b143439313800eef4fdf71dDaniel JasperAnnotatedToken *AnnotatedToken::getPreviousNoneComment() const { 51ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper AnnotatedToken *Tok = Parent; 52ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper while (Tok != NULL && Tok->is(tok::comment)) 53ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper Tok = Tok->Parent; 54ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper return Tok; 5529f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper} 5629f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 57ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasperconst AnnotatedToken *AnnotatedToken::getNextNoneComment() const { 58ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper const AnnotatedToken *Tok = Children.empty() ? NULL : &Children[0]; 59ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper while (Tok != NULL && Tok->is(tok::comment)) 60ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper Tok = Tok->Children.empty() ? NULL : &Tok->Children[0]; 61ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper return Tok; 620178673f541685cf5067814dfeee2644078e39a9Daniel Jasper} 630178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 64ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasperbool AnnotatedToken::closesScope() const { 65ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper return isOneOf(tok::r_paren, tok::r_brace, tok::r_square) || 66ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper Type == TT_TemplateCloser; 67e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko} 68e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko 69ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasperbool AnnotatedToken::opensScope() const { 70ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper return isOneOf(tok::l_paren, tok::l_brace, tok::l_square) || 71ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper Type == TT_TemplateOpener; 72e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko} 73e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko 7432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper/// \brief A parser that gathers additional information about tokens. 7532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper/// 763fd9ccdd9f8d259bcf518e7056cfd419d992e984Alexander Kornienko/// The \c TokenAnnotator tries to match parenthesis and square brakets and 7732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper/// store a parenthesis levels. It also tries to resolve matching "<" and ">" 7832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper/// into template parameter lists. 7932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasperclass AnnotatingParser { 8032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasperpublic: 81c2e6d2a4a7fe9dfa7d52a38c6048b7b18e6b591aNico Weber AnnotatingParser(SourceManager &SourceMgr, Lexer &Lex, AnnotatedLine &Line, 82c2e6d2a4a7fe9dfa7d52a38c6048b7b18e6b591aNico Weber IdentifierInfo &Ident_in) 830178673f541685cf5067814dfeee2644078e39a9Daniel Jasper : SourceMgr(SourceMgr), Lex(Lex), Line(Line), CurrentToken(&Line.First), 841407bee187d7b964d5293ac8bf4f7a490c78cec6Daniel Jasper KeywordVirtualFound(false), NameFound(false), Ident_in(Ident_in) { 85923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper Contexts.push_back(Context(tok::unknown, 1, /*IsExpression=*/ false)); 8632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 8732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 8895e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weberprivate: 8932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool parseAngle() { 9032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken == NULL) 9132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 92923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper ScopedContextCreator ContextCreator(*this, tok::less, 10); 9332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper AnnotatedToken *Left = CurrentToken->Parent; 944e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().IsExpression = false; 9532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper while (CurrentToken != NULL) { 9632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::greater)) { 9732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left->MatchingParen = CurrentToken; 9832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->MatchingParen = Left; 9932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->Type = TT_TemplateCloser; 10032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 10132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 10232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 103e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko if (CurrentToken->isOneOf(tok::r_paren, tok::r_square, tok::r_brace, 104e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko tok::pipepipe, tok::ampamp, tok::question, 105e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko tok::colon)) 10632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 1079fc56f2636137fcde8acb38865555ed6c7b84dfdDaniel Jasper updateParameterCount(Left, CurrentToken); 10832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!consumeToken()) 10932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 11032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 11132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 11232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 11332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 11432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool parseParens(bool LookForDecls = false) { 11532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken == NULL) 11632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 117923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper ScopedContextCreator ContextCreator(*this, tok::l_paren, 1); 1184e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper 1194e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper // FIXME: This is a bit of a hack. Do better. 1204e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().ColonIsForRangeExpr = 1214e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.size() == 2 && Contexts[0].ColonIsForRangeExpr; 1224e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper 12332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool StartsObjCMethodExpr = false; 12432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper AnnotatedToken *Left = CurrentToken->Parent; 12532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::caret)) { 12632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // ^( starts a block. 12732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left->Type = TT_ObjCBlockLParen; 12832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } else if (AnnotatedToken *MaybeSel = Left->Parent) { 12932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // @selector( starts a selector. 13032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (MaybeSel->isObjCAtKeyword(tok::objc_selector) && MaybeSel->Parent && 13132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper MaybeSel->Parent->is(tok::at)) { 13232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper StartsObjCMethodExpr = true; 13332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 13432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 13532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 1364e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper if (StartsObjCMethodExpr) { 1374e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().ColonIsObjCMethodExpr = true; 1384e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Left->Type = TT_ObjCMethodExpr; 1394e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper } 14032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 14132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper while (CurrentToken != NULL) { 14232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // LookForDecls is set when "if (" has been seen. Check for 14332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // 'identifier' '*' 'identifier' followed by not '=' -- this 14432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // '*' has to be a binary operator but determineStarAmpUsage() will 14532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // categorize it as an unary operator, so set the right type here. 14632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (LookForDecls && !CurrentToken->Children.empty()) { 14732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper AnnotatedToken &Prev = *CurrentToken->Parent; 14832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper AnnotatedToken &Next = CurrentToken->Children[0]; 14932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Prev.Parent->is(tok::identifier) && 150e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko Prev.isOneOf(tok::star, tok::amp, tok::ampamp) && 15132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->is(tok::identifier) && Next.isNot(tok::equal)) { 15232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Prev.Type = TT_BinaryOperator; 15332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper LookForDecls = false; 15432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 15532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 15632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 15732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::r_paren)) { 158fca24bc45192c254ca92ef1d7cef71a290392f31Daniel Jasper if (CurrentToken->Parent->closesScope()) 159fca24bc45192c254ca92ef1d7cef71a290392f31Daniel Jasper CurrentToken->Parent->MatchingParen->NoMoreTokensOnLevel = true; 16032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left->MatchingParen = CurrentToken; 16132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->MatchingParen = Left; 16232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 16363d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper if (StartsObjCMethodExpr) { 1644e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper CurrentToken->Type = TT_ObjCMethodExpr; 1654e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper if (Contexts.back().FirstObjCSelectorName != NULL) { 1664e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 1674e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().LongestObjCSelectorName; 16863d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper } 16963d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper } 17032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 17132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 17232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 17332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 174e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko if (CurrentToken->isOneOf(tok::r_square, tok::r_brace)) 17532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 1769fc56f2636137fcde8acb38865555ed6c7b84dfdDaniel Jasper updateParameterCount(Left, CurrentToken); 17732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!consumeToken()) 17832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 17932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 18032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 18132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 18232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 18332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool parseSquare() { 18432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!CurrentToken) 18532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 18632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 18732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // A '[' could be an index subscript (after an indentifier or after 188051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber // ')' or ']'), it could be the start of an Objective-C method 189051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber // expression, or it could the the start of an Objective-C array literal. 19032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper AnnotatedToken *Left = CurrentToken->Parent; 191ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper AnnotatedToken *Parent = Left->getPreviousNoneComment(); 19232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool StartsObjCMethodExpr = 1936f21a988990ff5872822dcb049bd8fc65ce3d236Daniel Jasper Contexts.back().CanBeExpression && 194e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko (!Parent || Parent->isOneOf(tok::colon, tok::l_square, tok::l_paren, 195e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko tok::kw_return, tok::kw_throw) || 196ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper Parent->isUnaryOperator() || Parent->Type == TT_ObjCForIn || 197e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko Parent->Type == TT_CastRParen || 1986f21a988990ff5872822dcb049bd8fc65ce3d236Daniel Jasper getBinOpPrecedence(Parent->FormatTok.Tok.getKind(), true, true) > 199f9955d309d3de328e65563baf2d34571249dccbbDaniel Jasper prec::Unknown); 200923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper ScopedContextCreator ContextCreator(*this, tok::l_square, 10); 2016f21a988990ff5872822dcb049bd8fc65ce3d236Daniel Jasper Contexts.back().IsExpression = true; 202051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber bool StartsObjCArrayLiteral = Parent && Parent->is(tok::at); 20332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 2044e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper if (StartsObjCMethodExpr) { 2054e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().ColonIsObjCMethodExpr = true; 2064e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Left->Type = TT_ObjCMethodExpr; 207051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber } else if (StartsObjCArrayLiteral) { 208051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber Left->Type = TT_ObjCArrayLiteral; 2094e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper } 21032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 21132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper while (CurrentToken != NULL) { 21232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::r_square)) { 21332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!CurrentToken->Children.empty() && 21432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->Children[0].is(tok::l_paren)) { 215e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber // An ObjC method call is rarely followed by an open parenthesis. 21632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // FIXME: Do we incorrectly label ":" with this? 21732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper StartsObjCMethodExpr = false; 21832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left->Type = TT_Unknown; 21932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 2200178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (StartsObjCMethodExpr) { 2214e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper CurrentToken->Type = TT_ObjCMethodExpr; 222e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber // determineStarAmpUsage() thinks that '*' '[' is allocating an 223e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber // array of pointers, but if '[' starts a selector then '*' is a 224e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber // binary operator. 2253fd9ccdd9f8d259bcf518e7056cfd419d992e984Alexander Kornienko if (Parent != NULL && Parent->Type == TT_PointerOrReference) 2264ed7f3e003c906d9fdb92a9484feeb8ac6e28e2fNico Weber Parent->Type = TT_BinaryOperator; 227051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber } else if (StartsObjCArrayLiteral) { 228051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber CurrentToken->Type = TT_ObjCArrayLiteral; 2290178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 23032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left->MatchingParen = CurrentToken; 23132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->MatchingParen = Left; 2324e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper if (Contexts.back().FirstObjCSelectorName != NULL) 2334e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 2344e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().LongestObjCSelectorName; 23532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 23632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 23732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 238e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko if (CurrentToken->isOneOf(tok::r_paren, tok::r_brace)) 23932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 2409fc56f2636137fcde8acb38865555ed6c7b84dfdDaniel Jasper updateParameterCount(Left, CurrentToken); 24132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!consumeToken()) 24232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 24332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 24432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 24532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 24632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 24732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool parseBrace() { 24853e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper if (CurrentToken != NULL) { 24953e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper ScopedContextCreator ContextCreator(*this, tok::l_brace, 1); 25053e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper AnnotatedToken *Left = CurrentToken->Parent; 25153e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper while (CurrentToken != NULL) { 25253e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper if (CurrentToken->is(tok::r_brace)) { 25353e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper Left->MatchingParen = CurrentToken; 25453e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper CurrentToken->MatchingParen = Left; 25553e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper next(); 25653e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper return true; 25753e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper } 25853e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper if (CurrentToken->isOneOf(tok::r_paren, tok::r_square)) 25953e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper return false; 26053e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper updateParameterCount(Left, CurrentToken); 26153e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper if (!consumeToken()) 26253e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper return false; 26332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 26432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 26553e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper // No closing "}" found, this probably starts a definition. 26653e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper Line.StartsDefinition = true; 26732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 26832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 269c4615b7aaf97e303a4fc675956f7f5572d492885Daniel Jasper 2709fc56f2636137fcde8acb38865555ed6c7b84dfdDaniel Jasper void updateParameterCount(AnnotatedToken *Left, AnnotatedToken *Current) { 2719fc56f2636137fcde8acb38865555ed6c7b84dfdDaniel Jasper if (Current->is(tok::comma)) 2729fc56f2636137fcde8acb38865555ed6c7b84dfdDaniel Jasper ++Left->ParameterCount; 2739fc56f2636137fcde8acb38865555ed6c7b84dfdDaniel Jasper else if (Left->ParameterCount == 0 && Current->isNot(tok::comment)) 2749fc56f2636137fcde8acb38865555ed6c7b84dfdDaniel Jasper Left->ParameterCount = 1; 2759fc56f2636137fcde8acb38865555ed6c7b84dfdDaniel Jasper } 27632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 27732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool parseConditional() { 27832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper while (CurrentToken != NULL) { 27932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::colon)) { 28032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->Type = TT_ConditionalExpr; 28132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 28232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 28332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 28432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!consumeToken()) 28532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 28632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 28732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 28832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 28932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 29032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool parseTemplateDeclaration() { 29132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken != NULL && CurrentToken->is(tok::less)) { 29232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->Type = TT_TemplateOpener; 29332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 29432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!parseAngle()) 29532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 29634511fb79201ba9ed39c97f3a7ea0f157a79436dDaniel Jasper if (CurrentToken != NULL) 29734511fb79201ba9ed39c97f3a7ea0f157a79436dDaniel Jasper CurrentToken->Parent->ClosesTemplateDeclaration = true; 29832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 29932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 30032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 30132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 30232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 30332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool consumeToken() { 30432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper AnnotatedToken *Tok = CurrentToken; 30532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 30632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper switch (Tok->FormatTok.Tok.getKind()) { 30732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::plus: 30832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::minus: 309627707b9360597b65a9a0953d0ead2a08c3a0d5dDaniel Jasper if (Tok->Parent == NULL && Line.MustBeDeclaration) 31032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Tok->Type = TT_ObjCMethodSpecifier; 31132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 31232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::colon: 313cf6d76af806f7e1ba97be7b72b31bc78b919e0f0Daniel Jasper if (Tok->Parent == NULL) 314cf6d76af806f7e1ba97be7b72b31bc78b919e0f0Daniel Jasper return false; 31532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // Colons from ?: are handled in parseConditional(). 316923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper if (Tok->Parent->is(tok::r_paren) && Contexts.size() == 1) { 31732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Tok->Type = TT_CtorInitializerColon; 3184e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper } else if (Contexts.back().ColonIsObjCMethodExpr || 31963d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper Line.First.Type == TT_ObjCMethodSpecifier) { 32032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Tok->Type = TT_ObjCMethodExpr; 32163d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper Tok->Parent->Type = TT_ObjCSelectorName; 3224e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper if (Tok->Parent->FormatTok.TokenLength > 323f9955d309d3de328e65563baf2d34571249dccbbDaniel Jasper Contexts.back().LongestObjCSelectorName) 3244e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().LongestObjCSelectorName = 3254e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Tok->Parent->FormatTok.TokenLength; 3264e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper if (Contexts.back().FirstObjCSelectorName == NULL) 3274e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().FirstObjCSelectorName = Tok->Parent; 3284e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper } else if (Contexts.back().ColonIsForRangeExpr) { 32932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Tok->Type = TT_RangeBasedForLoopColon; 3306cabab48dacc1317821f8f078ed2d4c603b67affDaniel Jasper } else if (Contexts.size() == 1) { 3316cabab48dacc1317821f8f078ed2d4c603b67affDaniel Jasper Tok->Type = TT_InheritanceColon; 332923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper } else if (Contexts.back().ContextKind == tok::l_paren) { 333923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper Tok->Type = TT_InlineASMColon; 33463d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper } 33532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 33632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::kw_if: 33732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::kw_while: 33832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken != NULL && CurrentToken->is(tok::l_paren)) { 33932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 34032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!parseParens(/*LookForDecls=*/ true)) 34132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 34232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 34332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 34432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::kw_for: 3454e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().ColonIsForRangeExpr = true; 34632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 34732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!parseParens()) 34832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 34932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 35032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::l_paren: 35132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!parseParens()) 35232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 3531407bee187d7b964d5293ac8bf4f7a490c78cec6Daniel Jasper if (Line.MustBeDeclaration && NameFound && !Contexts.back().IsExpression) 3543c08a818a6ac9115fe8880af9bbf5a0a87bdffaaDaniel Jasper Line.MightBeFunctionDecl = true; 35532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 35632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::l_square: 35732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!parseSquare()) 35832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 35932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 36032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::l_brace: 36132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!parseBrace()) 36232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 36332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 36432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::less: 36532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (parseAngle()) 36632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Tok->Type = TT_TemplateOpener; 36732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper else { 36832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Tok->Type = TT_BinaryOperator; 36932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken = Tok; 37032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 37132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 37232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 37332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::r_paren: 37432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::r_square: 37532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 37632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::r_brace: 37732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // Lines can start with '}'. 37832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok->Parent != NULL) 37932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 38032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 38132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::greater: 38232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Tok->Type = TT_BinaryOperator; 38332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 38432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::kw_operator: 3852b4c924f85e156d66c01b3f16c850892c47dcc7aDaniel Jasper while (CurrentToken && CurrentToken->isNot(tok::l_paren)) { 386e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko if (CurrentToken->isOneOf(tok::star, tok::amp)) 3872b4c924f85e156d66c01b3f16c850892c47dcc7aDaniel Jasper CurrentToken->Type = TT_PointerOrReference; 3882b4c924f85e156d66c01b3f16c850892c47dcc7aDaniel Jasper consumeToken(); 38932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 3902b4c924f85e156d66c01b3f16c850892c47dcc7aDaniel Jasper if (CurrentToken) 3912b4c924f85e156d66c01b3f16c850892c47dcc7aDaniel Jasper CurrentToken->Type = TT_OverloadedOperatorLParen; 39232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 39332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::question: 39432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper parseConditional(); 39532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 39632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::kw_template: 39732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper parseTemplateDeclaration(); 39832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 399c2e6d2a4a7fe9dfa7d52a38c6048b7b18e6b591aNico Weber case tok::identifier: 400c2e6d2a4a7fe9dfa7d52a38c6048b7b18e6b591aNico Weber if (Line.First.is(tok::kw_for) && 401c2e6d2a4a7fe9dfa7d52a38c6048b7b18e6b591aNico Weber Tok->FormatTok.Tok.getIdentifierInfo() == &Ident_in) 402c2e6d2a4a7fe9dfa7d52a38c6048b7b18e6b591aNico Weber Tok->Type = TT_ObjCForIn; 403c2e6d2a4a7fe9dfa7d52a38c6048b7b18e6b591aNico Weber break; 4048ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::comma: 4058ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper if (Contexts.back().FirstStartOfName) 4068ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper Contexts.back().FirstStartOfName->PartOfMultiVariableDeclStmt = true; 4078ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper break; 40832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper default: 40932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 41032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 41132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 41232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 41332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 41432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper void parseIncludeDirective() { 41532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 41632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken != NULL && CurrentToken->is(tok::less)) { 41732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 41832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper while (CurrentToken != NULL) { 41932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->isNot(tok::comment) || 42032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper !CurrentToken->Children.empty()) 42132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->Type = TT_ImplicitStringLiteral; 42232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 42332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 42432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } else { 42532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper while (CurrentToken != NULL) { 4263a204418482c9ae70ad482e781132c54306c3aa6Daniel Jasper if (CurrentToken->is(tok::string_literal)) 4273a204418482c9ae70ad482e781132c54306c3aa6Daniel Jasper // Mark these string literals as "implicit" literals, too, so that 4283a204418482c9ae70ad482e781132c54306c3aa6Daniel Jasper // they are not split or line-wrapped. 4293a204418482c9ae70ad482e781132c54306c3aa6Daniel Jasper CurrentToken->Type = TT_ImplicitStringLiteral; 43032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 43132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 43232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 43332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 43432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 43532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper void parseWarningOrError() { 43632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 43732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // We still want to format the whitespace left of the first token of the 43832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // warning or error. 43932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 44032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper while (CurrentToken != NULL) { 44132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->Type = TT_ImplicitStringLiteral; 44232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 44332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 44432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 44532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 44632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper void parsePreprocessorDirective() { 44732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 44832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken == NULL) 44932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return; 45032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // Hashes in the middle of a line can lead to any strange token 45132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // sequence. 45232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->FormatTok.Tok.getIdentifierInfo() == NULL) 45332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return; 45432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper switch (CurrentToken->FormatTok.Tok.getIdentifierInfo()->getPPKeywordID()) { 45532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::pp_include: 45632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::pp_import: 45732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper parseIncludeDirective(); 45832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 45932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::pp_error: 46032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::pp_warning: 46132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper parseWarningOrError(); 46232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 463aae7bad5cdd804cb88e918e9defbf5faf69f4cfdDaniel Jasper case tok::pp_if: 464aae7bad5cdd804cb88e918e9defbf5faf69f4cfdDaniel Jasper case tok::pp_elif: 465aae7bad5cdd804cb88e918e9defbf5faf69f4cfdDaniel Jasper parseLine(); 466aae7bad5cdd804cb88e918e9defbf5faf69f4cfdDaniel Jasper break; 46732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper default: 46832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 46932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 4705b7e7b0ec77f49c1b24deffc9b7032ca16ca9f0dDaniel Jasper while (CurrentToken != NULL) 4715b7e7b0ec77f49c1b24deffc9b7032ca16ca9f0dDaniel Jasper next(); 47232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 47332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 47495e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weberpublic: 47532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper LineType parseLine() { 47632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper int PeriodsAndArrows = 0; 477248497199bc56e86d1c089beb9529f3b3d77abb1Daniel Jasper AnnotatedToken *LastPeriodOrArrow = NULL; 47832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool CanBeBuilderTypeStmt = true; 47932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::hash)) { 48032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper parsePreprocessorDirective(); 48132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return LT_PreprocessorDirective; 48232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 48332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper while (CurrentToken != NULL) { 48432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::kw_virtual)) 48532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper KeywordVirtualFound = true; 486e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko if (CurrentToken->isOneOf(tok::period, tok::arrow)) { 48732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper ++PeriodsAndArrows; 488248497199bc56e86d1c089beb9529f3b3d77abb1Daniel Jasper LastPeriodOrArrow = CurrentToken; 489248497199bc56e86d1c089beb9529f3b3d77abb1Daniel Jasper } 4904a544e5856ceadef1c095c7d1ae5c8d760851d59Daniel Jasper AnnotatedToken *TheToken = CurrentToken; 49132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!consumeToken()) 49232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return LT_Invalid; 4934a544e5856ceadef1c095c7d1ae5c8d760851d59Daniel Jasper if (getPrecedence(*TheToken) > prec::Assignment && 49482282dc907a04b1931f8f578693b035ad751fd3bDaniel Jasper TheToken->Type == TT_BinaryOperator) 4954a544e5856ceadef1c095c7d1ae5c8d760851d59Daniel Jasper CanBeBuilderTypeStmt = false; 49632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 49732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (KeywordVirtualFound) 49832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return LT_VirtualFunctionDecl; 49932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 50032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // Assume a builder-type call if there are 2 or more "." and "->". 501248497199bc56e86d1c089beb9529f3b3d77abb1Daniel Jasper if (PeriodsAndArrows >= 2 && CanBeBuilderTypeStmt) { 502248497199bc56e86d1c089beb9529f3b3d77abb1Daniel Jasper LastPeriodOrArrow->LastInChainOfCalls = true; 50332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return LT_BuilderTypeCall; 504248497199bc56e86d1c089beb9529f3b3d77abb1Daniel Jasper } 50532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 50663d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper if (Line.First.Type == TT_ObjCMethodSpecifier) { 5074e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper if (Contexts.back().FirstObjCSelectorName != NULL) 5084e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 5094e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().LongestObjCSelectorName; 51063d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper return LT_ObjCMethodDecl; 51163d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper } 51263d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper 51332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return LT_Other; 51432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 51532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 51695e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weberprivate: 51732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper void next() { 5180178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (CurrentToken != NULL) { 5190178673f541685cf5067814dfeee2644078e39a9Daniel Jasper determineTokenType(*CurrentToken); 5204e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper CurrentToken->BindingStrength = Contexts.back().BindingStrength; 5210178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 5220178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 52332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken != NULL && !CurrentToken->Children.empty()) 52432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken = &CurrentToken->Children[0]; 52532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper else 52632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken = NULL; 527d0f349be1422a123fdb28d6dd556f7300e6d51e9Daniel Jasper 528d0f349be1422a123fdb28d6dd556f7300e6d51e9Daniel Jasper // Reset token type in case we have already looked at it and then recovered 529d0f349be1422a123fdb28d6dd556f7300e6d51e9Daniel Jasper // from an error (e.g. failure to find the matching >). 530d0f349be1422a123fdb28d6dd556f7300e6d51e9Daniel Jasper if (CurrentToken != NULL) 531d0f349be1422a123fdb28d6dd556f7300e6d51e9Daniel Jasper CurrentToken->Type = TT_Unknown; 53232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 53332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 5344e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper /// \brief A struct to hold information valid in a specific context, e.g. 5354e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper /// a pair of parenthesis. 5364e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper struct Context { 537923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper Context(tok::TokenKind ContextKind, unsigned BindingStrength, 538923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper bool IsExpression) 539923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper : ContextKind(ContextKind), BindingStrength(BindingStrength), 540923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper LongestObjCSelectorName(0), ColonIsForRangeExpr(false), 541923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper ColonIsObjCMethodExpr(false), FirstObjCSelectorName(NULL), 5428ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper FirstStartOfName(NULL), IsExpression(IsExpression), 5438ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper CanBeExpression(true) {} 544923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper 545923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper tok::TokenKind ContextKind; 5464e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper unsigned BindingStrength; 5474e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper unsigned LongestObjCSelectorName; 5484e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper bool ColonIsForRangeExpr; 5494e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper bool ColonIsObjCMethodExpr; 5504e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper AnnotatedToken *FirstObjCSelectorName; 5518ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper AnnotatedToken *FirstStartOfName; 5524e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper bool IsExpression; 5536f21a988990ff5872822dcb049bd8fc65ce3d236Daniel Jasper bool CanBeExpression; 5544e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper }; 5554e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper 5564e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper /// \brief Puts a new \c Context onto the stack \c Contexts for the lifetime 5574e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper /// of each instance. 5584e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper struct ScopedContextCreator { 5594e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper AnnotatingParser &P; 5604e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper 561923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper ScopedContextCreator(AnnotatingParser &P, tok::TokenKind ContextKind, 562923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper unsigned Increase) 563923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper : P(P) { 564923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper P.Contexts.push_back( 565923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper Context(ContextKind, P.Contexts.back().BindingStrength + Increase, 566923ebef120a37122ce50722a85cbe42c0c2dab53Daniel Jasper P.Contexts.back().IsExpression)); 5674e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper } 5684e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper 5694e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper ~ScopedContextCreator() { P.Contexts.pop_back(); } 5704e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper }; 5710178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 5720178673f541685cf5067814dfeee2644078e39a9Daniel Jasper void determineTokenType(AnnotatedToken &Current) { 5732eb23b73f001e475c604652732f1a156f252352dDaniel Jasper if (getPrecedence(Current) == prec::Assignment && 5742eb23b73f001e475c604652732f1a156f252352dDaniel Jasper (!Current.Parent || Current.Parent->isNot(tok::kw_operator))) { 5754e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().IsExpression = true; 57695e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weber for (AnnotatedToken *Previous = Current.Parent; 57795e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weber Previous && Previous->isNot(tok::comma); 57895e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weber Previous = Previous->Parent) { 5799c65b069821b7de79427e291b006293a0f55ff8fDaniel Jasper if (Previous->is(tok::r_square)) 5809c65b069821b7de79427e291b006293a0f55ff8fDaniel Jasper Previous = Previous->MatchingParen; 5810178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (Previous->Type == TT_BinaryOperator && 582e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko Previous->isOneOf(tok::star, tok::amp)) { 5830178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Previous->Type = TT_PointerOrReference; 5840178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 5850178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 586e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko } else if (Current.isOneOf(tok::kw_return, tok::kw_throw) || 58795e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weber (Current.is(tok::l_paren) && !Line.MustBeDeclaration && 58895e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weber (!Current.Parent || Current.Parent->isNot(tok::kw_for)))) { 5894e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().IsExpression = true; 590e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko } else if (Current.isOneOf(tok::r_paren, tok::greater, tok::comma)) { 59195e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weber for (AnnotatedToken *Previous = Current.Parent; 592e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko Previous && Previous->isOneOf(tok::star, tok::amp); 59395e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weber Previous = Previous->Parent) 59495e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weber Previous->Type = TT_PointerOrReference; 595d0f349be1422a123fdb28d6dd556f7300e6d51e9Daniel Jasper } else if (Current.Parent && 596d0f349be1422a123fdb28d6dd556f7300e6d51e9Daniel Jasper Current.Parent->Type == TT_CtorInitializerColon) { 597d0f349be1422a123fdb28d6dd556f7300e6d51e9Daniel Jasper Contexts.back().IsExpression = true; 5986f21a988990ff5872822dcb049bd8fc65ce3d236Daniel Jasper } else if (Current.is(tok::kw_new)) { 5996f21a988990ff5872822dcb049bd8fc65ce3d236Daniel Jasper Contexts.back().CanBeExpression = false; 60016a69ef481f4580c571b6c693a5d3dd64ea56b53Daniel Jasper } else if (Current.is(tok::semi)) { 60116a69ef481f4580c571b6c693a5d3dd64ea56b53Daniel Jasper // This should be the condition or increment in a for-loop. 60216a69ef481f4580c571b6c693a5d3dd64ea56b53Daniel Jasper Contexts.back().IsExpression = true; 60395e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weber } 6040178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 6050178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (Current.Type == TT_Unknown) { 6063c08a818a6ac9115fe8880af9bbf5a0a87bdffaaDaniel Jasper if (Current.Parent && Current.is(tok::identifier) && 6073c08a818a6ac9115fe8880af9bbf5a0a87bdffaaDaniel Jasper ((Current.Parent->is(tok::identifier) && 6083c08a818a6ac9115fe8880af9bbf5a0a87bdffaaDaniel Jasper Current.Parent->FormatTok.Tok.getIdentifierInfo() 6093c08a818a6ac9115fe8880af9bbf5a0a87bdffaaDaniel Jasper ->getPPKeywordID() == tok::pp_not_keyword) || 6108ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper isSimpleTypeSpecifier(*Current.Parent) || 6113c08a818a6ac9115fe8880af9bbf5a0a87bdffaaDaniel Jasper Current.Parent->Type == TT_PointerOrReference || 6123c08a818a6ac9115fe8880af9bbf5a0a87bdffaaDaniel Jasper Current.Parent->Type == TT_TemplateCloser)) { 6138ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper Contexts.back().FirstStartOfName = &Current; 6143c08a818a6ac9115fe8880af9bbf5a0a87bdffaaDaniel Jasper Current.Type = TT_StartOfName; 6151407bee187d7b964d5293ac8bf4f7a490c78cec6Daniel Jasper NameFound = true; 616e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko } else if (Current.isOneOf(tok::star, tok::amp, tok::ampamp)) { 6174e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Current.Type = 6184e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper determineStarAmpUsage(Current, Contexts.back().IsExpression); 619e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko } else if (Current.isOneOf(tok::minus, tok::plus, tok::caret)) { 6200178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.Type = determinePlusMinusCaretUsage(Current); 621e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko } else if (Current.isOneOf(tok::minusminus, tok::plusplus)) { 6220178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.Type = determineIncrementUsage(Current); 6230178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } else if (Current.is(tok::exclaim)) { 6240178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.Type = TT_UnaryOperator; 625ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper } else if (Current.isBinaryOperator()) { 6260178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.Type = TT_BinaryOperator; 6270178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } else if (Current.is(tok::comment)) { 6280178673f541685cf5067814dfeee2644078e39a9Daniel Jasper std::string Data(Lexer::getSpelling(Current.FormatTok.Tok, SourceMgr, 6290178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Lex.getLangOpts())); 6300178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (StringRef(Data).startswith("//")) 6310178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.Type = TT_LineComment; 6320178673f541685cf5067814dfeee2644078e39a9Daniel Jasper else 6330178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.Type = TT_BlockComment; 63437d693160eba22343e08d7bcf66cd132ace77e5cNico Weber } else if (Current.is(tok::r_paren)) { 63503628b86a9c50e066412fb0e49908686ff117378Daniel Jasper bool ParensNotExpr = !Current.Parent || 63603628b86a9c50e066412fb0e49908686ff117378Daniel Jasper Current.Parent->Type == TT_PointerOrReference || 63737d693160eba22343e08d7bcf66cd132ace77e5cNico Weber Current.Parent->Type == TT_TemplateCloser; 63837d693160eba22343e08d7bcf66cd132ace77e5cNico Weber bool ParensCouldEndDecl = 639e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko !Current.Children.empty() && 640e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko Current.Children[0].isOneOf(tok::equal, tok::semi, tok::l_brace); 6416a365aaa057a8c445d25344c0433726c752b3e7dDaniel Jasper bool IsSizeOfOrAlignOf = 6426a365aaa057a8c445d25344c0433726c752b3e7dDaniel Jasper Current.MatchingParen && Current.MatchingParen->Parent && 6436a365aaa057a8c445d25344c0433726c752b3e7dDaniel Jasper Current.MatchingParen->Parent->isOneOf(tok::kw_sizeof, 6446a365aaa057a8c445d25344c0433726c752b3e7dDaniel Jasper tok::kw_alignof); 6456a365aaa057a8c445d25344c0433726c752b3e7dDaniel Jasper if (ParensNotExpr && !ParensCouldEndDecl && !IsSizeOfOrAlignOf && 64637eff83413a064c504c5a42097e4f5dd0b2962d2Daniel Jasper Contexts.back().IsExpression) 64737d693160eba22343e08d7bcf66cd132ace77e5cNico Weber // FIXME: We need to get smarter and understand more cases of casts. 64837d693160eba22343e08d7bcf66cd132ace77e5cNico Weber Current.Type = TT_CastRParen; 6490178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } else if (Current.is(tok::at) && Current.Children.size()) { 6500178673f541685cf5067814dfeee2644078e39a9Daniel Jasper switch (Current.Children[0].FormatTok.Tok.getObjCKeywordID()) { 6510178673f541685cf5067814dfeee2644078e39a9Daniel Jasper case tok::objc_interface: 6520178673f541685cf5067814dfeee2644078e39a9Daniel Jasper case tok::objc_implementation: 6530178673f541685cf5067814dfeee2644078e39a9Daniel Jasper case tok::objc_protocol: 6540178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.Type = TT_ObjCDecl; 6550178673f541685cf5067814dfeee2644078e39a9Daniel Jasper break; 6560178673f541685cf5067814dfeee2644078e39a9Daniel Jasper case tok::objc_property: 6570178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.Type = TT_ObjCProperty; 6580178673f541685cf5067814dfeee2644078e39a9Daniel Jasper break; 6590178673f541685cf5067814dfeee2644078e39a9Daniel Jasper default: 6600178673f541685cf5067814dfeee2644078e39a9Daniel Jasper break; 6610178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 6620178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 6630178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 6640178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 6650178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 6660178673f541685cf5067814dfeee2644078e39a9Daniel Jasper /// \brief Return the type of the given token assuming it is * or &. 667dbef71ebc66fe5553db01eb8e95b696c3223e737Daniel Jasper TokenType determineStarAmpUsage(const AnnotatedToken &Tok, 668dbef71ebc66fe5553db01eb8e95b696c3223e737Daniel Jasper bool IsExpression) { 669ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper const AnnotatedToken *PrevToken = Tok.getPreviousNoneComment(); 6700178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (PrevToken == NULL) 6710178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_UnaryOperator; 6720178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 673ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper const AnnotatedToken *NextToken = Tok.getNextNoneComment(); 6740178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (NextToken == NULL) 6750178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_Unknown; 6760178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 6778a5d7cd100ebfb8c6b353ee4ad5b14ab4105d32dDaniel Jasper if (PrevToken->is(tok::l_paren) && !IsExpression) 6788a5d7cd100ebfb8c6b353ee4ad5b14ab4105d32dDaniel Jasper return TT_PointerOrReference; 6798a5d7cd100ebfb8c6b353ee4ad5b14ab4105d32dDaniel Jasper 680e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko if (PrevToken->isOneOf(tok::l_paren, tok::l_square, tok::l_brace, 681d3cf17b5f1fed43dbd0cd35c43d15139803c9c84Daniel Jasper tok::comma, tok::semi, tok::kw_return, tok::colon, 682dbef71ebc66fe5553db01eb8e95b696c3223e737Daniel Jasper tok::equal, tok::kw_delete) || 683e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko PrevToken->Type == TT_BinaryOperator || 6840178673f541685cf5067814dfeee2644078e39a9Daniel Jasper PrevToken->Type == TT_UnaryOperator || PrevToken->Type == TT_CastRParen) 6850178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_UnaryOperator; 6860178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 687e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber if (NextToken->is(tok::l_square)) 688e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber return TT_PointerOrReference; 689e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber 690e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko if (PrevToken->FormatTok.Tok.isLiteral() || 691e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko PrevToken->isOneOf(tok::r_paren, tok::r_square) || 692ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper NextToken->FormatTok.Tok.isLiteral() || NextToken->isUnaryOperator()) 6930178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_BinaryOperator; 6940178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 6950178673f541685cf5067814dfeee2644078e39a9Daniel Jasper // It is very unlikely that we are going to find a pointer or reference type 6960178673f541685cf5067814dfeee2644078e39a9Daniel Jasper // definition on the RHS of an assignment. 6970178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (IsExpression) 6980178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_BinaryOperator; 6990178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 7000178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_PointerOrReference; 7010178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 7020178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 7030178673f541685cf5067814dfeee2644078e39a9Daniel Jasper TokenType determinePlusMinusCaretUsage(const AnnotatedToken &Tok) { 704ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper const AnnotatedToken *PrevToken = Tok.getPreviousNoneComment(); 7050178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (PrevToken == NULL) 7060178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_UnaryOperator; 7070178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 7080178673f541685cf5067814dfeee2644078e39a9Daniel Jasper // Use heuristics to recognize unary operators. 709e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko if (PrevToken->isOneOf(tok::equal, tok::l_paren, tok::comma, tok::l_square, 710e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko tok::question, tok::colon, tok::kw_return, 711e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko tok::kw_case, tok::at, tok::l_brace)) 7120178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_UnaryOperator; 7130178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 714ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber // There can't be two consecutive binary operators. 7150178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (PrevToken->Type == TT_BinaryOperator) 7160178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_UnaryOperator; 7170178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 7180178673f541685cf5067814dfeee2644078e39a9Daniel Jasper // Fall back to marking the token as binary operator. 7190178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_BinaryOperator; 7200178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 7210178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 7220178673f541685cf5067814dfeee2644078e39a9Daniel Jasper /// \brief Determine whether ++/-- are pre- or post-increments/-decrements. 7230178673f541685cf5067814dfeee2644078e39a9Daniel Jasper TokenType determineIncrementUsage(const AnnotatedToken &Tok) { 724ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper const AnnotatedToken *PrevToken = Tok.getPreviousNoneComment(); 7250178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (PrevToken == NULL) 7260178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_UnaryOperator; 727e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko if (PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::identifier)) 7280178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_TrailingUnaryOperator; 7290178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 7300178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_UnaryOperator; 7310178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 7324e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper 7338ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper // FIXME: This is copy&pasted from Sema. Put it in a common place and remove 7348ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper // duplication. 7358ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper /// \brief Determine whether the token kind starts a simple-type-specifier. 7368ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper bool isSimpleTypeSpecifier(const AnnotatedToken &Tok) const { 7378ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper switch (Tok.FormatTok.Tok.getKind()) { 7388ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw_short: 7398ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw_long: 7408ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw___int64: 7418ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw___int128: 7428ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw_signed: 7438ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw_unsigned: 7448ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw_void: 7458ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw_char: 7468ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw_int: 7478ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw_half: 7488ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw_float: 7498ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw_double: 7508ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw_wchar_t: 7518ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw_bool: 7528ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw___underlying_type: 7538ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper return true; 7548ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::annot_typename: 7558ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw_char16_t: 7568ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw_char32_t: 7578ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw_typeof: 7588ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper case tok::kw_decltype: 7598ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper return Lex.getLangOpts().CPlusPlus; 7608ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper default: 7618ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper break; 7628ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper } 7638ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper return false; 7648ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper } 7658ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper 7664e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper SmallVector<Context, 8> Contexts; 7674e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper 7684e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper SourceManager &SourceMgr; 7694e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Lexer &Lex; 7704e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper AnnotatedLine &Line; 7714e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper AnnotatedToken *CurrentToken; 7724e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper bool KeywordVirtualFound; 7731407bee187d7b964d5293ac8bf4f7a490c78cec6Daniel Jasper bool NameFound; 774c2e6d2a4a7fe9dfa7d52a38c6048b7b18e6b591aNico Weber IdentifierInfo &Ident_in; 77532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper}; 77632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 77729f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper/// \brief Parses binary expressions by inserting fake parenthesis based on 77829f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper/// operator precedence. 77929f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasperclass ExpressionParser { 78029f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasperpublic: 78129f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper ExpressionParser(AnnotatedLine &Line) : Current(&Line.First) {} 78229f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 78329f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper /// \brief Parse expressions with the given operatore precedence. 784237d4c1c785be13656bff6c09e5b7ccd066ff5baDaniel Jasper void parse(int Precedence = 0) { 78529f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper if (Precedence > prec::PointerToMember || Current == NULL) 78629f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper return; 78729f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 78829f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper // Eagerly consume trailing comments. 789ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper while (Current && Current->isTrailingComment()) { 79029f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper next(); 79129f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper } 79229f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 79329f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper AnnotatedToken *Start = Current; 79429f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper bool OperatorFound = false; 79529f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 796237d4c1c785be13656bff6c09e5b7ccd066ff5baDaniel Jasper while (Current) { 79729f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper // Consume operators with higher precedence. 798bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper parse(Precedence + 1); 79929f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 800237d4c1c785be13656bff6c09e5b7ccd066ff5baDaniel Jasper int CurrentPrecedence = 0; 801237d4c1c785be13656bff6c09e5b7ccd066ff5baDaniel Jasper if (Current) { 802237d4c1c785be13656bff6c09e5b7ccd066ff5baDaniel Jasper if (Current->Type == TT_ConditionalExpr) 803237d4c1c785be13656bff6c09e5b7ccd066ff5baDaniel Jasper CurrentPrecedence = 1 + (int) prec::Conditional; 804bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper else if (Current->is(tok::semi) || Current->Type == TT_InlineASMColon) 805237d4c1c785be13656bff6c09e5b7ccd066ff5baDaniel Jasper CurrentPrecedence = 1; 806237d4c1c785be13656bff6c09e5b7ccd066ff5baDaniel Jasper else if (Current->Type == TT_BinaryOperator || Current->is(tok::comma)) 807237d4c1c785be13656bff6c09e5b7ccd066ff5baDaniel Jasper CurrentPrecedence = 1 + (int) getPrecedence(*Current); 808237d4c1c785be13656bff6c09e5b7ccd066ff5baDaniel Jasper } 809237d4c1c785be13656bff6c09e5b7ccd066ff5baDaniel Jasper 81029f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper // At the end of the line or when an operator with higher precedence is 81129f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper // found, insert fake parenthesis and return. 812ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper if (Current == NULL || Current->closesScope() || 813237d4c1c785be13656bff6c09e5b7ccd066ff5baDaniel Jasper (CurrentPrecedence != 0 && CurrentPrecedence < Precedence)) { 81429f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper if (OperatorFound) { 815bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper Start->FakeLParens.push_back(prec::Level(Precedence - 1)); 816237d4c1c785be13656bff6c09e5b7ccd066ff5baDaniel Jasper if (Current) 817087387a1e9ce5abeb4f348e14f64e5c2273eaedbDaniel Jasper ++Current->Parent->FakeRParens; 81829f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper } 81929f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper return; 82029f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper } 82129f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 82229f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper // Consume scopes: (), [], <> and {} 823ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper if (Current->opensScope()) { 824ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper while (Current && !Current->closesScope()) { 82529f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper next(); 82629f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper parse(); 82729f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper } 82829f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper next(); 82929f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper } else { 83029f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper // Operator found. 831237d4c1c785be13656bff6c09e5b7ccd066ff5baDaniel Jasper if (CurrentPrecedence == Precedence) 83229f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper OperatorFound = true; 83329f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 83429f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper next(); 83529f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper } 83629f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper } 83729f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper } 83829f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 83929f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasperprivate: 84029f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper void next() { 84129f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper if (Current != NULL) 84229f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper Current = Current->Children.empty() ? NULL : &Current->Children[0]; 84329f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper } 84429f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 84529f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper AnnotatedToken *Current; 84629f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper}; 84729f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 8488ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jaspervoid TokenAnnotator::annotate(AnnotatedLine &Line) { 849c2e6d2a4a7fe9dfa7d52a38c6048b7b18e6b591aNico Weber AnnotatingParser Parser(SourceMgr, Lex, Line, Ident_in); 85032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Line.Type = Parser.parseLine(); 85132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Line.Type == LT_Invalid) 85232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return; 85332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 85429f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper ExpressionParser ExprParser(Line); 85529f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper ExprParser.parse(); 85629f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 85732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Line.First.Type == TT_ObjCMethodSpecifier) 85832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Line.Type = LT_ObjCMethodDecl; 85932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper else if (Line.First.Type == TT_ObjCDecl) 86032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Line.Type = LT_ObjCDecl; 86132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper else if (Line.First.Type == TT_ObjCProperty) 86232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Line.Type = LT_ObjCProperty; 86332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 864729a743b317d877df3978e88a4a247d2edbf2090Daniel Jasper Line.First.SpacesRequiredBefore = 1; 86532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Line.First.MustBreakBefore = Line.First.FormatTok.MustBreakBefore; 86632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Line.First.CanBreakBefore = Line.First.MustBreakBefore; 86732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 86832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Line.First.TotalLength = Line.First.FormatTok.TokenLength; 86932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} 87032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 8718ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jaspervoid TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) { 8728ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper if (Line.First.Children.empty()) 8738ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper return; 8748ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper AnnotatedToken *Current = &Line.First.Children[0]; 8758ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper while (Current != NULL) { 876729a743b317d877df3978e88a4a247d2edbf2090Daniel Jasper if (Current->Type == TT_LineComment) 877729a743b317d877df3978e88a4a247d2edbf2090Daniel Jasper Current->SpacesRequiredBefore = Style.SpacesBeforeTrailingComments; 878729a743b317d877df3978e88a4a247d2edbf2090Daniel Jasper else 879729a743b317d877df3978e88a4a247d2edbf2090Daniel Jasper Current->SpacesRequiredBefore = 880729a743b317d877df3978e88a4a247d2edbf2090Daniel Jasper spaceRequiredBefore(Line, *Current) ? 1 : 0; 8818ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper 8828ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper if (Current->FormatTok.MustBreakBefore) { 8838ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->MustBreakBefore = true; 8848ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper } else if (Current->Type == TT_LineComment) { 8858ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->MustBreakBefore = Current->FormatTok.NewlinesBefore > 0; 886ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper } else if (Current->Parent->isTrailingComment() || 8878ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper (Current->is(tok::string_literal) && 8888ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->Parent->is(tok::string_literal))) { 8898ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->MustBreakBefore = true; 8908ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper } else if (Current->is(tok::lessless) && !Current->Children.empty() && 8918ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->Parent->is(tok::string_literal) && 8928ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->Children[0].is(tok::string_literal)) { 8938ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->MustBreakBefore = true; 8948ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper } else { 8958ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->MustBreakBefore = false; 8968ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper } 8978ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->CanBreakBefore = 8988ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->MustBreakBefore || canBreakBefore(Line, *Current); 8998ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper if (Current->MustBreakBefore) 9008ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->TotalLength = Current->Parent->TotalLength + Style.ColumnLimit; 9018ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper else 9028ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->TotalLength = 9038ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->Parent->TotalLength + Current->FormatTok.TokenLength + 904729a743b317d877df3978e88a4a247d2edbf2090Daniel Jasper Current->SpacesRequiredBefore; 9058ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper // FIXME: Only calculate this if CanBreakBefore is true once static 9068ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper // initializers etc. are sorted out. 9078ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper // FIXME: Move magic numbers to a better place. 9088ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->SplitPenalty = 9098ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper 20 * Current->BindingStrength + splitPenalty(Line, *Current); 9108ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper 9118ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current = Current->Children.empty() ? NULL : &Current->Children[0]; 91232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 913bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper 914bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper DEBUG({ 915bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper printDebugInfo(Line); 916bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper }); 91732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} 91832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 9198ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasperunsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line, 9208ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper const AnnotatedToken &Tok) { 92132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper const AnnotatedToken &Left = *Tok.Parent; 92232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper const AnnotatedToken &Right = Tok; 92332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 9243c08a818a6ac9115fe8880af9bbf5a0a87bdffaaDaniel Jasper if (Right.Type == TT_StartOfName) { 9258ed9f2b25f082a1643ab5310f9eec33cf31a7577Daniel Jasper if (Line.First.is(tok::kw_for) && Right.PartOfMultiVariableDeclStmt) 9263c08a818a6ac9115fe8880af9bbf5a0a87bdffaaDaniel Jasper return 3; 9273c08a818a6ac9115fe8880af9bbf5a0a87bdffaaDaniel Jasper else if (Line.MightBeFunctionDecl && Right.BindingStrength == 1) 9283c08a818a6ac9115fe8880af9bbf5a0a87bdffaaDaniel Jasper // FIXME: Clean up hack of using BindingStrength to find top-level names. 9293c08a818a6ac9115fe8880af9bbf5a0a87bdffaaDaniel Jasper return Style.PenaltyReturnTypeOnItsOwnLine; 9303c08a818a6ac9115fe8880af9bbf5a0a87bdffaaDaniel Jasper else 9311407bee187d7b964d5293ac8bf4f7a490c78cec6Daniel Jasper return 200; 9323c08a818a6ac9115fe8880af9bbf5a0a87bdffaaDaniel Jasper } 93332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::equal) && Right.is(tok::l_brace)) 93432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return 150; 93532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::coloncolon)) 93632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return 500; 9376b119d63f5036344acd4e00a6ff2b3c72f26966fDaniel Jasper if (Left.isOneOf(tok::kw_class, tok::kw_struct)) 9386b119d63f5036344acd4e00a6ff2b3c72f26966fDaniel Jasper return 5000; 93932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 9406cabab48dacc1317821f8f078ed2d4c603b67affDaniel Jasper if (Left.Type == TT_RangeBasedForLoopColon || 9416cabab48dacc1317821f8f078ed2d4c603b67affDaniel Jasper Left.Type == TT_InheritanceColon) 94284a1a63b034744b68a27ec171dca5b1b7cf303f0Daniel Jasper return 2; 94332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 944e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko if (Right.isOneOf(tok::arrow, tok::period)) { 945515f65df40624a767bc8763a0b6b678146b8e3c9Daniel Jasper if (Line.Type == LT_BuilderTypeCall) 9466a365aaa057a8c445d25344c0433726c752b3e7dDaniel Jasper return prec::PointerToMember; 947e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko if (Left.isOneOf(tok::r_paren, tok::r_square) && Left.MatchingParen && 948e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko Left.MatchingParen->ParameterCount > 0) 949518ee34467c0722e253a58efea20456e96aa5802Daniel Jasper return 20; // Should be smaller than breaking at a nested comma. 95032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return 150; 95132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 95232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 95332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // In for-loops, prefer breaking at ',' and ';'. 9547d81281fc39f6d40d86be6600adba13c05b4a639Daniel Jasper if (Line.First.is(tok::kw_for) && Left.is(tok::equal)) 9557d81281fc39f6d40d86be6600adba13c05b4a639Daniel Jasper return 4; 95632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 9578159d2f271c9142b46a672ac2c45821911171a7dDaniel Jasper if (Left.is(tok::semi)) 95832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return 0; 9598159d2f271c9142b46a672ac2c45821911171a7dDaniel Jasper if (Left.is(tok::comma)) 9608159d2f271c9142b46a672ac2c45821911171a7dDaniel Jasper return 1; 96132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 96232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // In Objective-C method expressions, prefer breaking before "param:" over 96332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // breaking after it. 96463d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper if (Right.Type == TT_ObjCSelectorName) 96532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return 0; 96663d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper if (Left.is(tok::colon) && Left.Type == TT_ObjCMethodExpr) 96732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return 20; 96832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 9691407bee187d7b964d5293ac8bf4f7a490c78cec6Daniel Jasper if (Left.is(tok::l_paren) && Line.MightBeFunctionDecl) 9701407bee187d7b964d5293ac8bf4f7a490c78cec6Daniel Jasper return 100; 971ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper if (Left.opensScope()) 97264f092865c01c72ecb9e380432e241f3af55c249Daniel Jasper return Left.ParameterCount > 1 ? prec::Comma : 20; 97332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 9744e8a7b4a95962f63a938c0d21c9aca0a51b78345Daniel Jasper if (Right.is(tok::lessless)) { 9754e8a7b4a95962f63a938c0d21c9aca0a51b78345Daniel Jasper if (Left.is(tok::string_literal)) { 976bfa1edd8247b80e951a570ff2486fe5fa9898c41Daniel Jasper StringRef Content = StringRef(Left.FormatTok.Tok.getLiteralData(), 977bfa1edd8247b80e951a570ff2486fe5fa9898c41Daniel Jasper Left.FormatTok.TokenLength); 978bfa1edd8247b80e951a570ff2486fe5fa9898c41Daniel Jasper Content = Content.drop_back(1).drop_front(1).trim(); 979bfa1edd8247b80e951a570ff2486fe5fa9898c41Daniel Jasper if (Content.size() > 1 && 980bfa1edd8247b80e951a570ff2486fe5fa9898c41Daniel Jasper (Content.back() == ':' || Content.back() == '=')) 9814e8a7b4a95962f63a938c0d21c9aca0a51b78345Daniel Jasper return 100; 9824e8a7b4a95962f63a938c0d21c9aca0a51b78345Daniel Jasper } 9830178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return prec::Shift; 9844e8a7b4a95962f63a938c0d21c9aca0a51b78345Daniel Jasper } 98532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.Type == TT_ConditionalExpr) 986518ee34467c0722e253a58efea20456e96aa5802Daniel Jasper return prec::Conditional; 98732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper prec::Level Level = getPrecedence(Left); 98832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 98932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Level != prec::Unknown) 99032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return Level; 991248497199bc56e86d1c089beb9529f3b3d77abb1Daniel Jasper 99232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return 3; 99332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} 99432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 9958ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasperbool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, 9968ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper const AnnotatedToken &Left, 99732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper const AnnotatedToken &Right) { 99832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::hashhash)) 99932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return Left.is(tok::hash); 1000e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko if (Left.isOneOf(tok::hashhash, tok::hash)) 100132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return Right.is(tok::hash); 1002e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko if (Right.isOneOf(tok::r_paren, tok::semi, tok::comma)) 100332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 100432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::less) && 100532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper (Left.is(tok::kw_template) || 100632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper (Line.Type == LT_ObjCDecl && Style.ObjCSpaceBeforeProtocolList))) 100732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 100832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::arrow) || Right.is(tok::arrow)) 100932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 1010e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko if (Left.isOneOf(tok::exclaim, tok::tilde)) 101132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 101232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::at) && 1013e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko Right.isOneOf(tok::identifier, tok::string_literal, tok::char_constant, 1014e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko tok::numeric_constant, tok::l_paren, tok::l_brace, 1015e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko tok::kw_true, tok::kw_false)) 101632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 101732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::coloncolon)) 101832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 101932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::coloncolon)) 1020e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko return !Left.isOneOf(tok::identifier, tok::greater, tok::l_paren); 1021e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko if (Left.is(tok::less) || Right.isOneOf(tok::greater, tok::less)) 102232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 10233fd9ccdd9f8d259bcf518e7056cfd419d992e984Alexander Kornienko if (Right.Type == TT_PointerOrReference) 102432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return Left.FormatTok.Tok.isLiteral() || 10253fd9ccdd9f8d259bcf518e7056cfd419d992e984Alexander Kornienko ((Left.Type != TT_PointerOrReference) && Left.isNot(tok::l_paren) && 10263fd9ccdd9f8d259bcf518e7056cfd419d992e984Alexander Kornienko !Style.PointerBindsToType); 10273fd9ccdd9f8d259bcf518e7056cfd419d992e984Alexander Kornienko if (Left.Type == TT_PointerOrReference) 102895e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weber return Right.FormatTok.Tok.isLiteral() || 10299322aaee900b872c98f8fc10b38a231cb1e9b57aDaniel Jasper ((Right.Type != TT_PointerOrReference) && 103081d2d38d2d774a2550fa0d2efffa707e7a53b39cDaniel Jasper Right.isNot(tok::l_paren) && Style.PointerBindsToType && 103181d2d38d2d774a2550fa0d2efffa707e7a53b39cDaniel Jasper Left.Parent && Left.Parent->isNot(tok::l_paren)); 103232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::star) && Left.is(tok::l_paren)) 103332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 1034051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber if (Left.is(tok::l_square)) 1035051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber return Left.Type == TT_ObjCArrayLiteral && Right.isNot(tok::r_square); 1036051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber if (Right.is(tok::r_square)) 1037051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber return Right.Type == TT_ObjCArrayLiteral; 103832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::l_square) && Right.Type != TT_ObjCMethodExpr) 103932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 104032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::period) || Right.is(tok::period)) 104132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 104232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::colon)) 104332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return Left.Type != TT_ObjCMethodExpr; 104432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::colon)) 104532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return Right.Type != TT_ObjCMethodExpr; 104632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::l_paren)) 104732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 104832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::l_paren)) { 1049e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko return Line.Type == LT_ObjCDecl || 1050e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko Left.isOneOf(tok::kw_if, tok::kw_for, tok::kw_while, tok::kw_switch, 1051e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko tok::kw_return, tok::kw_catch, tok::kw_new, 1052454cb70f9470dc37d0c0646012877d64fb1e73d7Daniel Jasper tok::kw_delete, tok::semi); 105332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 105432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::at) && 105532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Right.FormatTok.Tok.getObjCKeywordID() != tok::objc_not_keyword) 105632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 105732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::l_brace) && Right.is(tok::r_brace)) 105832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 1059f022018698ced7e538b338d4f7befef9f81051eaDaniel Jasper if (Right.is(tok::ellipsis)) 1060f022018698ced7e538b338d4f7befef9f81051eaDaniel Jasper return false; 106132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 106232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} 106332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 10648ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasperbool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, 10658ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper const AnnotatedToken &Tok) { 10662b4c924f85e156d66c01b3f16c850892c47dcc7aDaniel Jasper if (Tok.FormatTok.Tok.getIdentifierInfo() && 10672b4c924f85e156d66c01b3f16c850892c47dcc7aDaniel Jasper Tok.Parent->FormatTok.Tok.getIdentifierInfo()) 10682b4c924f85e156d66c01b3f16c850892c47dcc7aDaniel Jasper return true; // Never ever merge two identifiers. 106932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Line.Type == LT_ObjCMethodDecl) { 107032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.Parent->Type == TT_ObjCMethodSpecifier) 107132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 107232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.Parent->is(tok::r_paren) && Tok.is(tok::identifier)) 107332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // Don't space between ')' and <id> 107432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 107532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 107632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Line.Type == LT_ObjCProperty && 107732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper (Tok.is(tok::equal) || Tok.Parent->is(tok::equal))) 107832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 107932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 108032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.Parent->is(tok::comma)) 108132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 10829c3c7b3130bc72b3f50703c11b85152b1264fc90Daniel Jasper if (Tok.is(tok::comma)) 10839c3c7b3130bc72b3f50703c11b85152b1264fc90Daniel Jasper return false; 108432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.Type == TT_CtorInitializerColon || Tok.Type == TT_ObjCBlockLParen) 108532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 10862b4c924f85e156d66c01b3f16c850892c47dcc7aDaniel Jasper if (Tok.Parent->FormatTok.Tok.is(tok::kw_operator)) 10872b4c924f85e156d66c01b3f16c850892c47dcc7aDaniel Jasper return false; 10882b4c924f85e156d66c01b3f16c850892c47dcc7aDaniel Jasper if (Tok.Type == TT_OverloadedOperatorLParen) 108932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 109032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.is(tok::colon)) 1091e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko return !Line.First.isOneOf(tok::kw_case, tok::kw_default) && 1092ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper Tok.getNextNoneComment() != NULL && Tok.Type != TT_ObjCMethodExpr; 10938a5d7cd100ebfb8c6b353ee4ad5b14ab4105d32dDaniel Jasper if (Tok.is(tok::l_paren) && !Tok.Children.empty() && 10948a5d7cd100ebfb8c6b353ee4ad5b14ab4105d32dDaniel Jasper Tok.Children[0].Type == TT_PointerOrReference && 10958a5d7cd100ebfb8c6b353ee4ad5b14ab4105d32dDaniel Jasper !Tok.Children[0].Children.empty() && 109654a38bd5cf243310290f34b43fc940a498a00f90Alexander Kornienko Tok.Children[0].Children[0].isNot(tok::r_paren) && 109781d2d38d2d774a2550fa0d2efffa707e7a53b39cDaniel Jasper Tok.Parent->isNot(tok::l_paren) && 109881d2d38d2d774a2550fa0d2efffa707e7a53b39cDaniel Jasper (Tok.Parent->Type != TT_PointerOrReference || Style.PointerBindsToType)) 10998a5d7cd100ebfb8c6b353ee4ad5b14ab4105d32dDaniel Jasper return true; 110032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.Parent->Type == TT_UnaryOperator || Tok.Parent->Type == TT_CastRParen) 110132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 110232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.Type == TT_UnaryOperator) 1103e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko return !Tok.Parent->isOneOf(tok::l_paren, tok::l_square, tok::at) && 110432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper (Tok.Parent->isNot(tok::colon) || 110532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Tok.Parent->Type != TT_ObjCMethodExpr); 110632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.Parent->is(tok::greater) && Tok.is(tok::greater)) { 110729f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper return Tok.Type == TT_TemplateCloser && 110829f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper Tok.Parent->Type == TT_TemplateCloser && 110929f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper Style.Standard != FormatStyle::LS_Cpp11; 111032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 111154a38bd5cf243310290f34b43fc940a498a00f90Alexander Kornienko if (Tok.isOneOf(tok::arrowstar, tok::periodstar) || 111254a38bd5cf243310290f34b43fc940a498a00f90Alexander Kornienko Tok.Parent->isOneOf(tok::arrowstar, tok::periodstar)) 11139c3c7b3130bc72b3f50703c11b85152b1264fc90Daniel Jasper return false; 11149c3c7b3130bc72b3f50703c11b85152b1264fc90Daniel Jasper if (Tok.Type == TT_BinaryOperator || Tok.Parent->Type == TT_BinaryOperator) 111532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 111632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.Parent->Type == TT_TemplateCloser && Tok.is(tok::l_paren)) 111732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 111832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.is(tok::less) && Line.First.is(tok::hash)) 111932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 112032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.Type == TT_TrailingUnaryOperator) 112132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 11228ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper return spaceRequiredBetween(Line, *Tok.Parent, Tok); 112332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} 112432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 11258ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasperbool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, 11268ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper const AnnotatedToken &Right) { 112732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper const AnnotatedToken &Left = *Right.Parent; 1128a03ab10f0e4d888139b3b694dd55d176982f72a4Daniel Jasper if (Right.Type == TT_StartOfName) 112932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 113032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::colon) && Right.Type == TT_ObjCMethodExpr) 113132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 113232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::colon) && Left.Type == TT_ObjCMethodExpr) 113332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 113463d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper if (Right.Type == TT_ObjCSelectorName) 113532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 113632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.ClosesTemplateDeclaration) 113732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 113832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.Type == TT_ConditionalExpr || Right.is(tok::question)) 113932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 11406cabab48dacc1317821f8f078ed2d4c603b67affDaniel Jasper if (Right.Type == TT_RangeBasedForLoopColon || 114127b91cc046f580fbe825f15b3e27f1b6407ee3e3Daniel Jasper Right.Type == TT_OverloadedOperatorLParen) 11426cabab48dacc1317821f8f078ed2d4c603b67affDaniel Jasper return false; 1143c194c95036b7bf1281a6f2ed683f7c85ee5d2c20Daniel Jasper if (Left.Type == TT_RangeBasedForLoopColon) 114432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 11457d81281fc39f6d40d86be6600adba13c05b4a639Daniel Jasper if (Right.Type == TT_RangeBasedForLoopColon) 11467d81281fc39f6d40d86be6600adba13c05b4a639Daniel Jasper return false; 114732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.Type == TT_PointerOrReference || Left.Type == TT_TemplateCloser || 114832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left.Type == TT_UnaryOperator || Left.Type == TT_ConditionalExpr || 1149e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko Left.isOneOf(tok::question, tok::kw_operator)) 115032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 115132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::equal) && Line.Type == LT_VirtualFunctionDecl) 115232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 11538ed4100410ea055a03be5ec4a92a947a0ee664cdDaniel Jasper if (Left.is(tok::l_paren) && Right.is(tok::l_paren) && Left.Parent && 11548ed4100410ea055a03be5ec4a92a947a0ee664cdDaniel Jasper Left.Parent->is(tok::kw___attribute)) 11558ed4100410ea055a03be5ec4a92a947a0ee664cdDaniel Jasper return false; 115632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 115732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.Type == TT_LineComment) 115832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // We rely on MustBreakBefore being set correctly here as we should not 115932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // change the "binding" behavior of a comment. 116032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 116132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 116232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // Allow breaking after a trailing 'const', e.g. after a method declaration, 116332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // unless it is follow by ';', '{' or '='. 116432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::kw_const) && Left.Parent != NULL && 116532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left.Parent->is(tok::r_paren)) 1166e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko return !Right.isOneOf(tok::l_brace, tok::semi, tok::equal); 116732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 11688ef19a22956defa392df46c79e2d499ab7b16647Daniel Jasper if (Right.is(tok::kw___attribute)) 11698ef19a22956defa392df46c79e2d499ab7b16647Daniel Jasper return true; 11708ef19a22956defa392df46c79e2d499ab7b16647Daniel Jasper 117132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // We only break before r_brace if there was a corresponding break before 117232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // the l_brace, which is tracked by BreakBeforeClosingBrace. 11738ef19a22956defa392df46c79e2d499ab7b16647Daniel Jasper if (Right.isOneOf(tok::r_brace, tok::r_paren, tok::greater)) 117432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 11753a204418482c9ae70ad482e781132c54306c3aa6Daniel Jasper if (Left.is(tok::identifier) && Right.is(tok::string_literal)) 11763a204418482c9ae70ad482e781132c54306c3aa6Daniel Jasper return true; 1177ac3223e45e7d17c65b143439313800eef4fdf71dDaniel Jasper return (Left.isBinaryOperator() && Left.isNot(tok::lessless)) || 11786b119d63f5036344acd4e00a6ff2b3c72f26966fDaniel Jasper Left.isOneOf(tok::comma, tok::coloncolon, tok::semi, tok::l_brace, 11796b119d63f5036344acd4e00a6ff2b3c72f26966fDaniel Jasper tok::kw_class, tok::kw_struct) || 1180e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko Right.isOneOf(tok::lessless, tok::arrow, tok::period, tok::colon) || 118132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper (Left.is(tok::r_paren) && Left.Type != TT_CastRParen && 1182e74de28ec3692986f3467a7f160a0e293277fa7eAlexander Kornienko Right.isOneOf(tok::identifier, tok::kw___attribute)) || 118332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper (Left.is(tok::l_paren) && !Right.is(tok::r_paren)) || 118432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper (Left.is(tok::l_square) && !Right.is(tok::r_square)); 118532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} 118632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 1187bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jaspervoid TokenAnnotator::printDebugInfo(const AnnotatedLine &Line) { 1188bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper llvm::errs() << "AnnotatedTokens:\n"; 1189bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper const AnnotatedToken *Tok = &Line.First; 1190bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper while (Tok) { 1191bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper llvm::errs() << " M=" << Tok->MustBreakBefore 1192bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper << " C=" << Tok->CanBreakBefore << " T=" << Tok->Type 1193bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper << " S=" << Tok->SpacesRequiredBefore 1194aae7bad5cdd804cb88e918e9defbf5faf69f4cfdDaniel Jasper << " P=" << Tok->SplitPenalty 1195bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper << " Name=" << Tok->FormatTok.Tok.getName() << " FakeLParens="; 1196bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper for (unsigned i = 0, e = Tok->FakeLParens.size(); i != e; ++i) 1197bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper llvm::errs() << Tok->FakeLParens[i] << "/"; 1198bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper llvm::errs() << " FakeRParens=" << Tok->FakeRParens << "\n"; 1199bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper Tok = Tok->Children.empty() ? NULL : &Tok->Children[0]; 1200bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper } 1201bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper llvm::errs() << "----\n"; 1202bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper} 1203bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper 120432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} // namespace format 120532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} // namespace clang 1206