TokenAnnotator.cpp revision 4ed7f3e003c906d9fdb92a9484feeb8ac6e28e2f
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" 1932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 2032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jaspernamespace clang { 2132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jaspernamespace format { 2232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 23ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weberstatic bool isUnaryOperator(const AnnotatedToken &Tok) { 24ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber switch (Tok.FormatTok.Tok.getKind()) { 25ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber case tok::plus: 26ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber case tok::plusplus: 27ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber case tok::minus: 28ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber case tok::minusminus: 29ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber case tok::exclaim: 30ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber case tok::tilde: 31ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber case tok::kw_sizeof: 32ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber case tok::kw_alignof: 33ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber return true; 34ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber default: 35ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber return false; 36ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber } 37ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber} 38ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber 3932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasperstatic bool isBinaryOperator(const AnnotatedToken &Tok) { 4032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // Comma is a binary operator, but does not behave as such wrt. formatting. 4132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return getPrecedence(Tok) > prec::Comma; 4232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} 4332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 440178673f541685cf5067814dfeee2644078e39a9Daniel Jasper// Returns the previous token ignoring comments. 454ed7f3e003c906d9fdb92a9484feeb8ac6e28e2fNico Weberstatic AnnotatedToken *getPreviousToken(AnnotatedToken &Tok) { 464ed7f3e003c906d9fdb92a9484feeb8ac6e28e2fNico Weber AnnotatedToken *PrevToken = Tok.Parent; 470178673f541685cf5067814dfeee2644078e39a9Daniel Jasper while (PrevToken != NULL && PrevToken->is(tok::comment)) 480178673f541685cf5067814dfeee2644078e39a9Daniel Jasper PrevToken = PrevToken->Parent; 490178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return PrevToken; 500178673f541685cf5067814dfeee2644078e39a9Daniel Jasper} 514ed7f3e003c906d9fdb92a9484feeb8ac6e28e2fNico Weberstatic const AnnotatedToken *getPreviousToken(const AnnotatedToken &Tok) { 524ed7f3e003c906d9fdb92a9484feeb8ac6e28e2fNico Weber return getPreviousToken(const_cast<AnnotatedToken &>(Tok)); 534ed7f3e003c906d9fdb92a9484feeb8ac6e28e2fNico Weber} 540178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 550178673f541685cf5067814dfeee2644078e39a9Daniel Jasper// Returns the next token ignoring comments. 560178673f541685cf5067814dfeee2644078e39a9Daniel Jasperstatic const AnnotatedToken *getNextToken(const AnnotatedToken &Tok) { 570178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (Tok.Children.empty()) 580178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return NULL; 590178673f541685cf5067814dfeee2644078e39a9Daniel Jasper const AnnotatedToken *NextToken = &Tok.Children[0]; 600178673f541685cf5067814dfeee2644078e39a9Daniel Jasper while (NextToken->is(tok::comment)) { 610178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (NextToken->Children.empty()) 620178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return NULL; 630178673f541685cf5067814dfeee2644078e39a9Daniel Jasper NextToken = &NextToken->Children[0]; 640178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 650178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return NextToken; 660178673f541685cf5067814dfeee2644078e39a9Daniel Jasper} 670178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 6832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper/// \brief A parser that gathers additional information about tokens. 6932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper/// 7032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper/// The \c TokenAnnotator tries to matches parenthesis and square brakets and 7132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper/// store a parenthesis levels. It also tries to resolve matching "<" and ">" 7232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper/// into template parameter lists. 7332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasperclass AnnotatingParser { 7432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasperpublic: 750178673f541685cf5067814dfeee2644078e39a9Daniel Jasper AnnotatingParser(SourceManager &SourceMgr, Lexer &Lex, AnnotatedLine &Line) 760178673f541685cf5067814dfeee2644078e39a9Daniel Jasper : SourceMgr(SourceMgr), Lex(Lex), Line(Line), CurrentToken(&Line.First), 774e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper KeywordVirtualFound(false) { 784e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.push_back(Context(1, /*IsExpression=*/ false)); 794e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().LookForFunctionName = Line.MustBeDeclaration; 8032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 8132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 8232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool parseAngle() { 8332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken == NULL) 8432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 854e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper ScopedContextCreator ContextCreator(*this, 10); 8632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper AnnotatedToken *Left = CurrentToken->Parent; 874e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().IsExpression = false; 8832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper while (CurrentToken != NULL) { 8932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::greater)) { 9032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left->MatchingParen = CurrentToken; 9132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->MatchingParen = Left; 9232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->Type = TT_TemplateCloser; 9332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 9432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 9532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 9632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::r_paren) || CurrentToken->is(tok::r_square) || 9732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->is(tok::r_brace)) 9832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 9932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::pipepipe) || CurrentToken->is(tok::ampamp) || 10032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->is(tok::question) || CurrentToken->is(tok::colon)) 10132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 10232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::comma)) 10332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper ++Left->ParameterCount; 10432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!consumeToken()) 10532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 10632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 10732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 10832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 10932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 11032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool parseParens(bool LookForDecls = false) { 11132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken == NULL) 11232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 1134e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper ScopedContextCreator ContextCreator(*this, 1); 1144e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper 1154e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper // FIXME: This is a bit of a hack. Do better. 1164e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().ColonIsForRangeExpr = 1174e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.size() == 2 && Contexts[0].ColonIsForRangeExpr; 1184e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper 11932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool StartsObjCMethodExpr = false; 12032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper AnnotatedToken *Left = CurrentToken->Parent; 12132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::caret)) { 12232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // ^( starts a block. 12332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left->Type = TT_ObjCBlockLParen; 12432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } else if (AnnotatedToken *MaybeSel = Left->Parent) { 12532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // @selector( starts a selector. 12632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (MaybeSel->isObjCAtKeyword(tok::objc_selector) && MaybeSel->Parent && 12732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper MaybeSel->Parent->is(tok::at)) { 12832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper StartsObjCMethodExpr = true; 12932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 13032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 13132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 1324e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper if (StartsObjCMethodExpr) { 1334e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().ColonIsObjCMethodExpr = true; 1344e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Left->Type = TT_ObjCMethodExpr; 1354e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper } 13632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 13732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper while (CurrentToken != NULL) { 13832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // LookForDecls is set when "if (" has been seen. Check for 13932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // 'identifier' '*' 'identifier' followed by not '=' -- this 14032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // '*' has to be a binary operator but determineStarAmpUsage() will 14132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // categorize it as an unary operator, so set the right type here. 14232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (LookForDecls && !CurrentToken->Children.empty()) { 14332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper AnnotatedToken &Prev = *CurrentToken->Parent; 14432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper AnnotatedToken &Next = CurrentToken->Children[0]; 14532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Prev.Parent->is(tok::identifier) && 14632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper (Prev.is(tok::star) || Prev.is(tok::amp)) && 14732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->is(tok::identifier) && Next.isNot(tok::equal)) { 14832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Prev.Type = TT_BinaryOperator; 14932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper LookForDecls = false; 15032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 15132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 15232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 15332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::r_paren)) { 15432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left->MatchingParen = CurrentToken; 15532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->MatchingParen = Left; 15632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 15763d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper if (StartsObjCMethodExpr) { 1584e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper CurrentToken->Type = TT_ObjCMethodExpr; 1594e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper if (Contexts.back().FirstObjCSelectorName != NULL) { 1604e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 1614e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().LongestObjCSelectorName; 16263d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper } 16363d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper } 16432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 16532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 16632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 16732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 16832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::r_square) || CurrentToken->is(tok::r_brace)) 16932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 17032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::comma)) 17132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper ++Left->ParameterCount; 17232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!consumeToken()) 17332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 17432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 17532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 17632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 17732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 17832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool parseSquare() { 17932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!CurrentToken) 18032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 1814e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper ScopedContextCreator ContextCreator(*this, 10); 18232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 18332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // A '[' could be an index subscript (after an indentifier or after 18432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // ')' or ']'), or it could be the start of an Objective-C method 18532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // expression. 18632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper AnnotatedToken *Left = CurrentToken->Parent; 1874ed7f3e003c906d9fdb92a9484feeb8ac6e28e2fNico Weber AnnotatedToken *Parent = getPreviousToken(*Left); 18832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool StartsObjCMethodExpr = 1894ed7f3e003c906d9fdb92a9484feeb8ac6e28e2fNico Weber !Parent || Parent->is(tok::colon) || Parent->is(tok::l_square) || 1904ed7f3e003c906d9fdb92a9484feeb8ac6e28e2fNico Weber Parent->is(tok::l_paren) || Parent->is(tok::kw_return) || 1914ed7f3e003c906d9fdb92a9484feeb8ac6e28e2fNico Weber Parent->is(tok::kw_throw) || isUnaryOperator(*Parent) || 1924ed7f3e003c906d9fdb92a9484feeb8ac6e28e2fNico Weber getBinOpPrecedence(Parent->FormatTok.Tok.getKind(), true, true) > 19332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper prec::Unknown; 19432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 1954e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper if (StartsObjCMethodExpr) { 1964e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().ColonIsObjCMethodExpr = true; 1974e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Left->Type = TT_ObjCMethodExpr; 1984e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper } 19932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 20032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper while (CurrentToken != NULL) { 20132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::r_square)) { 20232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!CurrentToken->Children.empty() && 20332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->Children[0].is(tok::l_paren)) { 204e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber // An ObjC method call is rarely followed by an open parenthesis. 20532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // FIXME: Do we incorrectly label ":" with this? 20632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper StartsObjCMethodExpr = false; 20732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left->Type = TT_Unknown; 20832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 2090178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (StartsObjCMethodExpr) { 2104e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper CurrentToken->Type = TT_ObjCMethodExpr; 211e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber // determineStarAmpUsage() thinks that '*' '[' is allocating an 212e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber // array of pointers, but if '[' starts a selector then '*' is a 213e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber // binary operator. 2144ed7f3e003c906d9fdb92a9484feeb8ac6e28e2fNico Weber if (Parent != NULL && 2154ed7f3e003c906d9fdb92a9484feeb8ac6e28e2fNico Weber (Parent->is(tok::star) || Parent->is(tok::amp)) && 2164ed7f3e003c906d9fdb92a9484feeb8ac6e28e2fNico Weber Parent->Type == TT_PointerOrReference) 2174ed7f3e003c906d9fdb92a9484feeb8ac6e28e2fNico Weber Parent->Type = TT_BinaryOperator; 2180178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 21932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left->MatchingParen = CurrentToken; 22032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->MatchingParen = Left; 2214e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper if (Contexts.back().FirstObjCSelectorName != NULL) 2224e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 2234e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().LongestObjCSelectorName; 22432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 22532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 22632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 22732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::r_paren) || CurrentToken->is(tok::r_brace)) 22832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 22932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::comma)) 23032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper ++Left->ParameterCount; 23132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!consumeToken()) 23232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 23332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 23432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 23532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 23632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 23732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool parseBrace() { 23832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // Lines are fine to end with '{'. 23932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken == NULL) 24032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 2414e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper ScopedContextCreator ContextCreator(*this, 1); 24232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper AnnotatedToken *Left = CurrentToken->Parent; 24332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper while (CurrentToken != NULL) { 24432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::r_brace)) { 24532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left->MatchingParen = CurrentToken; 24632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->MatchingParen = Left; 24732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 24832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 24932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 25032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::r_paren) || CurrentToken->is(tok::r_square)) 25132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 252f343cabb68d495041706b8e2f1ed48fbac3cba06Daniel Jasper if (CurrentToken->is(tok::comma)) 253f343cabb68d495041706b8e2f1ed48fbac3cba06Daniel Jasper ++Left->ParameterCount; 25432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!consumeToken()) 25532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 25632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 25732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 25832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 25932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 26032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool parseConditional() { 26132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper while (CurrentToken != NULL) { 26232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::colon)) { 26332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->Type = TT_ConditionalExpr; 26432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 26532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 26632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 26732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!consumeToken()) 26832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 26932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 27032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 27132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 27232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 27332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool parseTemplateDeclaration() { 27432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken != NULL && CurrentToken->is(tok::less)) { 27532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->Type = TT_TemplateOpener; 27632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 27732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!parseAngle()) 27832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 27932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->Parent->ClosesTemplateDeclaration = true; 28032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 28132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 28232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 28332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 28432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 28532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool consumeToken() { 28632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper AnnotatedToken *Tok = CurrentToken; 28732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 28832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper switch (Tok->FormatTok.Tok.getKind()) { 28932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::plus: 29032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::minus: 29132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // At the start of the line, +/- specific ObjectiveC method 29232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // declarations. 29332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok->Parent == NULL) 29432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Tok->Type = TT_ObjCMethodSpecifier; 29532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 29632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::colon: 29732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // Colons from ?: are handled in parseConditional(). 29863d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper if (Tok->Parent->is(tok::r_paren)) { 29932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Tok->Type = TT_CtorInitializerColon; 3004e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper } else if (Contexts.back().ColonIsObjCMethodExpr || 30163d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper Line.First.Type == TT_ObjCMethodSpecifier) { 30232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Tok->Type = TT_ObjCMethodExpr; 30363d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper Tok->Parent->Type = TT_ObjCSelectorName; 3044e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper if (Tok->Parent->FormatTok.TokenLength > 3054e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().LongestObjCSelectorName) 3064e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().LongestObjCSelectorName = 3074e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Tok->Parent->FormatTok.TokenLength; 3084e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper if (Contexts.back().FirstObjCSelectorName == NULL) 3094e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().FirstObjCSelectorName = Tok->Parent; 3104e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper } else if (Contexts.back().ColonIsForRangeExpr) { 31132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Tok->Type = TT_RangeBasedForLoopColon; 31263d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper } 31332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 31432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::kw_if: 31532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::kw_while: 31632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken != NULL && CurrentToken->is(tok::l_paren)) { 31732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 31832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!parseParens(/*LookForDecls=*/ true)) 31932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 32032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 32132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 32232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::kw_for: 3234e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().ColonIsForRangeExpr = true; 32432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 32532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!parseParens()) 32632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 32732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 32832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::l_paren: 32932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!parseParens()) 33032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 33132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 33232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::l_square: 33332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!parseSquare()) 33432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 33532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 33632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::l_brace: 33732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!parseBrace()) 33832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 33932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 34032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::less: 34132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (parseAngle()) 34232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Tok->Type = TT_TemplateOpener; 34332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper else { 34432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Tok->Type = TT_BinaryOperator; 34532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken = Tok; 34632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 34732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 34832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 34932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::r_paren: 35032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::r_square: 35132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 35232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::r_brace: 35332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // Lines can start with '}'. 35432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok->Parent != NULL) 35532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 35632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 35732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::greater: 35832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Tok->Type = TT_BinaryOperator; 35932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 36032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::kw_operator: 36132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken != NULL && CurrentToken->is(tok::l_paren)) { 36232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->Type = TT_OverloadedOperator; 36332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 36432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken != NULL && CurrentToken->is(tok::r_paren)) { 36532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->Type = TT_OverloadedOperator; 36632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 36732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 36832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } else { 36932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper while (CurrentToken != NULL && CurrentToken->isNot(tok::l_paren)) { 37032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->Type = TT_OverloadedOperator; 37132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 37232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 37332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 37432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 37532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::question: 37632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper parseConditional(); 37732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 37832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::kw_template: 37932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper parseTemplateDeclaration(); 38032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 38132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper default: 38232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 38332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 38432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 38532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 38632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 38732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper void parseIncludeDirective() { 38832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 38932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken != NULL && CurrentToken->is(tok::less)) { 39032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 39132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper while (CurrentToken != NULL) { 39232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->isNot(tok::comment) || 39332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper !CurrentToken->Children.empty()) 39432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->Type = TT_ImplicitStringLiteral; 39532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 39632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 39732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } else { 39832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper while (CurrentToken != NULL) { 39932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 40032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 40132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 40232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 40332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 40432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper void parseWarningOrError() { 40532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 40632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // We still want to format the whitespace left of the first token of the 40732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // warning or error. 40832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 40932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper while (CurrentToken != NULL) { 41032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->Type = TT_ImplicitStringLiteral; 41132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 41232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 41332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 41432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 41532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper void parsePreprocessorDirective() { 41632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 41732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken == NULL) 41832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return; 41932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // Hashes in the middle of a line can lead to any strange token 42032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // sequence. 42132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->FormatTok.Tok.getIdentifierInfo() == NULL) 42232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return; 42332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper switch (CurrentToken->FormatTok.Tok.getIdentifierInfo()->getPPKeywordID()) { 42432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::pp_include: 42532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::pp_import: 42632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper parseIncludeDirective(); 42732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 42832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::pp_error: 42932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::pp_warning: 43032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper parseWarningOrError(); 43132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 43232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper default: 43332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 43432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 4355b7e7b0ec77f49c1b24deffc9b7032ca16ca9f0dDaniel Jasper while (CurrentToken != NULL) 4365b7e7b0ec77f49c1b24deffc9b7032ca16ca9f0dDaniel Jasper next(); 43732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 43832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 43932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper LineType parseLine() { 44032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper int PeriodsAndArrows = 0; 44132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool CanBeBuilderTypeStmt = true; 44232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::hash)) { 44332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper parsePreprocessorDirective(); 44432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return LT_PreprocessorDirective; 44532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 44632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper while (CurrentToken != NULL) { 44732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::kw_virtual)) 44832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper KeywordVirtualFound = true; 44932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::period) || CurrentToken->is(tok::arrow)) 45032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper ++PeriodsAndArrows; 45132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (getPrecedence(*CurrentToken) > prec::Assignment && 45232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->isNot(tok::less) && CurrentToken->isNot(tok::greater)) 45332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CanBeBuilderTypeStmt = false; 45432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!consumeToken()) 45532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return LT_Invalid; 45632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 45732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (KeywordVirtualFound) 45832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return LT_VirtualFunctionDecl; 45932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 46032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // Assume a builder-type call if there are 2 or more "." and "->". 46132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (PeriodsAndArrows >= 2 && CanBeBuilderTypeStmt) 46232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return LT_BuilderTypeCall; 46332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 46463d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper if (Line.First.Type == TT_ObjCMethodSpecifier) { 4654e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper if (Contexts.back().FirstObjCSelectorName != NULL) 4664e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 4674e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().LongestObjCSelectorName; 46863d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper return LT_ObjCMethodDecl; 46963d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper } 47063d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper 47132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return LT_Other; 47232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 47332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 47432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper void next() { 4750178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (CurrentToken != NULL) { 4760178673f541685cf5067814dfeee2644078e39a9Daniel Jasper determineTokenType(*CurrentToken); 4774e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper CurrentToken->BindingStrength = Contexts.back().BindingStrength; 4780178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 4790178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 48032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken != NULL && !CurrentToken->Children.empty()) 48132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken = &CurrentToken->Children[0]; 48232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper else 48332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken = NULL; 48432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 48532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 48632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasperprivate: 4874e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper /// \brief A struct to hold information valid in a specific context, e.g. 4884e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper /// a pair of parenthesis. 4894e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper struct Context { 4904e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Context(unsigned BindingStrength, bool IsExpression) 4914e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper : BindingStrength(BindingStrength), LongestObjCSelectorName(0), 4924e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper ColonIsForRangeExpr(false), ColonIsObjCMethodExpr(false), 4934e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper FirstObjCSelectorName(NULL), IsExpression(IsExpression), 4944e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper LookForFunctionName(false) { 4954e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper } 4960178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 4974e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper unsigned BindingStrength; 4984e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper unsigned LongestObjCSelectorName; 4994e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper bool ColonIsForRangeExpr; 5004e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper bool ColonIsObjCMethodExpr; 5014e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper AnnotatedToken *FirstObjCSelectorName; 5024e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper bool IsExpression; 5034e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper bool LookForFunctionName; 5044e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper }; 5054e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper 5064e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper /// \brief Puts a new \c Context onto the stack \c Contexts for the lifetime 5074e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper /// of each instance. 5084e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper struct ScopedContextCreator { 5094e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper AnnotatingParser &P; 5104e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper 5114e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper ScopedContextCreator(AnnotatingParser &P, unsigned Increase) 5124e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper : P(P) { 5134e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper P.Contexts.push_back(Context( 5144e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper P.Contexts.back().BindingStrength + Increase, 5154e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper P.Contexts.back().IsExpression)); 5164e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper } 5174e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper 5184e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper ~ScopedContextCreator() { P.Contexts.pop_back(); } 5194e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper }; 5200178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 5210178673f541685cf5067814dfeee2644078e39a9Daniel Jasper void determineTokenType(AnnotatedToken &Current) { 5220178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (getPrecedence(Current) == prec::Assignment) { 5234e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().IsExpression = true; 5240178673f541685cf5067814dfeee2644078e39a9Daniel Jasper AnnotatedToken *Previous = Current.Parent; 5256b5ba8be528bf614d5f4477a4cdbd7c3b19714a6Daniel Jasper while (Previous != NULL && Previous->isNot(tok::comma)) { 5260178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (Previous->Type == TT_BinaryOperator && 5270178673f541685cf5067814dfeee2644078e39a9Daniel Jasper (Previous->is(tok::star) || Previous->is(tok::amp))) { 5280178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Previous->Type = TT_PointerOrReference; 5290178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 5300178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Previous = Previous->Parent; 5310178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 5320178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 5330178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (Current.is(tok::kw_return) || Current.is(tok::kw_throw) || 5340178673f541685cf5067814dfeee2644078e39a9Daniel Jasper (Current.is(tok::l_paren) && !Line.MustBeDeclaration && 5350178673f541685cf5067814dfeee2644078e39a9Daniel Jasper (Current.Parent == NULL || Current.Parent->isNot(tok::kw_for)))) 5364e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().IsExpression = true; 5370178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 5380178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (Current.Type == TT_Unknown) { 5394e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper if (Contexts.back().LookForFunctionName && Current.is(tok::l_paren)) { 5400178673f541685cf5067814dfeee2644078e39a9Daniel Jasper findFunctionName(&Current); 5414e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().LookForFunctionName = false; 5420178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } else if (Current.is(tok::star) || Current.is(tok::amp)) { 5434e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Current.Type = 5444e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper determineStarAmpUsage(Current, Contexts.back().IsExpression); 5450178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } else if (Current.is(tok::minus) || Current.is(tok::plus) || 5460178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.is(tok::caret)) { 5470178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.Type = determinePlusMinusCaretUsage(Current); 5480178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } else if (Current.is(tok::minusminus) || Current.is(tok::plusplus)) { 5490178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.Type = determineIncrementUsage(Current); 5500178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } else if (Current.is(tok::exclaim)) { 5510178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.Type = TT_UnaryOperator; 5520178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } else if (isBinaryOperator(Current)) { 5530178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.Type = TT_BinaryOperator; 5540178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } else if (Current.is(tok::comment)) { 5550178673f541685cf5067814dfeee2644078e39a9Daniel Jasper std::string Data(Lexer::getSpelling(Current.FormatTok.Tok, SourceMgr, 5560178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Lex.getLangOpts())); 5570178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (StringRef(Data).startswith("//")) 5580178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.Type = TT_LineComment; 5590178673f541685cf5067814dfeee2644078e39a9Daniel Jasper else 5600178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.Type = TT_BlockComment; 5610178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } else if (Current.is(tok::r_paren) && 5620178673f541685cf5067814dfeee2644078e39a9Daniel Jasper (Current.Parent->Type == TT_PointerOrReference || 5630178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.Parent->Type == TT_TemplateCloser) && 5640178673f541685cf5067814dfeee2644078e39a9Daniel Jasper (Current.Children.empty() || 5650178673f541685cf5067814dfeee2644078e39a9Daniel Jasper (Current.Children[0].isNot(tok::equal) && 5660178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.Children[0].isNot(tok::semi) && 5670178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.Children[0].isNot(tok::l_brace)))) { 5680178673f541685cf5067814dfeee2644078e39a9Daniel Jasper // FIXME: We need to get smarter and understand more cases of casts. 5690178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.Type = TT_CastRParen; 5700178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } else if (Current.is(tok::at) && Current.Children.size()) { 5710178673f541685cf5067814dfeee2644078e39a9Daniel Jasper switch (Current.Children[0].FormatTok.Tok.getObjCKeywordID()) { 5720178673f541685cf5067814dfeee2644078e39a9Daniel Jasper case tok::objc_interface: 5730178673f541685cf5067814dfeee2644078e39a9Daniel Jasper case tok::objc_implementation: 5740178673f541685cf5067814dfeee2644078e39a9Daniel Jasper case tok::objc_protocol: 5750178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.Type = TT_ObjCDecl; 5760178673f541685cf5067814dfeee2644078e39a9Daniel Jasper break; 5770178673f541685cf5067814dfeee2644078e39a9Daniel Jasper case tok::objc_property: 5780178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.Type = TT_ObjCProperty; 5790178673f541685cf5067814dfeee2644078e39a9Daniel Jasper break; 5800178673f541685cf5067814dfeee2644078e39a9Daniel Jasper default: 5810178673f541685cf5067814dfeee2644078e39a9Daniel Jasper break; 5820178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 5830178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 5840178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 5850178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 5860178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 5870178673f541685cf5067814dfeee2644078e39a9Daniel Jasper /// \brief Starting from \p Current, this searches backwards for an 5880178673f541685cf5067814dfeee2644078e39a9Daniel Jasper /// identifier which could be the start of a function name and marks it. 5890178673f541685cf5067814dfeee2644078e39a9Daniel Jasper void findFunctionName(AnnotatedToken *Current) { 5900178673f541685cf5067814dfeee2644078e39a9Daniel Jasper AnnotatedToken *Parent = Current->Parent; 5910178673f541685cf5067814dfeee2644078e39a9Daniel Jasper while (Parent != NULL && Parent->Parent != NULL) { 5920178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (Parent->is(tok::identifier) && 5930178673f541685cf5067814dfeee2644078e39a9Daniel Jasper (Parent->Parent->is(tok::identifier) || 5940178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Parent->Parent->Type == TT_PointerOrReference || 5950178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Parent->Parent->Type == TT_TemplateCloser)) { 5960178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Parent->Type = TT_StartOfName; 5970178673f541685cf5067814dfeee2644078e39a9Daniel Jasper break; 5980178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 5990178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Parent = Parent->Parent; 6000178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 6010178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 6020178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 6030178673f541685cf5067814dfeee2644078e39a9Daniel Jasper /// \brief Return the type of the given token assuming it is * or &. 6040178673f541685cf5067814dfeee2644078e39a9Daniel Jasper TokenType 6050178673f541685cf5067814dfeee2644078e39a9Daniel Jasper determineStarAmpUsage(const AnnotatedToken &Tok, bool IsExpression) { 6060178673f541685cf5067814dfeee2644078e39a9Daniel Jasper const AnnotatedToken *PrevToken = getPreviousToken(Tok); 6070178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (PrevToken == NULL) 6080178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_UnaryOperator; 6090178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 6100178673f541685cf5067814dfeee2644078e39a9Daniel Jasper const AnnotatedToken *NextToken = getNextToken(Tok); 6110178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (NextToken == NULL) 6120178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_Unknown; 6130178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 6140178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (PrevToken->is(tok::l_paren) || PrevToken->is(tok::l_square) || 6150178673f541685cf5067814dfeee2644078e39a9Daniel Jasper PrevToken->is(tok::l_brace) || PrevToken->is(tok::comma) || 6160178673f541685cf5067814dfeee2644078e39a9Daniel Jasper PrevToken->is(tok::kw_return) || PrevToken->is(tok::colon) || 617e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber PrevToken->is(tok::equal) || PrevToken->Type == TT_BinaryOperator || 6180178673f541685cf5067814dfeee2644078e39a9Daniel Jasper PrevToken->Type == TT_UnaryOperator || PrevToken->Type == TT_CastRParen) 6190178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_UnaryOperator; 6200178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 621e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber if (NextToken->is(tok::l_square)) 622e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber return TT_PointerOrReference; 623e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber 6240178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (PrevToken->FormatTok.Tok.isLiteral() || PrevToken->is(tok::r_paren) || 6250178673f541685cf5067814dfeee2644078e39a9Daniel Jasper PrevToken->is(tok::r_square) || NextToken->FormatTok.Tok.isLiteral() || 626ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber isUnaryOperator(*NextToken) || NextToken->is(tok::l_paren) || 627ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber NextToken->is(tok::l_square)) 6280178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_BinaryOperator; 6290178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 6300178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (NextToken->is(tok::comma) || NextToken->is(tok::r_paren) || 6310178673f541685cf5067814dfeee2644078e39a9Daniel Jasper NextToken->is(tok::greater)) 6320178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_PointerOrReference; 6330178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 6340178673f541685cf5067814dfeee2644078e39a9Daniel Jasper // It is very unlikely that we are going to find a pointer or reference type 6350178673f541685cf5067814dfeee2644078e39a9Daniel Jasper // definition on the RHS of an assignment. 6360178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (IsExpression) 6370178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_BinaryOperator; 6380178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 6390178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_PointerOrReference; 6400178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 6410178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 6420178673f541685cf5067814dfeee2644078e39a9Daniel Jasper TokenType determinePlusMinusCaretUsage(const AnnotatedToken &Tok) { 6430178673f541685cf5067814dfeee2644078e39a9Daniel Jasper const AnnotatedToken *PrevToken = getPreviousToken(Tok); 6440178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (PrevToken == NULL) 6450178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_UnaryOperator; 6460178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 6470178673f541685cf5067814dfeee2644078e39a9Daniel Jasper // Use heuristics to recognize unary operators. 6480178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (PrevToken->is(tok::equal) || PrevToken->is(tok::l_paren) || 6490178673f541685cf5067814dfeee2644078e39a9Daniel Jasper PrevToken->is(tok::comma) || PrevToken->is(tok::l_square) || 6500178673f541685cf5067814dfeee2644078e39a9Daniel Jasper PrevToken->is(tok::question) || PrevToken->is(tok::colon) || 6510178673f541685cf5067814dfeee2644078e39a9Daniel Jasper PrevToken->is(tok::kw_return) || PrevToken->is(tok::kw_case) || 6520178673f541685cf5067814dfeee2644078e39a9Daniel Jasper PrevToken->is(tok::at) || PrevToken->is(tok::l_brace)) 6530178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_UnaryOperator; 6540178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 655ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber // There can't be two consecutive binary operators. 6560178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (PrevToken->Type == TT_BinaryOperator) 6570178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_UnaryOperator; 6580178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 6590178673f541685cf5067814dfeee2644078e39a9Daniel Jasper // Fall back to marking the token as binary operator. 6600178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_BinaryOperator; 6610178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 6620178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 6630178673f541685cf5067814dfeee2644078e39a9Daniel Jasper /// \brief Determine whether ++/-- are pre- or post-increments/-decrements. 6640178673f541685cf5067814dfeee2644078e39a9Daniel Jasper TokenType determineIncrementUsage(const AnnotatedToken &Tok) { 6650178673f541685cf5067814dfeee2644078e39a9Daniel Jasper const AnnotatedToken *PrevToken = getPreviousToken(Tok); 6660178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (PrevToken == NULL) 6670178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_UnaryOperator; 6680178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (PrevToken->is(tok::r_paren) || PrevToken->is(tok::r_square) || 6690178673f541685cf5067814dfeee2644078e39a9Daniel Jasper PrevToken->is(tok::identifier)) 6700178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_TrailingUnaryOperator; 6710178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 6720178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_UnaryOperator; 6730178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 6744e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper 6754e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper SmallVector<Context, 8> Contexts; 6764e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper 6774e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper SourceManager &SourceMgr; 6784e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Lexer &Lex; 6794e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper AnnotatedLine &Line; 6804e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper AnnotatedToken *CurrentToken; 6814e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper bool KeywordVirtualFound; 68232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper}; 68332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 6848ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jaspervoid TokenAnnotator::annotate(AnnotatedLine &Line) { 6850178673f541685cf5067814dfeee2644078e39a9Daniel Jasper AnnotatingParser Parser(SourceMgr, Lex, Line); 68632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Line.Type = Parser.parseLine(); 68732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Line.Type == LT_Invalid) 68832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return; 68932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 69032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Line.First.Type == TT_ObjCMethodSpecifier) 69132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Line.Type = LT_ObjCMethodDecl; 69232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper else if (Line.First.Type == TT_ObjCDecl) 69332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Line.Type = LT_ObjCDecl; 69432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper else if (Line.First.Type == TT_ObjCProperty) 69532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Line.Type = LT_ObjCProperty; 69632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 69732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Line.First.SpaceRequiredBefore = true; 69832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Line.First.MustBreakBefore = Line.First.FormatTok.MustBreakBefore; 69932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Line.First.CanBreakBefore = Line.First.MustBreakBefore; 70032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 70132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Line.First.TotalLength = Line.First.FormatTok.TokenLength; 70232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} 70332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 7048ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jaspervoid TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) { 7058ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper if (Line.First.Children.empty()) 7068ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper return; 7078ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper AnnotatedToken *Current = &Line.First.Children[0]; 7088ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper while (Current != NULL) { 7098ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->SpaceRequiredBefore = spaceRequiredBefore(Line, *Current); 7108ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper 7118ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper if (Current->FormatTok.MustBreakBefore) { 7128ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->MustBreakBefore = true; 7138ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper } else if (Current->Type == TT_LineComment) { 7148ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->MustBreakBefore = Current->FormatTok.NewlinesBefore > 0; 7158ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper } else if ((Current->Parent->is(tok::comment) && 7168ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->FormatTok.NewlinesBefore > 0) || 7178ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper (Current->is(tok::string_literal) && 7188ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->Parent->is(tok::string_literal))) { 7198ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->MustBreakBefore = true; 7208ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper } else if (Current->is(tok::lessless) && !Current->Children.empty() && 7218ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->Parent->is(tok::string_literal) && 7228ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->Children[0].is(tok::string_literal)) { 7238ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->MustBreakBefore = true; 7248ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper } else { 7258ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->MustBreakBefore = false; 7268ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper } 7278ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->CanBreakBefore = 7288ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->MustBreakBefore || canBreakBefore(Line, *Current); 7298ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper if (Current->MustBreakBefore) 7308ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->TotalLength = Current->Parent->TotalLength + Style.ColumnLimit; 7318ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper else 7328ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->TotalLength = 7338ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->Parent->TotalLength + Current->FormatTok.TokenLength + 7348ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper (Current->SpaceRequiredBefore ? 1 : 0); 7358ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper // FIXME: Only calculate this if CanBreakBefore is true once static 7368ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper // initializers etc. are sorted out. 7378ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper // FIXME: Move magic numbers to a better place. 7388ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->SplitPenalty = 7398ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper 20 * Current->BindingStrength + splitPenalty(Line, *Current); 7408ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper 7418ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current = Current->Children.empty() ? NULL : &Current->Children[0]; 74232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 74332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} 74432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 7458ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasperunsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line, 7468ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper const AnnotatedToken &Tok) { 74732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper const AnnotatedToken &Left = *Tok.Parent; 74832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper const AnnotatedToken &Right = Tok; 74932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 75032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::l_brace) && Right.isNot(tok::l_brace)) 75132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return 50; 75232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::equal) && Right.is(tok::l_brace)) 75332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return 150; 75432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::coloncolon)) 75532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return 500; 75632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 75732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.Type == TT_RangeBasedForLoopColon) 75832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return 5; 75932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 76032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::arrow) || Right.is(tok::period)) { 76132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::r_paren) && Line.Type == LT_BuilderTypeCall) 76232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return 5; // Should be smaller than breaking at a nested comma. 76332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return 150; 76432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 76532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 76632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // In for-loops, prefer breaking at ',' and ';'. 76732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Line.First.is(tok::kw_for) && 76832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper (Left.isNot(tok::comma) && Left.isNot(tok::semi))) 76932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return 20; 77032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 7718159d2f271c9142b46a672ac2c45821911171a7dDaniel Jasper if (Left.is(tok::semi)) 77232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return 0; 7738159d2f271c9142b46a672ac2c45821911171a7dDaniel Jasper if (Left.is(tok::comma)) 7748159d2f271c9142b46a672ac2c45821911171a7dDaniel Jasper return 1; 77532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 77632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // In Objective-C method expressions, prefer breaking before "param:" over 77732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // breaking after it. 77863d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper if (Right.Type == TT_ObjCSelectorName) 77932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return 0; 78063d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper if (Left.is(tok::colon) && Left.Type == TT_ObjCMethodExpr) 78132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return 20; 78232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 7830178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (Left.is(tok::l_paren) || Left.is(tok::l_square) || 7840178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Left.Type == TT_TemplateOpener) 78532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return 20; 78632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 7870178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (Right.is(tok::lessless)) 7880178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return prec::Shift; 78932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.Type == TT_ConditionalExpr) 79032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return prec::Assignment; 79132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper prec::Level Level = getPrecedence(Left); 79232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 79332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Level != prec::Unknown) 79432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return Level; 79532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 79632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return 3; 79732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} 79832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 7998ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasperbool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, 8008ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper const AnnotatedToken &Left, 80132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper const AnnotatedToken &Right) { 80232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::hashhash)) 80332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return Left.is(tok::hash); 80432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::hashhash) || Left.is(tok::hash)) 80532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return Right.is(tok::hash); 80632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::r_paren) || Right.is(tok::semi) || Right.is(tok::comma)) 80732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 80832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::less) && 80932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper (Left.is(tok::kw_template) || 81032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper (Line.Type == LT_ObjCDecl && Style.ObjCSpaceBeforeProtocolList))) 81132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 81232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::arrow) || Right.is(tok::arrow)) 81332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 81432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::exclaim) || Left.is(tok::tilde)) 81532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 81632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::at) && 81732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper (Right.is(tok::identifier) || Right.is(tok::string_literal) || 81832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Right.is(tok::char_constant) || Right.is(tok::numeric_constant) || 81932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Right.is(tok::l_paren) || Right.is(tok::l_brace) || 82032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Right.is(tok::kw_true) || Right.is(tok::kw_false))) 82132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 82232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::coloncolon)) 82332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 82432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::coloncolon)) 82532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return Left.isNot(tok::identifier) && Left.isNot(tok::greater); 82632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::less) || Right.is(tok::greater) || Right.is(tok::less)) 82732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 82832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::amp) || Right.is(tok::star)) 82932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return Left.FormatTok.Tok.isLiteral() || 83032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper (Left.isNot(tok::star) && Left.isNot(tok::amp) && 8318ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper !Style.PointerBindsToType); 83232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::amp) || Left.is(tok::star)) 83332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return Right.FormatTok.Tok.isLiteral() || 8348ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Style.PointerBindsToType; 83532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::star) && Left.is(tok::l_paren)) 83632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 83732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::l_square) || Right.is(tok::r_square)) 83832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 83932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::l_square) && Right.Type != TT_ObjCMethodExpr) 84032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 84132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::period) || Right.is(tok::period)) 84232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 84332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::colon)) 84432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return Left.Type != TT_ObjCMethodExpr; 84532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::colon)) 84632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return Right.Type != TT_ObjCMethodExpr; 84732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::l_paren)) 84832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 84932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::l_paren)) { 85032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return Line.Type == LT_ObjCDecl || Left.is(tok::kw_if) || 85132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left.is(tok::kw_for) || Left.is(tok::kw_while) || 85232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left.is(tok::kw_switch) || Left.is(tok::kw_return) || 85332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left.is(tok::kw_catch) || Left.is(tok::kw_new) || 85432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left.is(tok::kw_delete); 85532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 85632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::at) && 85732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Right.FormatTok.Tok.getObjCKeywordID() != tok::objc_not_keyword) 85832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 85932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::l_brace) && Right.is(tok::r_brace)) 86032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 86132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 86232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} 86332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 8648ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasperbool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, 8658ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper const AnnotatedToken &Tok) { 86632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Line.Type == LT_ObjCMethodDecl) { 86732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.is(tok::identifier) && !Tok.Children.empty() && 86832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Tok.Children[0].is(tok::colon) && Tok.Parent->is(tok::identifier)) 86932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 87032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.is(tok::colon)) 87132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 87232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.Parent->Type == TT_ObjCMethodSpecifier) 87332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 87432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.Parent->is(tok::r_paren) && Tok.is(tok::identifier)) 87532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // Don't space between ')' and <id> 87632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 87732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.Parent->is(tok::colon) && Tok.is(tok::l_paren)) 87832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // Don't space between ':' and '(' 87932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 88032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 88132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Line.Type == LT_ObjCProperty && 88232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper (Tok.is(tok::equal) || Tok.Parent->is(tok::equal))) 88332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 88432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 88532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.Parent->is(tok::comma)) 88632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 88732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.Type == TT_CtorInitializerColon || Tok.Type == TT_ObjCBlockLParen) 88832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 88932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.Type == TT_OverloadedOperator) 89032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return Tok.is(tok::identifier) || Tok.is(tok::kw_new) || 89132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Tok.is(tok::kw_delete) || Tok.is(tok::kw_bool); 89232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.Parent->Type == TT_OverloadedOperator) 89332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 89432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.is(tok::colon)) 89532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return Line.First.isNot(tok::kw_case) && !Tok.Children.empty() && 89632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Tok.Type != TT_ObjCMethodExpr; 89732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.Parent->Type == TT_UnaryOperator || Tok.Parent->Type == TT_CastRParen) 89832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 89932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.Type == TT_UnaryOperator) 90032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return Tok.Parent->isNot(tok::l_paren) && 90132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Tok.Parent->isNot(tok::l_square) && Tok.Parent->isNot(tok::at) && 90232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper (Tok.Parent->isNot(tok::colon) || 90332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Tok.Parent->Type != TT_ObjCMethodExpr); 90432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.Parent->is(tok::greater) && Tok.is(tok::greater)) { 90532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return Tok.Type == TT_TemplateCloser && Tok.Parent->Type == 9068ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper TT_TemplateCloser && Style.Standard != FormatStyle::LS_Cpp11; 90732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 90832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.Type == TT_BinaryOperator || Tok.Parent->Type == TT_BinaryOperator) 90932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 91032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.Parent->Type == TT_TemplateCloser && Tok.is(tok::l_paren)) 91132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 91232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.is(tok::less) && Line.First.is(tok::hash)) 91332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 91432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.Type == TT_TrailingUnaryOperator) 91532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 9168ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper return spaceRequiredBetween(Line, *Tok.Parent, Tok); 91732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} 91832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 9198ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasperbool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, 9208ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper const AnnotatedToken &Right) { 92132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper const AnnotatedToken &Left = *Right.Parent; 92232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Line.Type == LT_ObjCMethodDecl) { 92332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::identifier) && !Right.Children.empty() && 92432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Right.Children[0].is(tok::colon) && Left.is(tok::identifier)) 92532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 92632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::identifier) && Left.is(tok::l_paren) && 92732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left.Parent->is(tok::colon)) 92832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // Don't break this identifier as ':' or identifier 92932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // before it will break. 93032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 93132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::colon) && Left.is(tok::identifier) && Left.CanBreakBefore) 93232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // Don't break at ':' if identifier before it can beak. 93332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 93432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 93532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.Type == TT_StartOfName && Style.AllowReturnTypeOnItsOwnLine) 93632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 93732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::colon) && Right.Type == TT_ObjCMethodExpr) 93832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 93932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::colon) && Left.Type == TT_ObjCMethodExpr) 94032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 94163d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper if (Right.Type == TT_ObjCSelectorName) 94232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 94332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.ClosesTemplateDeclaration) 94432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 94532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.Type == TT_ConditionalExpr || Right.is(tok::question)) 94632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 94732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.Type == TT_RangeBasedForLoopColon) 94832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 94932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.Type == TT_PointerOrReference || Left.Type == TT_TemplateCloser || 95032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left.Type == TT_UnaryOperator || Left.Type == TT_ConditionalExpr || 95132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left.is(tok::question)) 95232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 95332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::equal) && Line.Type == LT_VirtualFunctionDecl) 95432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 95532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 95632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.Type == TT_LineComment) 95732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // We rely on MustBreakBefore being set correctly here as we should not 95832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // change the "binding" behavior of a comment. 95932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 96032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 96132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // Allow breaking after a trailing 'const', e.g. after a method declaration, 96232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // unless it is follow by ';', '{' or '='. 96332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::kw_const) && Left.Parent != NULL && 96432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left.Parent->is(tok::r_paren)) 96532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return Right.isNot(tok::l_brace) && Right.isNot(tok::semi) && 96632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Right.isNot(tok::equal); 96732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 96832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // We only break before r_brace if there was a corresponding break before 96932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // the l_brace, which is tracked by BreakBeforeClosingBrace. 97032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::r_brace)) 97132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 97232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 97332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::r_paren) || Right.is(tok::greater)) 97432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 97532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return (isBinaryOperator(Left) && Left.isNot(tok::lessless)) || 97632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left.is(tok::comma) || Right.is(tok::lessless) || 97732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Right.is(tok::arrow) || Right.is(tok::period) || 97832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Right.is(tok::colon) || Left.is(tok::coloncolon) || 97932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left.is(tok::semi) || Left.is(tok::l_brace) || 98032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper (Left.is(tok::r_paren) && Left.Type != TT_CastRParen && 98132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Right.is(tok::identifier)) || 98232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper (Left.is(tok::l_paren) && !Right.is(tok::r_paren)) || 98332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper (Left.is(tok::l_square) && !Right.is(tok::r_square)); 98432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} 98532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 98632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} // namespace format 98732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} // namespace clang 988