TokenAnnotator.cpp revision 3a204418482c9ae70ad482e781132c54306c3aa6
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 5529f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasperstatic bool isTrailingComment(AnnotatedToken *Tok) { 5629f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper return Tok != NULL && Tok->is(tok::comment) && 5729f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper (Tok->Children.empty() || 5829f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper Tok->Children[0].FormatTok.NewlinesBefore > 0); 5929f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper} 6029f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 610178673f541685cf5067814dfeee2644078e39a9Daniel Jasper// Returns the next token ignoring comments. 620178673f541685cf5067814dfeee2644078e39a9Daniel Jasperstatic const AnnotatedToken *getNextToken(const AnnotatedToken &Tok) { 630178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (Tok.Children.empty()) 640178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return NULL; 650178673f541685cf5067814dfeee2644078e39a9Daniel Jasper const AnnotatedToken *NextToken = &Tok.Children[0]; 660178673f541685cf5067814dfeee2644078e39a9Daniel Jasper while (NextToken->is(tok::comment)) { 670178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (NextToken->Children.empty()) 680178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return NULL; 690178673f541685cf5067814dfeee2644078e39a9Daniel Jasper NextToken = &NextToken->Children[0]; 700178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 710178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return NextToken; 720178673f541685cf5067814dfeee2644078e39a9Daniel Jasper} 730178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 7432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper/// \brief A parser that gathers additional information about tokens. 7532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper/// 7632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper/// The \c TokenAnnotator tries to matches 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), 84c2e6d2a4a7fe9dfa7d52a38c6048b7b18e6b591aNico Weber KeywordVirtualFound(false), Ident_in(Ident_in) { 854e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.push_back(Context(1, /*IsExpression=*/ false)); 864e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().LookForFunctionName = Line.MustBeDeclaration; 8732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 8832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 8995e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weberprivate: 9032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool parseAngle() { 9132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken == NULL) 9232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 934e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper ScopedContextCreator ContextCreator(*this, 10); 9432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper AnnotatedToken *Left = CurrentToken->Parent; 954e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().IsExpression = false; 9632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper while (CurrentToken != NULL) { 9732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::greater)) { 9832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left->MatchingParen = CurrentToken; 9932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->MatchingParen = Left; 10032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->Type = TT_TemplateCloser; 10132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 10232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 10332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 10432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::r_paren) || CurrentToken->is(tok::r_square) || 10532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->is(tok::r_brace)) 10632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 10732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::pipepipe) || CurrentToken->is(tok::ampamp) || 10832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->is(tok::question) || CurrentToken->is(tok::colon)) 10932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 1109fc56f2636137fcde8acb38865555ed6c7b84dfdDaniel Jasper updateParameterCount(Left, CurrentToken); 11132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!consumeToken()) 11232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 11332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 11432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 11532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 11632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 11732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool parseParens(bool LookForDecls = false) { 11832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken == NULL) 11932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 1204e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper ScopedContextCreator ContextCreator(*this, 1); 1214e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper 1224e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper // FIXME: This is a bit of a hack. Do better. 1234e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().ColonIsForRangeExpr = 1244e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.size() == 2 && Contexts[0].ColonIsForRangeExpr; 1254e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper 12632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool StartsObjCMethodExpr = false; 12732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper AnnotatedToken *Left = CurrentToken->Parent; 12832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::caret)) { 12932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // ^( starts a block. 13032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left->Type = TT_ObjCBlockLParen; 13132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } else if (AnnotatedToken *MaybeSel = Left->Parent) { 13232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // @selector( starts a selector. 13332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (MaybeSel->isObjCAtKeyword(tok::objc_selector) && MaybeSel->Parent && 13432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper MaybeSel->Parent->is(tok::at)) { 13532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper StartsObjCMethodExpr = true; 13632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 13732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 13832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 1394e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper if (StartsObjCMethodExpr) { 1404e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().ColonIsObjCMethodExpr = true; 1414e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Left->Type = TT_ObjCMethodExpr; 1424e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper } 14332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 14432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper while (CurrentToken != NULL) { 14532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // LookForDecls is set when "if (" has been seen. Check for 14632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // 'identifier' '*' 'identifier' followed by not '=' -- this 14732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // '*' has to be a binary operator but determineStarAmpUsage() will 14832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // categorize it as an unary operator, so set the right type here. 14932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (LookForDecls && !CurrentToken->Children.empty()) { 15032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper AnnotatedToken &Prev = *CurrentToken->Parent; 15132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper AnnotatedToken &Next = CurrentToken->Children[0]; 15232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Prev.Parent->is(tok::identifier) && 15332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper (Prev.is(tok::star) || Prev.is(tok::amp)) && 15432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->is(tok::identifier) && Next.isNot(tok::equal)) { 15532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Prev.Type = TT_BinaryOperator; 15632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper LookForDecls = false; 15732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 15832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 15932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 16032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::r_paren)) { 16132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left->MatchingParen = CurrentToken; 16232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->MatchingParen = Left; 16332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 16463d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper if (StartsObjCMethodExpr) { 1654e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper CurrentToken->Type = TT_ObjCMethodExpr; 1664e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper if (Contexts.back().FirstObjCSelectorName != NULL) { 1674e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 1684e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().LongestObjCSelectorName; 16963d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper } 17063d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper } 17132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 17232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 17332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 17432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 17532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::r_square) || CurrentToken->is(tok::r_brace)) 17632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 1779fc56f2636137fcde8acb38865555ed6c7b84dfdDaniel Jasper updateParameterCount(Left, CurrentToken); 17832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!consumeToken()) 17932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 18032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 18132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 18232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 18332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 18432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool parseSquare() { 18532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!CurrentToken) 18632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 1874e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper ScopedContextCreator ContextCreator(*this, 10); 18832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 18932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // A '[' could be an index subscript (after an indentifier or after 190051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber // ')' or ']'), it could be the start of an Objective-C method 191051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber // expression, or it could the the start of an Objective-C array literal. 19232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper AnnotatedToken *Left = CurrentToken->Parent; 1934ed7f3e003c906d9fdb92a9484feeb8ac6e28e2fNico Weber AnnotatedToken *Parent = getPreviousToken(*Left); 19432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool StartsObjCMethodExpr = 1954ed7f3e003c906d9fdb92a9484feeb8ac6e28e2fNico Weber !Parent || Parent->is(tok::colon) || Parent->is(tok::l_square) || 1964ed7f3e003c906d9fdb92a9484feeb8ac6e28e2fNico Weber Parent->is(tok::l_paren) || Parent->is(tok::kw_return) || 1974ed7f3e003c906d9fdb92a9484feeb8ac6e28e2fNico Weber Parent->is(tok::kw_throw) || isUnaryOperator(*Parent) || 1984c2cc603f5239f3b2963ce3e5d25adcf4d0a028dNico Weber Parent->Type == TT_ObjCForIn || Parent->Type == TT_CastRParen || 1994ed7f3e003c906d9fdb92a9484feeb8ac6e28e2fNico Weber getBinOpPrecedence(Parent->FormatTok.Tok.getKind(), true, true) > 20032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper prec::Unknown; 201051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber bool StartsObjCArrayLiteral = Parent && Parent->is(tok::at); 20232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 2034e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper if (StartsObjCMethodExpr) { 2044e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().ColonIsObjCMethodExpr = true; 2054e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Left->Type = TT_ObjCMethodExpr; 206051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber } else if (StartsObjCArrayLiteral) { 207051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber Left->Type = TT_ObjCArrayLiteral; 2084e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper } 20932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 21032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper while (CurrentToken != NULL) { 21132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::r_square)) { 21232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!CurrentToken->Children.empty() && 21332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->Children[0].is(tok::l_paren)) { 214e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber // An ObjC method call is rarely followed by an open parenthesis. 21532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // FIXME: Do we incorrectly label ":" with this? 21632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper StartsObjCMethodExpr = false; 21732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left->Type = TT_Unknown; 21832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 2190178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (StartsObjCMethodExpr) { 2204e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper CurrentToken->Type = TT_ObjCMethodExpr; 221e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber // determineStarAmpUsage() thinks that '*' '[' is allocating an 222e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber // array of pointers, but if '[' starts a selector then '*' is a 223e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber // binary operator. 2244ed7f3e003c906d9fdb92a9484feeb8ac6e28e2fNico Weber if (Parent != NULL && 2254ed7f3e003c906d9fdb92a9484feeb8ac6e28e2fNico Weber (Parent->is(tok::star) || Parent->is(tok::amp)) && 2264ed7f3e003c906d9fdb92a9484feeb8ac6e28e2fNico Weber Parent->Type == TT_PointerOrReference) 2274ed7f3e003c906d9fdb92a9484feeb8ac6e28e2fNico Weber Parent->Type = TT_BinaryOperator; 228051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber } else if (StartsObjCArrayLiteral) { 229051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber CurrentToken->Type = TT_ObjCArrayLiteral; 2300178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 23132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left->MatchingParen = CurrentToken; 23232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->MatchingParen = Left; 2334e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper if (Contexts.back().FirstObjCSelectorName != NULL) 2344e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 2354e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().LongestObjCSelectorName; 23632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 23732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 23832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 23932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::r_paren) || CurrentToken->is(tok::r_brace)) 24032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 2419fc56f2636137fcde8acb38865555ed6c7b84dfdDaniel Jasper updateParameterCount(Left, CurrentToken); 24232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!consumeToken()) 24332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 24432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 24532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 24632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 24732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 24832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool parseBrace() { 24932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // Lines are fine to end with '{'. 25032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken == NULL) 25132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 2524e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper ScopedContextCreator ContextCreator(*this, 1); 25332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper AnnotatedToken *Left = CurrentToken->Parent; 25432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper while (CurrentToken != NULL) { 25532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::r_brace)) { 25632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left->MatchingParen = CurrentToken; 25732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->MatchingParen = Left; 25832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 25932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 26032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 26132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::r_paren) || CurrentToken->is(tok::r_square)) 26232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 2639fc56f2636137fcde8acb38865555ed6c7b84dfdDaniel Jasper updateParameterCount(Left, CurrentToken); 26432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!consumeToken()) 26532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 26632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 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: 30932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // At the start of the line, +/- specific ObjectiveC method 31032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // declarations. 31132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok->Parent == NULL) 31232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Tok->Type = TT_ObjCMethodSpecifier; 31332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 31432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::colon: 31532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // Colons from ?: are handled in parseConditional(). 31663d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper if (Tok->Parent->is(tok::r_paren)) { 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 > 3234e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel 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; 33263d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper } 33332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 33432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::kw_if: 33532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::kw_while: 33632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken != NULL && CurrentToken->is(tok::l_paren)) { 33732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 33832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!parseParens(/*LookForDecls=*/ true)) 33932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 34032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 34132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 34232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::kw_for: 3434e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().ColonIsForRangeExpr = true; 34432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 34532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!parseParens()) 34632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 34732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 34832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::l_paren: 34932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!parseParens()) 35032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 35132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 35232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::l_square: 35332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!parseSquare()) 35432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 35532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 35632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::l_brace: 35732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!parseBrace()) 35832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 35932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 36032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::less: 36132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (parseAngle()) 36232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Tok->Type = TT_TemplateOpener; 36332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper else { 36432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Tok->Type = TT_BinaryOperator; 36532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken = Tok; 36632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 36732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 36832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 36932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::r_paren: 37032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::r_square: 37132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 37232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::r_brace: 37332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // Lines can start with '}'. 37432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok->Parent != NULL) 37532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 37632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 37732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::greater: 37832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Tok->Type = TT_BinaryOperator; 37932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 38032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::kw_operator: 3812b4c924f85e156d66c01b3f16c850892c47dcc7aDaniel Jasper while (CurrentToken && CurrentToken->isNot(tok::l_paren)) { 3822b4c924f85e156d66c01b3f16c850892c47dcc7aDaniel Jasper if (CurrentToken->is(tok::star) || CurrentToken->is(tok::amp)) 3832b4c924f85e156d66c01b3f16c850892c47dcc7aDaniel Jasper CurrentToken->Type = TT_PointerOrReference; 3842b4c924f85e156d66c01b3f16c850892c47dcc7aDaniel Jasper consumeToken(); 38532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 3862b4c924f85e156d66c01b3f16c850892c47dcc7aDaniel Jasper if (CurrentToken) 3872b4c924f85e156d66c01b3f16c850892c47dcc7aDaniel Jasper CurrentToken->Type = TT_OverloadedOperatorLParen; 38832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 38932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::question: 39032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper parseConditional(); 39132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 39232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::kw_template: 39332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper parseTemplateDeclaration(); 39432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 395c2e6d2a4a7fe9dfa7d52a38c6048b7b18e6b591aNico Weber case tok::identifier: 396c2e6d2a4a7fe9dfa7d52a38c6048b7b18e6b591aNico Weber if (Line.First.is(tok::kw_for) && 397c2e6d2a4a7fe9dfa7d52a38c6048b7b18e6b591aNico Weber Tok->FormatTok.Tok.getIdentifierInfo() == &Ident_in) 398c2e6d2a4a7fe9dfa7d52a38c6048b7b18e6b591aNico Weber Tok->Type = TT_ObjCForIn; 399c2e6d2a4a7fe9dfa7d52a38c6048b7b18e6b591aNico Weber break; 40032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper default: 40132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 40232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 40332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 40432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 40532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 40632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper void parseIncludeDirective() { 40732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 40832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken != NULL && CurrentToken->is(tok::less)) { 40932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 41032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper while (CurrentToken != NULL) { 41132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->isNot(tok::comment) || 41232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper !CurrentToken->Children.empty()) 41332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->Type = TT_ImplicitStringLiteral; 41432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 41532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 41632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } else { 41732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper while (CurrentToken != NULL) { 4183a204418482c9ae70ad482e781132c54306c3aa6Daniel Jasper if (CurrentToken->is(tok::string_literal)) 4193a204418482c9ae70ad482e781132c54306c3aa6Daniel Jasper // Mark these string literals as "implicit" literals, too, so that 4203a204418482c9ae70ad482e781132c54306c3aa6Daniel Jasper // they are not split or line-wrapped. 4213a204418482c9ae70ad482e781132c54306c3aa6Daniel Jasper CurrentToken->Type = TT_ImplicitStringLiteral; 42232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 42332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 42432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 42532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 42632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 42732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper void parseWarningOrError() { 42832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 42932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // We still want to format the whitespace left of the first token of the 43032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // warning or error. 43132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 43232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper while (CurrentToken != NULL) { 43332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken->Type = TT_ImplicitStringLiteral; 43432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 43532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 43632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 43732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 43832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper void parsePreprocessorDirective() { 43932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper next(); 44032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken == NULL) 44132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return; 44232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // Hashes in the middle of a line can lead to any strange token 44332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // sequence. 44432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->FormatTok.Tok.getIdentifierInfo() == NULL) 44532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return; 44632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper switch (CurrentToken->FormatTok.Tok.getIdentifierInfo()->getPPKeywordID()) { 44732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::pp_include: 44832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::pp_import: 44932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper parseIncludeDirective(); 45032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 45132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::pp_error: 45232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper case tok::pp_warning: 45332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper parseWarningOrError(); 45432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 45532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper default: 45632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper break; 45732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 4585b7e7b0ec77f49c1b24deffc9b7032ca16ca9f0dDaniel Jasper while (CurrentToken != NULL) 4595b7e7b0ec77f49c1b24deffc9b7032ca16ca9f0dDaniel Jasper next(); 46032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 46132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 46295e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weberpublic: 46332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper LineType parseLine() { 46432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper int PeriodsAndArrows = 0; 46532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool CanBeBuilderTypeStmt = true; 46632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::hash)) { 46732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper parsePreprocessorDirective(); 46832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return LT_PreprocessorDirective; 46932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 47032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper while (CurrentToken != NULL) { 47132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::kw_virtual)) 47232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper KeywordVirtualFound = true; 47332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken->is(tok::period) || CurrentToken->is(tok::arrow)) 47432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper ++PeriodsAndArrows; 4754a544e5856ceadef1c095c7d1ae5c8d760851d59Daniel Jasper AnnotatedToken *TheToken = CurrentToken; 47632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (!consumeToken()) 47732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return LT_Invalid; 4784a544e5856ceadef1c095c7d1ae5c8d760851d59Daniel Jasper if (getPrecedence(*TheToken) > prec::Assignment && 47982282dc907a04b1931f8f578693b035ad751fd3bDaniel Jasper TheToken->Type == TT_BinaryOperator) 4804a544e5856ceadef1c095c7d1ae5c8d760851d59Daniel Jasper CanBeBuilderTypeStmt = false; 48132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 48232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (KeywordVirtualFound) 48332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return LT_VirtualFunctionDecl; 48432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 48532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // Assume a builder-type call if there are 2 or more "." and "->". 48632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (PeriodsAndArrows >= 2 && CanBeBuilderTypeStmt) 48732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return LT_BuilderTypeCall; 48832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 48963d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper if (Line.First.Type == TT_ObjCMethodSpecifier) { 4904e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper if (Contexts.back().FirstObjCSelectorName != NULL) 4914e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 4924e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().LongestObjCSelectorName; 49363d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper return LT_ObjCMethodDecl; 49463d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper } 49563d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper 49632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return LT_Other; 49732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 49832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 49995e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weberprivate: 50032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper void next() { 5010178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (CurrentToken != NULL) { 5020178673f541685cf5067814dfeee2644078e39a9Daniel Jasper determineTokenType(*CurrentToken); 5034e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper CurrentToken->BindingStrength = Contexts.back().BindingStrength; 5040178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 5050178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 50632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (CurrentToken != NULL && !CurrentToken->Children.empty()) 50732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken = &CurrentToken->Children[0]; 50832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper else 50932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper CurrentToken = NULL; 510d0f349be1422a123fdb28d6dd556f7300e6d51e9Daniel Jasper 511d0f349be1422a123fdb28d6dd556f7300e6d51e9Daniel Jasper // Reset token type in case we have already looked at it and then recovered 512d0f349be1422a123fdb28d6dd556f7300e6d51e9Daniel Jasper // from an error (e.g. failure to find the matching >). 513d0f349be1422a123fdb28d6dd556f7300e6d51e9Daniel Jasper if (CurrentToken != NULL) 514d0f349be1422a123fdb28d6dd556f7300e6d51e9Daniel Jasper CurrentToken->Type = TT_Unknown; 51532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 51632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 5174e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper /// \brief A struct to hold information valid in a specific context, e.g. 5184e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper /// a pair of parenthesis. 5194e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper struct Context { 5204e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Context(unsigned BindingStrength, bool IsExpression) 5214e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper : BindingStrength(BindingStrength), LongestObjCSelectorName(0), 5224e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper ColonIsForRangeExpr(false), ColonIsObjCMethodExpr(false), 5234e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper FirstObjCSelectorName(NULL), IsExpression(IsExpression), 524f11a705c6075b12cbae5632ba4de433bc9bc105fDaniel Jasper LookForFunctionName(false) {} 5250178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 5264e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper unsigned BindingStrength; 5274e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper unsigned LongestObjCSelectorName; 5284e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper bool ColonIsForRangeExpr; 5294e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper bool ColonIsObjCMethodExpr; 5304e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper AnnotatedToken *FirstObjCSelectorName; 5314e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper bool IsExpression; 5324e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper bool LookForFunctionName; 5334e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper }; 5344e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper 5354e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper /// \brief Puts a new \c Context onto the stack \c Contexts for the lifetime 5364e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper /// of each instance. 5374e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper struct ScopedContextCreator { 5384e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper AnnotatingParser &P; 5394e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper 540fc75908a7f58903a92c47e1ae02f9a05c36c9f59Daniel Jasper ScopedContextCreator(AnnotatingParser &P, unsigned Increase) : P(P) { 541fc75908a7f58903a92c47e1ae02f9a05c36c9f59Daniel Jasper P.Contexts.push_back(Context(P.Contexts.back().BindingStrength + Increase, 542fc75908a7f58903a92c47e1ae02f9a05c36c9f59Daniel Jasper P.Contexts.back().IsExpression)); 5434e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper } 5444e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper 5454e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper ~ScopedContextCreator() { P.Contexts.pop_back(); } 5464e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper }; 5470178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 5480178673f541685cf5067814dfeee2644078e39a9Daniel Jasper void determineTokenType(AnnotatedToken &Current) { 5490178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (getPrecedence(Current) == prec::Assignment) { 5504e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().IsExpression = true; 55195e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weber for (AnnotatedToken *Previous = Current.Parent; 55295e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weber Previous && Previous->isNot(tok::comma); 55395e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weber Previous = Previous->Parent) { 5540178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (Previous->Type == TT_BinaryOperator && 5550178673f541685cf5067814dfeee2644078e39a9Daniel Jasper (Previous->is(tok::star) || Previous->is(tok::amp))) { 5560178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Previous->Type = TT_PointerOrReference; 5570178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 5580178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 55995e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weber } else if (Current.is(tok::kw_return) || Current.is(tok::kw_throw) || 56095e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weber (Current.is(tok::l_paren) && !Line.MustBeDeclaration && 56195e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weber (!Current.Parent || Current.Parent->isNot(tok::kw_for)))) { 5624e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().IsExpression = true; 56395e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weber } else if (Current.is(tok::r_paren) || Current.is(tok::greater) || 56495e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weber Current.is(tok::comma)) { 56595e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weber for (AnnotatedToken *Previous = Current.Parent; 56695e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weber Previous && (Previous->is(tok::star) || Previous->is(tok::amp)); 56795e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weber Previous = Previous->Parent) 56895e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weber Previous->Type = TT_PointerOrReference; 569d0f349be1422a123fdb28d6dd556f7300e6d51e9Daniel Jasper } else if (Current.Parent && 570d0f349be1422a123fdb28d6dd556f7300e6d51e9Daniel Jasper Current.Parent->Type == TT_CtorInitializerColon) { 571d0f349be1422a123fdb28d6dd556f7300e6d51e9Daniel Jasper Contexts.back().IsExpression = true; 57295e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weber } 5730178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 5740178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (Current.Type == TT_Unknown) { 5754e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper if (Contexts.back().LookForFunctionName && Current.is(tok::l_paren)) { 5760178673f541685cf5067814dfeee2644078e39a9Daniel Jasper findFunctionName(&Current); 5774e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Contexts.back().LookForFunctionName = false; 5780178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } else if (Current.is(tok::star) || Current.is(tok::amp)) { 5794e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Current.Type = 5804e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper determineStarAmpUsage(Current, Contexts.back().IsExpression); 5810178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } else if (Current.is(tok::minus) || Current.is(tok::plus) || 5820178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.is(tok::caret)) { 5830178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.Type = determinePlusMinusCaretUsage(Current); 5840178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } else if (Current.is(tok::minusminus) || Current.is(tok::plusplus)) { 5850178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.Type = determineIncrementUsage(Current); 5860178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } else if (Current.is(tok::exclaim)) { 5870178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.Type = TT_UnaryOperator; 5880178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } else if (isBinaryOperator(Current)) { 5890178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.Type = TT_BinaryOperator; 5900178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } else if (Current.is(tok::comment)) { 5910178673f541685cf5067814dfeee2644078e39a9Daniel Jasper std::string Data(Lexer::getSpelling(Current.FormatTok.Tok, SourceMgr, 5920178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Lex.getLangOpts())); 5930178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (StringRef(Data).startswith("//")) 5940178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.Type = TT_LineComment; 5950178673f541685cf5067814dfeee2644078e39a9Daniel Jasper else 5960178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.Type = TT_BlockComment; 59737d693160eba22343e08d7bcf66cd132ace77e5cNico Weber } else if (Current.is(tok::r_paren)) { 59803628b86a9c50e066412fb0e49908686ff117378Daniel Jasper bool ParensNotExpr = !Current.Parent || 59903628b86a9c50e066412fb0e49908686ff117378Daniel Jasper Current.Parent->Type == TT_PointerOrReference || 60037d693160eba22343e08d7bcf66cd132ace77e5cNico Weber Current.Parent->Type == TT_TemplateCloser; 60137d693160eba22343e08d7bcf66cd132ace77e5cNico Weber bool ParensCouldEndDecl = 60237d693160eba22343e08d7bcf66cd132ace77e5cNico Weber !Current.Children.empty() && (Current.Children[0].is(tok::equal) || 60337d693160eba22343e08d7bcf66cd132ace77e5cNico Weber Current.Children[0].is(tok::semi) || 60437d693160eba22343e08d7bcf66cd132ace77e5cNico Weber Current.Children[0].is(tok::l_brace)); 60537d693160eba22343e08d7bcf66cd132ace77e5cNico Weber if (ParensNotExpr && !ParensCouldEndDecl) 60637d693160eba22343e08d7bcf66cd132ace77e5cNico Weber // FIXME: We need to get smarter and understand more cases of casts. 60737d693160eba22343e08d7bcf66cd132ace77e5cNico Weber Current.Type = TT_CastRParen; 6080178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } else if (Current.is(tok::at) && Current.Children.size()) { 6090178673f541685cf5067814dfeee2644078e39a9Daniel Jasper switch (Current.Children[0].FormatTok.Tok.getObjCKeywordID()) { 6100178673f541685cf5067814dfeee2644078e39a9Daniel Jasper case tok::objc_interface: 6110178673f541685cf5067814dfeee2644078e39a9Daniel Jasper case tok::objc_implementation: 6120178673f541685cf5067814dfeee2644078e39a9Daniel Jasper case tok::objc_protocol: 6130178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.Type = TT_ObjCDecl; 6140178673f541685cf5067814dfeee2644078e39a9Daniel Jasper break; 6150178673f541685cf5067814dfeee2644078e39a9Daniel Jasper case tok::objc_property: 6160178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Current.Type = TT_ObjCProperty; 6170178673f541685cf5067814dfeee2644078e39a9Daniel Jasper break; 6180178673f541685cf5067814dfeee2644078e39a9Daniel Jasper default: 6190178673f541685cf5067814dfeee2644078e39a9Daniel Jasper break; 6200178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 6210178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 6220178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 6230178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 6240178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 6250178673f541685cf5067814dfeee2644078e39a9Daniel Jasper /// \brief Starting from \p Current, this searches backwards for an 6260178673f541685cf5067814dfeee2644078e39a9Daniel Jasper /// identifier which could be the start of a function name and marks it. 6270178673f541685cf5067814dfeee2644078e39a9Daniel Jasper void findFunctionName(AnnotatedToken *Current) { 6280178673f541685cf5067814dfeee2644078e39a9Daniel Jasper AnnotatedToken *Parent = Current->Parent; 6290178673f541685cf5067814dfeee2644078e39a9Daniel Jasper while (Parent != NULL && Parent->Parent != NULL) { 6300178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (Parent->is(tok::identifier) && 6310178673f541685cf5067814dfeee2644078e39a9Daniel Jasper (Parent->Parent->is(tok::identifier) || 6320178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Parent->Parent->Type == TT_PointerOrReference || 6330178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Parent->Parent->Type == TT_TemplateCloser)) { 6340178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Parent->Type = TT_StartOfName; 6350178673f541685cf5067814dfeee2644078e39a9Daniel Jasper break; 6360178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 6370178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Parent = Parent->Parent; 6380178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 6390178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 6400178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 6410178673f541685cf5067814dfeee2644078e39a9Daniel Jasper /// \brief Return the type of the given token assuming it is * or &. 6420178673f541685cf5067814dfeee2644078e39a9Daniel Jasper TokenType 6430178673f541685cf5067814dfeee2644078e39a9Daniel Jasper determineStarAmpUsage(const AnnotatedToken &Tok, bool IsExpression) { 6440178673f541685cf5067814dfeee2644078e39a9Daniel Jasper const AnnotatedToken *PrevToken = getPreviousToken(Tok); 6450178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (PrevToken == NULL) 6460178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_UnaryOperator; 6470178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 6480178673f541685cf5067814dfeee2644078e39a9Daniel Jasper const AnnotatedToken *NextToken = getNextToken(Tok); 6490178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (NextToken == NULL) 6500178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_Unknown; 6510178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 6520178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (PrevToken->is(tok::l_paren) || PrevToken->is(tok::l_square) || 6530178673f541685cf5067814dfeee2644078e39a9Daniel Jasper PrevToken->is(tok::l_brace) || PrevToken->is(tok::comma) || 6540178673f541685cf5067814dfeee2644078e39a9Daniel Jasper PrevToken->is(tok::kw_return) || PrevToken->is(tok::colon) || 655e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber PrevToken->is(tok::equal) || PrevToken->Type == TT_BinaryOperator || 6560178673f541685cf5067814dfeee2644078e39a9Daniel Jasper PrevToken->Type == TT_UnaryOperator || PrevToken->Type == TT_CastRParen) 6570178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_UnaryOperator; 6580178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 659e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber if (NextToken->is(tok::l_square)) 660e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber return TT_PointerOrReference; 661e8a97985f72b4e11435ff2107c0f11e925fb6d96Nico Weber 6620178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (PrevToken->FormatTok.Tok.isLiteral() || PrevToken->is(tok::r_paren) || 6630178673f541685cf5067814dfeee2644078e39a9Daniel Jasper PrevToken->is(tok::r_square) || NextToken->FormatTok.Tok.isLiteral() || 664ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber isUnaryOperator(*NextToken) || NextToken->is(tok::l_paren) || 665ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber NextToken->is(tok::l_square)) 6660178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_BinaryOperator; 6670178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 6680178673f541685cf5067814dfeee2644078e39a9Daniel Jasper // It is very unlikely that we are going to find a pointer or reference type 6690178673f541685cf5067814dfeee2644078e39a9Daniel Jasper // definition on the RHS of an assignment. 6700178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (IsExpression) 6710178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_BinaryOperator; 6720178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 6730178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_PointerOrReference; 6740178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 6750178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 6760178673f541685cf5067814dfeee2644078e39a9Daniel Jasper TokenType determinePlusMinusCaretUsage(const AnnotatedToken &Tok) { 6770178673f541685cf5067814dfeee2644078e39a9Daniel Jasper const AnnotatedToken *PrevToken = getPreviousToken(Tok); 6780178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (PrevToken == NULL) 6790178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_UnaryOperator; 6800178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 6810178673f541685cf5067814dfeee2644078e39a9Daniel Jasper // Use heuristics to recognize unary operators. 6820178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (PrevToken->is(tok::equal) || PrevToken->is(tok::l_paren) || 6830178673f541685cf5067814dfeee2644078e39a9Daniel Jasper PrevToken->is(tok::comma) || PrevToken->is(tok::l_square) || 6840178673f541685cf5067814dfeee2644078e39a9Daniel Jasper PrevToken->is(tok::question) || PrevToken->is(tok::colon) || 6850178673f541685cf5067814dfeee2644078e39a9Daniel Jasper PrevToken->is(tok::kw_return) || PrevToken->is(tok::kw_case) || 6860178673f541685cf5067814dfeee2644078e39a9Daniel Jasper PrevToken->is(tok::at) || PrevToken->is(tok::l_brace)) 6870178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_UnaryOperator; 6880178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 689ee0feec7362053f22b6c01d12e1bfa06fb3ac93fNico Weber // There can't be two consecutive binary operators. 6900178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (PrevToken->Type == TT_BinaryOperator) 6910178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_UnaryOperator; 6920178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 6930178673f541685cf5067814dfeee2644078e39a9Daniel Jasper // Fall back to marking the token as binary operator. 6940178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_BinaryOperator; 6950178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 6960178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 6970178673f541685cf5067814dfeee2644078e39a9Daniel Jasper /// \brief Determine whether ++/-- are pre- or post-increments/-decrements. 6980178673f541685cf5067814dfeee2644078e39a9Daniel Jasper TokenType determineIncrementUsage(const AnnotatedToken &Tok) { 6990178673f541685cf5067814dfeee2644078e39a9Daniel Jasper const AnnotatedToken *PrevToken = getPreviousToken(Tok); 7000178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (PrevToken == NULL) 7010178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_UnaryOperator; 7020178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (PrevToken->is(tok::r_paren) || PrevToken->is(tok::r_square) || 7030178673f541685cf5067814dfeee2644078e39a9Daniel Jasper PrevToken->is(tok::identifier)) 7040178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_TrailingUnaryOperator; 7050178673f541685cf5067814dfeee2644078e39a9Daniel Jasper 7060178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return TT_UnaryOperator; 7070178673f541685cf5067814dfeee2644078e39a9Daniel Jasper } 7084e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper 7094e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper SmallVector<Context, 8> Contexts; 7104e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper 7114e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper SourceManager &SourceMgr; 7124e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper Lexer &Lex; 7134e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper AnnotatedLine &Line; 7144e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper AnnotatedToken *CurrentToken; 7154e778091b0ff42895644ca8bef30f1a91ba6b32bDaniel Jasper bool KeywordVirtualFound; 716c2e6d2a4a7fe9dfa7d52a38c6048b7b18e6b591aNico Weber IdentifierInfo &Ident_in; 71732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper}; 71832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 71929f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper/// \brief Parses binary expressions by inserting fake parenthesis based on 72029f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper/// operator precedence. 72129f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasperclass ExpressionParser { 72229f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasperpublic: 72329f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper ExpressionParser(AnnotatedLine &Line) : Current(&Line.First) {} 72429f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 72529f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper /// \brief Parse expressions with the given operatore precedence. 7266ba52aab96c96b6d91ed7f5844f607b32f7f41c4Dmitri Gribenko void parse(prec::Level Precedence = prec::Unknown) { 72729f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper if (Precedence > prec::PointerToMember || Current == NULL) 72829f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper return; 72929f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 73029f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper // Skip over "return" until we can properly parse it. 73129f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper if (Current->is(tok::kw_return)) 73229f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper next(); 73329f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 73429f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper // Eagerly consume trailing comments. 73529f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper while (isTrailingComment(Current)) { 73629f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper next(); 73729f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper } 73829f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 73929f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper AnnotatedToken *Start = Current; 74029f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper bool OperatorFound = false; 74129f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 74229f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper while (Current != NULL) { 74329f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper // Consume operators with higher precedence. 7446ba52aab96c96b6d91ed7f5844f607b32f7f41c4Dmitri Gribenko parse(prec::Level(Precedence + 1)); 74529f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 74629f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper // At the end of the line or when an operator with higher precedence is 74729f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper // found, insert fake parenthesis and return. 74829f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper if (Current == NULL || Current->is(tok::semi) || closesScope(*Current) || 74929f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper ((Current->Type == TT_BinaryOperator || Current->is(tok::comma)) && 750468e399cfa371a0b698e566d89ffa786b9696f94Aaron Ballman getPrecedence(*Current) < Precedence)) { 75129f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper if (OperatorFound) { 75229f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper ++Start->FakeLParens; 75329f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper if (Current != NULL) 754087387a1e9ce5abeb4f348e14f64e5c2273eaedbDaniel Jasper ++Current->Parent->FakeRParens; 75529f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper } 75629f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper return; 75729f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper } 75829f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 75929f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper // Consume scopes: (), [], <> and {} 76029f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper if (opensScope(*Current)) { 76129f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper while (Current != NULL && !closesScope(*Current)) { 76229f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper next(); 76329f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper parse(); 76429f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper } 76529f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper next(); 76629f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper } else { 76729f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper // Operator found. 76829f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper if (getPrecedence(*Current) == Precedence) 76929f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper OperatorFound = true; 77029f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 77129f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper next(); 77229f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper } 77329f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper } 77429f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper } 77529f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 77629f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasperprivate: 77729f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper void next() { 77829f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper if (Current != NULL) 77929f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper Current = Current->Children.empty() ? NULL : &Current->Children[0]; 78029f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper } 78129f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 78229f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper bool closesScope(const AnnotatedToken &Tok) { 78329f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper return Current->is(tok::r_paren) || Current->Type == TT_TemplateCloser || 78429f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper Current->is(tok::r_brace) || Current->is(tok::r_square); 78529f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper } 78629f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 78729f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper bool opensScope(const AnnotatedToken &Tok) { 78829f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper return Current->is(tok::l_paren) || Current->Type == TT_TemplateOpener || 78929f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper Current->is(tok::l_brace) || Current->is(tok::l_square); 79029f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper } 79129f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 79229f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper AnnotatedToken *Current; 79329f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper}; 79429f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 7958ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jaspervoid TokenAnnotator::annotate(AnnotatedLine &Line) { 796c2e6d2a4a7fe9dfa7d52a38c6048b7b18e6b591aNico Weber AnnotatingParser Parser(SourceMgr, Lex, Line, Ident_in); 79732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Line.Type = Parser.parseLine(); 79832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Line.Type == LT_Invalid) 79932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return; 80032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 80129f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper ExpressionParser ExprParser(Line); 80229f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper ExprParser.parse(); 80329f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper 80432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Line.First.Type == TT_ObjCMethodSpecifier) 80532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Line.Type = LT_ObjCMethodDecl; 80632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper else if (Line.First.Type == TT_ObjCDecl) 80732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Line.Type = LT_ObjCDecl; 80832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper else if (Line.First.Type == TT_ObjCProperty) 80932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Line.Type = LT_ObjCProperty; 81032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 811729a743b317d877df3978e88a4a247d2edbf2090Daniel Jasper Line.First.SpacesRequiredBefore = 1; 81232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Line.First.MustBreakBefore = Line.First.FormatTok.MustBreakBefore; 81332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Line.First.CanBreakBefore = Line.First.MustBreakBefore; 81432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 81532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Line.First.TotalLength = Line.First.FormatTok.TokenLength; 81632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} 81732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 8188ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jaspervoid TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) { 8198ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper if (Line.First.Children.empty()) 8208ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper return; 8218ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper AnnotatedToken *Current = &Line.First.Children[0]; 8228ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper while (Current != NULL) { 823729a743b317d877df3978e88a4a247d2edbf2090Daniel Jasper if (Current->Type == TT_LineComment) 824729a743b317d877df3978e88a4a247d2edbf2090Daniel Jasper Current->SpacesRequiredBefore = Style.SpacesBeforeTrailingComments; 825729a743b317d877df3978e88a4a247d2edbf2090Daniel Jasper else 826729a743b317d877df3978e88a4a247d2edbf2090Daniel Jasper Current->SpacesRequiredBefore = 827729a743b317d877df3978e88a4a247d2edbf2090Daniel Jasper spaceRequiredBefore(Line, *Current) ? 1 : 0; 8288ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper 8298ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper if (Current->FormatTok.MustBreakBefore) { 8308ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->MustBreakBefore = true; 8318ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper } else if (Current->Type == TT_LineComment) { 8328ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->MustBreakBefore = Current->FormatTok.NewlinesBefore > 0; 83329f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper } else if (isTrailingComment(Current->Parent) || 8348ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper (Current->is(tok::string_literal) && 8358ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->Parent->is(tok::string_literal))) { 8368ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->MustBreakBefore = true; 8378ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper } else if (Current->is(tok::lessless) && !Current->Children.empty() && 8388ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->Parent->is(tok::string_literal) && 8398ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->Children[0].is(tok::string_literal)) { 8408ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->MustBreakBefore = true; 841c4615b7aaf97e303a4fc675956f7f5572d492885Daniel Jasper } else if (Current->FormatTok.NewlinesBefore > 1) { 842c4615b7aaf97e303a4fc675956f7f5572d492885Daniel Jasper Current->MustBreakBefore = true; 8438ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper } else { 8448ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->MustBreakBefore = false; 8458ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper } 8468ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->CanBreakBefore = 8478ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->MustBreakBefore || canBreakBefore(Line, *Current); 8488ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper if (Current->MustBreakBefore) 8498ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->TotalLength = Current->Parent->TotalLength + Style.ColumnLimit; 8508ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper else 8518ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->TotalLength = 8528ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->Parent->TotalLength + Current->FormatTok.TokenLength + 853729a743b317d877df3978e88a4a247d2edbf2090Daniel Jasper Current->SpacesRequiredBefore; 8548ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper // FIXME: Only calculate this if CanBreakBefore is true once static 8558ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper // initializers etc. are sorted out. 8568ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper // FIXME: Move magic numbers to a better place. 8578ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current->SplitPenalty = 8588ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper 20 * Current->BindingStrength + splitPenalty(Line, *Current); 8598ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper 8608ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper Current = Current->Children.empty() ? NULL : &Current->Children[0]; 86132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 86232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} 86332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 8648ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasperunsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line, 8658ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper const AnnotatedToken &Tok) { 86632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper const AnnotatedToken &Left = *Tok.Parent; 86732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper const AnnotatedToken &Right = Tok; 86832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 869a03ab10f0e4d888139b3b694dd55d176982f72a4Daniel Jasper if (Right.Type == TT_StartOfName) 870a03ab10f0e4d888139b3b694dd55d176982f72a4Daniel Jasper return Style.PenaltyReturnTypeOnItsOwnLine; 87132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::l_brace) && Right.isNot(tok::l_brace)) 87232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return 50; 87332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::equal) && Right.is(tok::l_brace)) 87432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return 150; 87532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::coloncolon)) 87632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return 500; 87732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 8786cabab48dacc1317821f8f078ed2d4c603b67affDaniel Jasper if (Left.Type == TT_RangeBasedForLoopColon || 8796cabab48dacc1317821f8f078ed2d4c603b67affDaniel Jasper Left.Type == TT_InheritanceColon) 88032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return 5; 88132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 88232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::arrow) || Right.is(tok::period)) { 883515f65df40624a767bc8763a0b6b678146b8e3c9Daniel Jasper if (Line.Type == LT_BuilderTypeCall) 88432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return 5; // Should be smaller than breaking at a nested comma. 885fc75908a7f58903a92c47e1ae02f9a05c36c9f59Daniel Jasper if ((Left.is(tok::r_paren) || Left.is(tok::r_square)) && 886fc75908a7f58903a92c47e1ae02f9a05c36c9f59Daniel Jasper Left.MatchingParen && Left.MatchingParen->ParameterCount > 0) 887fc75908a7f58903a92c47e1ae02f9a05c36c9f59Daniel Jasper return 10; 88832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return 150; 88932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 89032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 89132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // In for-loops, prefer breaking at ',' and ';'. 8927d81281fc39f6d40d86be6600adba13c05b4a639Daniel Jasper if (Line.First.is(tok::kw_for) && Left.is(tok::equal)) 8937d81281fc39f6d40d86be6600adba13c05b4a639Daniel Jasper return 4; 89432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 8958159d2f271c9142b46a672ac2c45821911171a7dDaniel Jasper if (Left.is(tok::semi)) 89632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return 0; 8978159d2f271c9142b46a672ac2c45821911171a7dDaniel Jasper if (Left.is(tok::comma)) 8988159d2f271c9142b46a672ac2c45821911171a7dDaniel Jasper return 1; 89932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 90032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // In Objective-C method expressions, prefer breaking before "param:" over 90132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // breaking after it. 90263d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper if (Right.Type == TT_ObjCSelectorName) 90332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return 0; 90463d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper if (Left.is(tok::colon) && Left.Type == TT_ObjCMethodExpr) 90532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return 20; 90632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 9070178673f541685cf5067814dfeee2644078e39a9Daniel Jasper if (Left.is(tok::l_paren) || Left.is(tok::l_square) || 9080178673f541685cf5067814dfeee2644078e39a9Daniel Jasper Left.Type == TT_TemplateOpener) 90932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return 20; 91032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 9114e8a7b4a95962f63a938c0d21c9aca0a51b78345Daniel Jasper if (Right.is(tok::lessless)) { 9124e8a7b4a95962f63a938c0d21c9aca0a51b78345Daniel Jasper if (Left.is(tok::string_literal)) { 9134e8a7b4a95962f63a938c0d21c9aca0a51b78345Daniel Jasper char LastChar = 9144e8a7b4a95962f63a938c0d21c9aca0a51b78345Daniel Jasper StringRef(Left.FormatTok.Tok.getLiteralData(), 9154e8a7b4a95962f63a938c0d21c9aca0a51b78345Daniel Jasper Left.FormatTok.TokenLength).drop_back(1).rtrim().back(); 9164e8a7b4a95962f63a938c0d21c9aca0a51b78345Daniel Jasper if (LastChar == ':' || LastChar == '=') 9174e8a7b4a95962f63a938c0d21c9aca0a51b78345Daniel Jasper return 100; 9184e8a7b4a95962f63a938c0d21c9aca0a51b78345Daniel Jasper } 9190178673f541685cf5067814dfeee2644078e39a9Daniel Jasper return prec::Shift; 9204e8a7b4a95962f63a938c0d21c9aca0a51b78345Daniel Jasper } 92132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.Type == TT_ConditionalExpr) 92232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return prec::Assignment; 92332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper prec::Level Level = getPrecedence(Left); 92432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 92532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Level != prec::Unknown) 92632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return Level; 92732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 92832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return 3; 92932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} 93032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 9318ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasperbool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, 9328ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper const AnnotatedToken &Left, 93332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper const AnnotatedToken &Right) { 93432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::hashhash)) 93532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return Left.is(tok::hash); 93632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::hashhash) || Left.is(tok::hash)) 93732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return Right.is(tok::hash); 93832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::r_paren) || Right.is(tok::semi) || Right.is(tok::comma)) 93932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 94032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::less) && 94132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper (Left.is(tok::kw_template) || 94232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper (Line.Type == LT_ObjCDecl && Style.ObjCSpaceBeforeProtocolList))) 94332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 94432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::arrow) || Right.is(tok::arrow)) 94532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 94632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::exclaim) || Left.is(tok::tilde)) 94732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 94832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::at) && 94932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper (Right.is(tok::identifier) || Right.is(tok::string_literal) || 95032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Right.is(tok::char_constant) || Right.is(tok::numeric_constant) || 95132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Right.is(tok::l_paren) || Right.is(tok::l_brace) || 95232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Right.is(tok::kw_true) || Right.is(tok::kw_false))) 95332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 95432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::coloncolon)) 95532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 95632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::coloncolon)) 957daf1a15d734d154f07d5a0328d3ef59cd9a68f13Daniel Jasper return Left.isNot(tok::identifier) && Left.isNot(tok::greater) && 958daf1a15d734d154f07d5a0328d3ef59cd9a68f13Daniel Jasper Left.isNot(tok::l_paren); 95932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::less) || Right.is(tok::greater) || Right.is(tok::less)) 96032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 96132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::amp) || Right.is(tok::star)) 96232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return Left.FormatTok.Tok.isLiteral() || 96332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper (Left.isNot(tok::star) && Left.isNot(tok::amp) && 96495e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weber Left.isNot(tok::l_paren) && !Style.PointerBindsToType); 96532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::amp) || Left.is(tok::star)) 96695e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weber return Right.FormatTok.Tok.isLiteral() || 96795e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weber (Right.isNot(tok::star) && Right.isNot(tok::amp) && 96895e8e468af284afb11ec1f994d0b5076fc7423d9Nico Weber Style.PointerBindsToType); 96932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::star) && Left.is(tok::l_paren)) 97032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 971051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber if (Left.is(tok::l_square)) 972051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber return Left.Type == TT_ObjCArrayLiteral && Right.isNot(tok::r_square); 973051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber if (Right.is(tok::r_square)) 974051860ee770bf83c3e66ab893be3642bb8bc2680Nico Weber return Right.Type == TT_ObjCArrayLiteral; 97532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::l_square) && Right.Type != TT_ObjCMethodExpr) 97632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 97732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::period) || Right.is(tok::period)) 97832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 97932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::colon)) 98032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return Left.Type != TT_ObjCMethodExpr; 98132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::colon)) 98232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return Right.Type != TT_ObjCMethodExpr; 98332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::l_paren)) 98432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 98532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::l_paren)) { 98632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return Line.Type == LT_ObjCDecl || Left.is(tok::kw_if) || 98732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left.is(tok::kw_for) || Left.is(tok::kw_while) || 98832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left.is(tok::kw_switch) || Left.is(tok::kw_return) || 98932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left.is(tok::kw_catch) || Left.is(tok::kw_new) || 99032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left.is(tok::kw_delete); 99132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 99232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::at) && 99332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Right.FormatTok.Tok.getObjCKeywordID() != tok::objc_not_keyword) 99432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 99532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::l_brace) && Right.is(tok::r_brace)) 99632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 99732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 99832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} 99932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 10008ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasperbool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, 10018ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper const AnnotatedToken &Tok) { 10022b4c924f85e156d66c01b3f16c850892c47dcc7aDaniel Jasper if (Tok.FormatTok.Tok.getIdentifierInfo() && 10032b4c924f85e156d66c01b3f16c850892c47dcc7aDaniel Jasper Tok.Parent->FormatTok.Tok.getIdentifierInfo()) 10042b4c924f85e156d66c01b3f16c850892c47dcc7aDaniel Jasper return true; // Never ever merge two identifiers. 100532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Line.Type == LT_ObjCMethodDecl) { 100632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.Parent->Type == TT_ObjCMethodSpecifier) 100732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 100832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.Parent->is(tok::r_paren) && Tok.is(tok::identifier)) 100932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // Don't space between ')' and <id> 101032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 101132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 101232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Line.Type == LT_ObjCProperty && 101332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper (Tok.is(tok::equal) || Tok.Parent->is(tok::equal))) 101432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 101532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 101632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.Parent->is(tok::comma)) 101732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 101832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.Type == TT_CtorInitializerColon || Tok.Type == TT_ObjCBlockLParen) 101932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 10202b4c924f85e156d66c01b3f16c850892c47dcc7aDaniel Jasper if (Tok.Parent->FormatTok.Tok.is(tok::kw_operator)) 10212b4c924f85e156d66c01b3f16c850892c47dcc7aDaniel Jasper return false; 10222b4c924f85e156d66c01b3f16c850892c47dcc7aDaniel Jasper if (Tok.Type == TT_OverloadedOperatorLParen) 102332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 102432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.is(tok::colon)) 102532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return Line.First.isNot(tok::kw_case) && !Tok.Children.empty() && 102632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Tok.Type != TT_ObjCMethodExpr; 102732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.Parent->Type == TT_UnaryOperator || Tok.Parent->Type == TT_CastRParen) 102832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 102932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.Type == TT_UnaryOperator) 103032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return Tok.Parent->isNot(tok::l_paren) && 103132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Tok.Parent->isNot(tok::l_square) && Tok.Parent->isNot(tok::at) && 103232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper (Tok.Parent->isNot(tok::colon) || 103332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Tok.Parent->Type != TT_ObjCMethodExpr); 103432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.Parent->is(tok::greater) && Tok.is(tok::greater)) { 103529f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper return Tok.Type == TT_TemplateCloser && 103629f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper Tok.Parent->Type == TT_TemplateCloser && 103729f123b2fa0435bb1962f0d9e9a2e660f35fbb2fDaniel Jasper Style.Standard != FormatStyle::LS_Cpp11; 103832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 103932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.Type == TT_BinaryOperator || Tok.Parent->Type == TT_BinaryOperator) 104032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 104132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.Parent->Type == TT_TemplateCloser && Tok.is(tok::l_paren)) 104232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 104332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.is(tok::less) && Line.First.is(tok::hash)) 104432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 104532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Tok.Type == TT_TrailingUnaryOperator) 104632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 10478ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper return spaceRequiredBetween(Line, *Tok.Parent, Tok); 104832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} 104932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 10508ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasperbool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, 10518ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper const AnnotatedToken &Right) { 105232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper const AnnotatedToken &Left = *Right.Parent; 1053a03ab10f0e4d888139b3b694dd55d176982f72a4Daniel Jasper if (Right.Type == TT_StartOfName) 105432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 105532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::colon) && Right.Type == TT_ObjCMethodExpr) 105632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 105732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::colon) && Left.Type == TT_ObjCMethodExpr) 105832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 105963d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper if (Right.Type == TT_ObjCSelectorName) 106032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 106132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.ClosesTemplateDeclaration) 106232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 106332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.Type == TT_ConditionalExpr || Right.is(tok::question)) 106432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 10656cabab48dacc1317821f8f078ed2d4c603b67affDaniel Jasper if (Right.Type == TT_RangeBasedForLoopColon || 10666cabab48dacc1317821f8f078ed2d4c603b67affDaniel Jasper Right.Type == TT_InheritanceColon) 10676cabab48dacc1317821f8f078ed2d4c603b67affDaniel Jasper return false; 10686cabab48dacc1317821f8f078ed2d4c603b67affDaniel Jasper if (Left.Type == TT_RangeBasedForLoopColon || 10696cabab48dacc1317821f8f078ed2d4c603b67affDaniel Jasper Left.Type == TT_InheritanceColon) 107032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return true; 10717d81281fc39f6d40d86be6600adba13c05b4a639Daniel Jasper if (Right.Type == TT_RangeBasedForLoopColon) 10727d81281fc39f6d40d86be6600adba13c05b4a639Daniel Jasper return false; 107332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.Type == TT_PointerOrReference || Left.Type == TT_TemplateCloser || 107432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left.Type == TT_UnaryOperator || Left.Type == TT_ConditionalExpr || 1075dc2efa1c10c4646d692cc57db9fdbbebe3a48255Daniel Jasper Left.is(tok::question) || Left.is(tok::kw_operator)) 107632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 107732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::equal) && Line.Type == LT_VirtualFunctionDecl) 107832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 107932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 108032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.Type == TT_LineComment) 108132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // We rely on MustBreakBefore being set correctly here as we should not 108232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // change the "binding" behavior of a comment. 108332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 108432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 10857d81281fc39f6d40d86be6600adba13c05b4a639Daniel Jasper // FIXME: We can probably remove this special case once we have implemented 10867d81281fc39f6d40d86be6600adba13c05b4a639Daniel Jasper // breaking after types in general. 10877d81281fc39f6d40d86be6600adba13c05b4a639Daniel Jasper if (Line.First.is(tok::kw_for) && !Right.Children.empty() && 10887d81281fc39f6d40d86be6600adba13c05b4a639Daniel Jasper Right.Children[0].is(tok::equal)) 10897d81281fc39f6d40d86be6600adba13c05b4a639Daniel Jasper return true; 10907d81281fc39f6d40d86be6600adba13c05b4a639Daniel Jasper 109132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // Allow breaking after a trailing 'const', e.g. after a method declaration, 109232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // unless it is follow by ';', '{' or '='. 109332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Left.is(tok::kw_const) && Left.Parent != NULL && 109432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left.Parent->is(tok::r_paren)) 109532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return Right.isNot(tok::l_brace) && Right.isNot(tok::semi) && 109632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Right.isNot(tok::equal); 109732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 109832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // We only break before r_brace if there was a corresponding break before 109932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper // the l_brace, which is tracked by BreakBeforeClosingBrace. 110032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::r_brace)) 110132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 110232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 110332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper if (Right.is(tok::r_paren) || Right.is(tok::greater)) 110432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return false; 11053a204418482c9ae70ad482e781132c54306c3aa6Daniel Jasper if (Left.is(tok::identifier) && Right.is(tok::string_literal)) 11063a204418482c9ae70ad482e781132c54306c3aa6Daniel Jasper return true; 110732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper return (isBinaryOperator(Left) && Left.isNot(tok::lessless)) || 110832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left.is(tok::comma) || Right.is(tok::lessless) || 110932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Right.is(tok::arrow) || Right.is(tok::period) || 111032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Right.is(tok::colon) || Left.is(tok::coloncolon) || 111132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Left.is(tok::semi) || Left.is(tok::l_brace) || 111232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper (Left.is(tok::r_paren) && Left.Type != TT_CastRParen && 111332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Right.is(tok::identifier)) || 111432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper (Left.is(tok::l_paren) && !Right.is(tok::r_paren)) || 111532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper (Left.is(tok::l_square) && !Right.is(tok::r_square)); 111632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} 111732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 111832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} // namespace format 111932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} // namespace clang 1120