TokenAnnotator.cpp revision 84a1a63b034744b68a27ec171dca5b1b7cf303f0
18dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor//===--- TokenAnnotator.cpp - Format C++ code -----------------------------===// 28dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor// 38dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor// The LLVM Compiler Infrastructure 48dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor// 58dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor// This file is distributed under the University of Illinois Open Source 68dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor// License. See LICENSE.TXT for details. 78dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor// 88dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor//===----------------------------------------------------------------------===// 98dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor/// 108dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor/// \file 118dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor/// \brief This file implements a token annotator, i.e. creates 122d88708cbe4e4ec5e04e4acb6bd7f5be68557379John McCall/// \c AnnotatedTokens out of \c FormatTokens with required extra information. 13e737f5041a36d0befb39ffeed8d50ba15916d3daDouglas Gregor/// 14f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall//===----------------------------------------------------------------------===// 157cd088e519d7e6caa4c4c12db52e0e4ae35d25c2John McCall 16aba43bb13b3aa3e81990989375fba3a902bfe1c2Douglas Gregor#include "TokenAnnotator.h" 178dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor#include "clang/Basic/SourceManager.h" 188dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor#include "clang/Lex/Lexer.h" 198dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor 200c01d18094100db92d38daa923c95661512db203John McCallnamespace clang { 218dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregornamespace format { 22a88cfbfac9bbcbb9858f048d6d73a48711d8e93dDouglas Gregor 2321ef0fa27b0783ec0bc6aa5b524feb2ec840f952John McCallstatic bool isUnaryOperator(const AnnotatedToken &Tok) { 2483ddad3ab513f5d73698cf9fbeb4ed3f011bc3b9Douglas Gregor switch (Tok.FormatTok.Tok.getKind()) { 258dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor case tok::plus: 268dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor case tok::plusplus: 278dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor case tok::minus: 28b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall case tok::minusminus: 29b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall case tok::exclaim: 30c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor case tok::tilde: 31c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor case tok::kw_sizeof: 32a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi case tok::kw_alignof: 33c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor return true; 34a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi default: 35c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor return false; 36a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi } 37c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor} 38b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall 39a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumistatic bool isBinaryOperator(const AnnotatedToken &Tok) { 40c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor // Comma is a binary operator, but does not behave as such wrt. formatting. 41b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall return getPrecedence(Tok) > prec::Comma; 42b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall} 43b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall 44b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall// Returns the previous token ignoring comments. 45b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCallstatic AnnotatedToken *getPreviousToken(AnnotatedToken &Tok) { 46c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor AnnotatedToken *PrevToken = Tok.Parent; 47c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor while (PrevToken != NULL && PrevToken->is(tok::comment)) 48a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi PrevToken = PrevToken->Parent; 49c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor return PrevToken; 50a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi} 51c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregorstatic const AnnotatedToken *getPreviousToken(const AnnotatedToken &Tok) { 52a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi return getPreviousToken(const_cast<AnnotatedToken &>(Tok)); 53c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor} 54b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall 55a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumistatic bool isTrailingComment(AnnotatedToken *Tok) { 56c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor return Tok != NULL && Tok->is(tok::comment) && 57b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall (Tok->Children.empty() || 58b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall Tok->Children[0].FormatTok.NewlinesBefore > 0); 59b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall} 607b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins 617b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins// Returns the next token ignoring comments. 627b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsstatic const AnnotatedToken *getNextToken(const AnnotatedToken &Tok) { 631d8d1ccd36888f1120b3a1df9e76f35dc2edb81dJohn McCall if (Tok.Children.empty()) 6423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins return NULL; 6523323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins const AnnotatedToken *NextToken = &Tok.Children[0]; 6623323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins while (NextToken->is(tok::comment)) { 67cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if (NextToken->Children.empty()) 68cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return NULL; 69cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt NextToken = &NextToken->Children[0]; 7023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins } 714ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth return NextToken; 724ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth} 73cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt 74cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt/// \brief A parser that gathers additional information about tokens. 75f6702a3927147655206ae729a84339c4fda4c651Richard Smith/// 76f6702a3927147655206ae729a84339c4fda4c651Richard Smith/// The \c TokenAnnotator tries to matches parenthesis and square brakets and 77f6702a3927147655206ae729a84339c4fda4c651Richard Smith/// store a parenthesis levels. It also tries to resolve matching "<" and ">" 78f6702a3927147655206ae729a84339c4fda4c651Richard Smith/// into template parameter lists. 7960d7b3a319d84d688752be3870615ac0f111fb16John McCallclass AnnotatingParser { 807663f396651716c82280f8fdcf97ad8e27c1ce5aNick Lewyckypublic: 81cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt AnnotatingParser(SourceManager &SourceMgr, Lexer &Lex, AnnotatedLine &Line, 82fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman IdentifierInfo &Ident_in) 83fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman : SourceMgr(SourceMgr), Lex(Lex), Line(Line), CurrentToken(&Line.First), 84f6702a3927147655206ae729a84339c4fda4c651Richard Smith KeywordVirtualFound(false), Ident_in(Ident_in) { 85cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt Contexts.push_back(Context(1, /*IsExpression=*/ false)); 867663f396651716c82280f8fdcf97ad8e27c1ce5aNick Lewycky } 87a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi 887663f396651716c82280f8fdcf97ad8e27c1ce5aNick Lewyckyprivate: 89cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt bool parseAngle() { 90fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman if (CurrentToken == NULL) 91fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman return false; 92cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt ScopedContextCreator ContextCreator(*this, 10); 934ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth AnnotatedToken *Left = CurrentToken->Parent; 944ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth Contexts.back().IsExpression = false; 954ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth while (CurrentToken != NULL) { 964ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth if (CurrentToken->is(tok::greater)) { 9723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins Left->MatchingParen = CurrentToken; 9823323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins CurrentToken->MatchingParen = Left; 9923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins CurrentToken->Type = TT_TemplateCloser; 10023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins next(); 10123323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins return true; 10223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins } 10323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins if (CurrentToken->is(tok::r_paren) || CurrentToken->is(tok::r_square) || 10423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins CurrentToken->is(tok::r_brace)) 1055bbc385ad2d8e487edfbc2756eaf4fb0b920cfe4Benjamin Kramer return false; 1065bbc385ad2d8e487edfbc2756eaf4fb0b920cfe4Benjamin Kramer if (CurrentToken->is(tok::pipepipe) || CurrentToken->is(tok::ampamp) || 10731c195ac0f3869e742d42f9d02b6cd33442fb630Rafael Espindola CurrentToken->is(tok::question) || CurrentToken->is(tok::colon)) 10831c195ac0f3869e742d42f9d02b6cd33442fb630Rafael Espindola return false; 10923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins updateParameterCount(Left, CurrentToken); 110d8fe2d56fb5463c9d109e8c6dab2e98b06bee186Anders Carlsson if (!consumeToken()) 111d8fe2d56fb5463c9d109e8c6dab2e98b06bee186Anders Carlsson return false; 112d8fe2d56fb5463c9d109e8c6dab2e98b06bee186Anders Carlsson } 1134f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor return false; 1144f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor } 115b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie 1164f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor bool parseParens(bool LookForDecls = false) { 1174f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor if (CurrentToken == NULL) 1184f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor return false; 11957ad37823e198f977cac605dbfbaefb4daf325e9Chris Lattner ScopedContextCreator ContextCreator(*this, 1); 12057ad37823e198f977cac605dbfbaefb4daf325e9Chris Lattner 12157ad37823e198f977cac605dbfbaefb4daf325e9Chris Lattner // FIXME: This is a bit of a hack. Do better. 12257ad37823e198f977cac605dbfbaefb4daf325e9Chris Lattner Contexts.back().ColonIsForRangeExpr = 12357ad37823e198f977cac605dbfbaefb4daf325e9Chris Lattner Contexts.size() == 2 && Contexts[0].ColonIsForRangeExpr; 12457ad37823e198f977cac605dbfbaefb4daf325e9Chris Lattner 12557ad37823e198f977cac605dbfbaefb4daf325e9Chris Lattner bool StartsObjCMethodExpr = false; 12657ad37823e198f977cac605dbfbaefb4daf325e9Chris Lattner AnnotatedToken *Left = CurrentToken->Parent; 1274f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor if (CurrentToken->is(tok::caret)) { 128b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie // ^( starts a block. 1294f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor Left->Type = TT_ObjCBlockLParen; 1304f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor } else if (AnnotatedToken *MaybeSel = Left->Parent) { 1313dbd3d5c04cd5abd7dfd83b15f51d7c610a3c512John McCall // @selector( starts a selector. 1323dbd3d5c04cd5abd7dfd83b15f51d7c610a3c512John McCall if (MaybeSel->isObjCAtKeyword(tok::objc_selector) && MaybeSel->Parent && 1333dbd3d5c04cd5abd7dfd83b15f51d7c610a3c512John McCall MaybeSel->Parent->is(tok::at)) { 1343dbd3d5c04cd5abd7dfd83b15f51d7c610a3c512John McCall StartsObjCMethodExpr = true; 1353dbd3d5c04cd5abd7dfd83b15f51d7c610a3c512John McCall } 1363dbd3d5c04cd5abd7dfd83b15f51d7c610a3c512John McCall } 1370cfaf6a270ecd0f5c7e541a8047c87948317548bDouglas Gregor 1380cfaf6a270ecd0f5c7e541a8047c87948317548bDouglas Gregor if (StartsObjCMethodExpr) { 1393dbd3d5c04cd5abd7dfd83b15f51d7c610a3c512John McCall Contexts.back().ColonIsObjCMethodExpr = true; 1403dbd3d5c04cd5abd7dfd83b15f51d7c610a3c512John McCall Left->Type = TT_ObjCMethodExpr; 1413dbd3d5c04cd5abd7dfd83b15f51d7c610a3c512John McCall } 1423dbd3d5c04cd5abd7dfd83b15f51d7c610a3c512John McCall 1433dbd3d5c04cd5abd7dfd83b15f51d7c610a3c512John McCall while (CurrentToken != NULL) { 1443dbd3d5c04cd5abd7dfd83b15f51d7c610a3c512John McCall // LookForDecls is set when "if (" has been seen. Check for 1453e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith // 'identifier' '*' 'identifier' followed by not '=' -- this 1463e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith // '*' has to be a binary operator but determineStarAmpUsage() will 1478dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor // categorize it as an unary operator, so set the right type here. 148a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall if (LookForDecls && !CurrentToken->Children.empty()) { 149561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor AnnotatedToken &Prev = *CurrentToken->Parent; 150836adf6771d5170d936599dfcce21687e37e9bbfDouglas Gregor AnnotatedToken &Next = CurrentToken->Children[0]; 151ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall if (Prev.Parent->is(tok::identifier) && 152ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall (Prev.is(tok::star) || Prev.is(tok::amp)) && 153ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall CurrentToken->is(tok::identifier) && Next.isNot(tok::equal)) { 1548dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor Prev.Type = TT_BinaryOperator; 155a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall LookForDecls = false; 1568dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor } 157b4eeaff1595b7d0a8fbc2b3c8bec7dc63f48b7fdDouglas Gregor } 158b4eeaff1595b7d0a8fbc2b3c8bec7dc63f48b7fdDouglas Gregor 1598dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor if (CurrentToken->is(tok::r_paren)) { 1601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Left->MatchingParen = CurrentToken; 161b5b37d194dddb960f43f763b3f9c3e17e7be3c2dRichard Smith CurrentToken->MatchingParen = Left; 162b5b37d194dddb960f43f763b3f9c3e17e7be3c2dRichard Smith 163b5b37d194dddb960f43f763b3f9c3e17e7be3c2dRichard Smith if (StartsObjCMethodExpr) { 164b5b37d194dddb960f43f763b3f9c3e17e7be3c2dRichard Smith CurrentToken->Type = TT_ObjCMethodExpr; 165b5b37d194dddb960f43f763b3f9c3e17e7be3c2dRichard Smith if (Contexts.back().FirstObjCSelectorName != NULL) { 166b5b37d194dddb960f43f763b3f9c3e17e7be3c2dRichard Smith Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 167b5b37d194dddb960f43f763b3f9c3e17e7be3c2dRichard Smith Contexts.back().LongestObjCSelectorName; 168b5b37d194dddb960f43f763b3f9c3e17e7be3c2dRichard Smith } 169b5b37d194dddb960f43f763b3f9c3e17e7be3c2dRichard Smith } 170b5b37d194dddb960f43f763b3f9c3e17e7be3c2dRichard Smith 171b5b37d194dddb960f43f763b3f9c3e17e7be3c2dRichard Smith next(); 172b5b37d194dddb960f43f763b3f9c3e17e7be3c2dRichard Smith return true; 173b5b37d194dddb960f43f763b3f9c3e17e7be3c2dRichard Smith } 174b5b37d194dddb960f43f763b3f9c3e17e7be3c2dRichard Smith if (CurrentToken->is(tok::r_square) || CurrentToken->is(tok::r_brace)) 175b5b37d194dddb960f43f763b3f9c3e17e7be3c2dRichard Smith return false; 176b5b37d194dddb960f43f763b3f9c3e17e7be3c2dRichard Smith updateParameterCount(Left, CurrentToken); 1778dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor if (!consumeToken()) 178162e1c1b487352434552147967c3dd296ebee2f7Richard Smith return false; 179162e1c1b487352434552147967c3dd296ebee2f7Richard Smith } 180162e1c1b487352434552147967c3dd296ebee2f7Richard Smith return false; 181162e1c1b487352434552147967c3dd296ebee2f7Richard Smith } 182162e1c1b487352434552147967c3dd296ebee2f7Richard Smith 183162e1c1b487352434552147967c3dd296ebee2f7Richard Smith bool parseSquare() { 184162e1c1b487352434552147967c3dd296ebee2f7Richard Smith if (!CurrentToken) 1858dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor return false; 1868dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor ScopedContextCreator ContextCreator(*this, 10); 1878dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor 188cde5a400dbc9655eddf0f383585d3cf67c11c539John McCall // A '[' could be an index subscript (after an indentifier or after 189cde5a400dbc9655eddf0f383585d3cf67c11c539John McCall // ')' or ']'), it could be the start of an Objective-C method 190cde5a400dbc9655eddf0f383585d3cf67c11c539John McCall // expression, or it could the the start of an Objective-C array literal. 191cde5a400dbc9655eddf0f383585d3cf67c11c539John McCall AnnotatedToken *Left = CurrentToken->Parent; 192162e1c1b487352434552147967c3dd296ebee2f7Richard Smith AnnotatedToken *Parent = getPreviousToken(*Left); 193cde5a400dbc9655eddf0f383585d3cf67c11c539John McCall bool StartsObjCMethodExpr = 194162e1c1b487352434552147967c3dd296ebee2f7Richard Smith !Parent || Parent->is(tok::colon) || Parent->is(tok::l_square) || 195162e1c1b487352434552147967c3dd296ebee2f7Richard Smith Parent->is(tok::l_paren) || Parent->is(tok::kw_return) || 196cde5a400dbc9655eddf0f383585d3cf67c11c539John McCall Parent->is(tok::kw_throw) || isUnaryOperator(*Parent) || 197d57a38ee02c285d69d05fed6df0d7406b2517888Douglas Gregor Parent->Type == TT_ObjCForIn || Parent->Type == TT_CastRParen || 198a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi getBinOpPrecedence(Parent->FormatTok.Tok.getKind(), true, true) > 199ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor prec::Unknown; 2007c1e98f1cb37b40e619a0c8aee8b337f037b432bDouglas Gregor bool StartsObjCArrayLiteral = Parent && Parent->is(tok::at); 2017c1e98f1cb37b40e619a0c8aee8b337f037b432bDouglas Gregor 202b710722d2348cd0945d2b4f02062c7f685146eb0Douglas Gregor if (StartsObjCMethodExpr) { 203b710722d2348cd0945d2b4f02062c7f685146eb0Douglas Gregor Contexts.back().ColonIsObjCMethodExpr = true; 204a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi Left->Type = TT_ObjCMethodExpr; 2055df37bd0242e838e465f0bd51a70af424d152053Rafael Espindola } else if (StartsObjCArrayLiteral) { 2065df37bd0242e838e465f0bd51a70af424d152053Rafael Espindola Left->Type = TT_ObjCArrayLiteral; 2075df37bd0242e838e465f0bd51a70af424d152053Rafael Espindola } 2085df37bd0242e838e465f0bd51a70af424d152053Rafael Espindola 2095df37bd0242e838e465f0bd51a70af424d152053Rafael Espindola while (CurrentToken != NULL) { 2105df37bd0242e838e465f0bd51a70af424d152053Rafael Espindola if (CurrentToken->is(tok::r_square)) { 2115126fd0dd92c4ec211c837ee78d5ce59c68dcbd5John McCall if (!CurrentToken->Children.empty() && 2125126fd0dd92c4ec211c837ee78d5ce59c68dcbd5John McCall CurrentToken->Children[0].is(tok::l_paren)) { 2131d8d1ccd36888f1120b3a1df9e76f35dc2edb81dJohn McCall // An ObjC method call is rarely followed by an open parenthesis. 214d57a38ee02c285d69d05fed6df0d7406b2517888Douglas Gregor // FIXME: Do we incorrectly label ":" with this? 21546460a68f6508775e98c19b4bb8454bb471aac24John McCall StartsObjCMethodExpr = false; 2161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Left->Type = TT_Unknown; 2178dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor } 2188dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor if (StartsObjCMethodExpr) { 2198dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor CurrentToken->Type = TT_ObjCMethodExpr; 220162e1c1b487352434552147967c3dd296ebee2f7Richard Smith // determineStarAmpUsage() thinks that '*' '[' is allocating an 2213e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith // array of pointers, but if '[' starts a selector then '*' is a 2223e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith // binary operator. 2233e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (Parent != NULL && 224162e1c1b487352434552147967c3dd296ebee2f7Richard Smith (Parent->is(tok::star) || Parent->is(tok::amp)) && 225162e1c1b487352434552147967c3dd296ebee2f7Richard Smith Parent->Type == TT_PointerOrReference) 226162e1c1b487352434552147967c3dd296ebee2f7Richard Smith Parent->Type = TT_BinaryOperator; 2273e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith } else if (StartsObjCArrayLiteral) { 2283e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith CurrentToken->Type = TT_ObjCArrayLiteral; 2293e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith } 2303e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith Left->MatchingParen = CurrentToken; 2313e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith CurrentToken->MatchingParen = Left; 2323e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (Contexts.back().FirstObjCSelectorName != NULL) 2333e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 2343e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith Contexts.back().LongestObjCSelectorName; 2353e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith next(); 2363e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith return true; 2373e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith } 2383e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (CurrentToken->is(tok::r_paren) || CurrentToken->is(tok::r_brace)) 2393e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith return false; 2403e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith updateParameterCount(Left, CurrentToken); 2413e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (!consumeToken()) 2423e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith return false; 2433e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith } 2443e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith return false; 2453e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith } 246ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor 2473e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith bool parseBrace() { 2483e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith // Lines are fine to end with '{'. 2493e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (CurrentToken == NULL) 2503e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith return true; 2513e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith ScopedContextCreator ContextCreator(*this, 1); 2523e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith AnnotatedToken *Left = CurrentToken->Parent; 2533e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith while (CurrentToken != NULL) { 2543e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (CurrentToken->is(tok::r_brace)) { 2553e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith Left->MatchingParen = CurrentToken; 2563e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith CurrentToken->MatchingParen = Left; 2573e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith next(); 2583e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith return true; 2593e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith } 2603e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (CurrentToken->is(tok::r_paren) || CurrentToken->is(tok::r_square)) 2613e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith return false; 2623e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith updateParameterCount(Left, CurrentToken); 2633e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (!consumeToken()) 2643e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith return false; 2653e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith } 2663e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith return true; 2673e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith } 268a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi 2693e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith void updateParameterCount(AnnotatedToken *Left, AnnotatedToken *Current) { 2703e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (Current->is(tok::comma)) 2713e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith ++Left->ParameterCount; 272162e1c1b487352434552147967c3dd296ebee2f7Richard Smith else if (Left->ParameterCount == 0 && Current->isNot(tok::comment)) 273162e1c1b487352434552147967c3dd296ebee2f7Richard Smith Left->ParameterCount = 1; 2743d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor } 2759901c57806f7e36736ed1616e6ab3eebcc99b78cDouglas Gregor 2769901c57806f7e36736ed1616e6ab3eebcc99b78cDouglas Gregor bool parseConditional() { 2779901c57806f7e36736ed1616e6ab3eebcc99b78cDouglas Gregor while (CurrentToken != NULL) { 2789901c57806f7e36736ed1616e6ab3eebcc99b78cDouglas Gregor if (CurrentToken->is(tok::colon)) { 2799901c57806f7e36736ed1616e6ab3eebcc99b78cDouglas Gregor CurrentToken->Type = TT_ConditionalExpr; 2809901c57806f7e36736ed1616e6ab3eebcc99b78cDouglas Gregor next(); 2819901c57806f7e36736ed1616e6ab3eebcc99b78cDouglas Gregor return true; 282ce3ff2bd3a3386dbc209d3cba4b8769173b274c1John McCall } 283a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall if (!consumeToken()) 2840a5fa06a688e1086ea553a24b42b9915996ed1f7John McCall return false; 2850a5fa06a688e1086ea553a24b42b9915996ed1f7John McCall } 2860a5fa06a688e1086ea553a24b42b9915996ed1f7John McCall return false; 2870a5fa06a688e1086ea553a24b42b9915996ed1f7John McCall } 2883d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor 2893d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor bool parseTemplateDeclaration() { 290c6dbc3fa467e2355b678a6b717534928048efcb2Douglas Gregor if (CurrentToken != NULL && CurrentToken->is(tok::less)) { 291c6dbc3fa467e2355b678a6b717534928048efcb2Douglas Gregor CurrentToken->Type = TT_TemplateOpener; 292c6dbc3fa467e2355b678a6b717534928048efcb2Douglas Gregor next(); 293c6dbc3fa467e2355b678a6b717534928048efcb2Douglas Gregor if (!parseAngle()) 294c6dbc3fa467e2355b678a6b717534928048efcb2Douglas Gregor return false; 295a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi if (CurrentToken != NULL) 296b9f1b8d877541e76390cd3807c2dcff2f950360aDouglas Gregor CurrentToken->Parent->ClosesTemplateDeclaration = true; 2973d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor return true; 298ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara } 2993d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor return false; 3000a5fa06a688e1086ea553a24b42b9915996ed1f7John McCall } 30116573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor 30216573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor bool consumeToken() { 3033d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor AnnotatedToken *Tok = CurrentToken; 3045b9cc5df25c2198f270dd1d5c438fdce70d4051dSebastian Redl next(); 305ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith switch (Tok->FormatTok.Tok.getKind()) { 306796c1a1e3e63e459e371383ac878aa5f40b02a8cRichard Smith case tok::plus: 3071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case tok::minus: 308b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall // At the start of the line, +/- specific ObjectiveC method 309b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall // declarations. 310b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall if (Tok->Parent == NULL) 311b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall Tok->Type = TT_ObjCMethodSpecifier; 3121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump break; 3137caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor case tok::colon: 3147caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor // Colons from ?: are handled in parseConditional(). 3157caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor if (Tok->Parent->is(tok::r_paren)) { 3167caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor Tok->Type = TT_CtorInitializerColon; 3171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } else if (Contexts.back().ColonIsObjCMethodExpr || 31846460a68f6508775e98c19b4bb8454bb471aac24John McCall Line.First.Type == TT_ObjCMethodSpecifier) { 319a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi Tok->Type = TT_ObjCMethodExpr; 3206b6b42aed07726178f61954ac6e51f47da00275cArgyrios Kyrtzidis Tok->Parent->Type = TT_ObjCSelectorName; 321c070cc602d6eefea881f71a60de09e05b54c3fddDouglas Gregor if (Tok->Parent->FormatTok.TokenLength > 3226b6b42aed07726178f61954ac6e51f47da00275cArgyrios Kyrtzidis Contexts.back().LongestObjCSelectorName) 3236b6b42aed07726178f61954ac6e51f47da00275cArgyrios Kyrtzidis Contexts.back().LongestObjCSelectorName = 324a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi Tok->Parent->FormatTok.TokenLength; 325390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump if (Contexts.back().FirstObjCSelectorName == NULL) 326390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump Contexts.back().FirstObjCSelectorName = Tok->Parent; 3276826314938f8510cd1a6b03b5d032592456ae27bJohn McCall } else if (Contexts.back().ColonIsForRangeExpr) { 3286826314938f8510cd1a6b03b5d032592456ae27bJohn McCall Tok->Type = TT_RangeBasedForLoopColon; 329449d0a829007ea654912098e6a73134a2c529d61Douglas Gregor } else if (Contexts.size() == 1) { 33060c93c9981c467738369702e7aa23fd58c2b6aacDouglas Gregor Tok->Type = TT_InheritanceColon; 33160c93c9981c467738369702e7aa23fd58c2b6aacDouglas Gregor } 3329aab9c4116bb3ea876d92d4af10bff7f4c451f24Douglas Gregor break; 3339aab9c4116bb3ea876d92d4af10bff7f4c451f24Douglas Gregor case tok::kw_if: 3344e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie case tok::kw_while: 3359aab9c4116bb3ea876d92d4af10bff7f4c451f24Douglas Gregor if (CurrentToken != NULL && CurrentToken->is(tok::l_paren)) { 3369aab9c4116bb3ea876d92d4af10bff7f4c451f24Douglas Gregor next(); 3379aab9c4116bb3ea876d92d4af10bff7f4c451f24Douglas Gregor if (!parseParens(/*LookForDecls=*/ true)) 3382c712f50cd56eaf3662989b556e9c6b1e8fcd11aKaelyn Uhrain return false; 3391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 3407caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor break; 3413e9ea0b8cd7c4691d62e385245556be5fded58a7Richard Smith case tok::kw_for: 3427caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor Contexts.back().ColonIsForRangeExpr = true; 3437caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor next(); 3447caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor if (!parseParens()) 345f7d72f5a4a3f0e610d77c6779ca3c21920a14bc7Douglas Gregor return false; 346f7d72f5a4a3f0e610d77c6779ca3c21920a14bc7Douglas Gregor break; 3477caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor case tok::l_paren: 348dd5756c04c98e354b85c4f7eb660ae60c6d341ecDeLesley Hutchins if (!parseParens()) 349a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi return false; 350251b4ff2578e26959a4c036140ccd61c5e9292f2Douglas Gregor if (Line.MustBeDeclaration) 351251b4ff2578e26959a4c036140ccd61c5e9292f2Douglas Gregor Line.MightBeFunctionDecl = true; 352251b4ff2578e26959a4c036140ccd61c5e9292f2Douglas Gregor break; 353a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi case tok::l_square: 354cf3293eaeb3853d12cff47e648bbe835004e929fDouglas Gregor if (!parseSquare()) 355a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi return false; 35660c93c9981c467738369702e7aa23fd58c2b6aacDouglas Gregor break; 35760c93c9981c467738369702e7aa23fd58c2b6aacDouglas Gregor case tok::l_brace: 35860c93c9981c467738369702e7aa23fd58c2b6aacDouglas Gregor if (!parseBrace()) 3591f5f3a4d58a1c7c50c331b33329fc14563533c04Douglas Gregor return false; 360adb1d4c18ee83249d4cffc99ef902f98e846092aRichard Smith break; 3611f5f3a4d58a1c7c50c331b33329fc14563533c04Douglas Gregor case tok::less: 362adb1d4c18ee83249d4cffc99ef902f98e846092aRichard Smith if (parseAngle()) 3631f5f3a4d58a1c7c50c331b33329fc14563533c04Douglas Gregor Tok->Type = TT_TemplateOpener; 3646b98b2e5f33ce2dcdb7fa385f7e21672d49f1a69Douglas Gregor else { 3655b9cc5df25c2198f270dd1d5c438fdce70d4051dSebastian Redl Tok->Type = TT_BinaryOperator; 3665b9cc5df25c2198f270dd1d5c438fdce70d4051dSebastian Redl CurrentToken = Tok; 3675b9cc5df25c2198f270dd1d5c438fdce70d4051dSebastian Redl next(); 36834b41d939a1328f484511c6002ba2456db879a29Richard Smith } 3695b9cc5df25c2198f270dd1d5c438fdce70d4051dSebastian Redl break; 3705b9cc5df25c2198f270dd1d5c438fdce70d4051dSebastian Redl case tok::r_paren: 3715b9cc5df25c2198f270dd1d5c438fdce70d4051dSebastian Redl case tok::r_square: 3725b9cc5df25c2198f270dd1d5c438fdce70d4051dSebastian Redl return false; 3735b9cc5df25c2198f270dd1d5c438fdce70d4051dSebastian Redl case tok::r_brace: 3746aeaa60217e1ed11a621409acf1b53df0d14b591Eli Friedman // Lines can start with '}'. 3756eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor if (Tok->Parent != NULL) 3766b98b2e5f33ce2dcdb7fa385f7e21672d49f1a69Douglas Gregor return false; 3776b98b2e5f33ce2dcdb7fa385f7e21672d49f1a69Douglas Gregor break; 3786b98b2e5f33ce2dcdb7fa385f7e21672d49f1a69Douglas Gregor case tok::greater: 3796eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor Tok->Type = TT_BinaryOperator; 380a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi break; 3811f5f3a4d58a1c7c50c331b33329fc14563533c04Douglas Gregor case tok::kw_operator: 382ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith while (CurrentToken && CurrentToken->isNot(tok::l_paren)) { 383ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith if (CurrentToken->is(tok::star) || CurrentToken->is(tok::amp)) 384d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall CurrentToken->Type = TT_PointerOrReference; 3853d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor consumeToken(); 386e3499cae8e5323ac553ad56977bf1cd42b9a5a35Richard Smith } 387e3499cae8e5323ac553ad56977bf1cd42b9a5a35Richard Smith if (CurrentToken) 388e3499cae8e5323ac553ad56977bf1cd42b9a5a35Richard Smith CurrentToken->Type = TT_OverloadedOperatorLParen; 389e3499cae8e5323ac553ad56977bf1cd42b9a5a35Richard Smith break; 3905764f613e61cb3183f3d7ceeafd23396de96ed16Douglas Gregor case tok::question: 391bbc6454bb98d6a6ecbaafa715222c5db834307f2Argyrios Kyrtzidis parseConditional(); 3923d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor break; 3933d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor case tok::kw_template: 3943d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor parseTemplateDeclaration(); 3956206d53f67613958ae1b023aba337ebb46f11a8bAbramo Bagnara break; 3966206d53f67613958ae1b023aba337ebb46f11a8bAbramo Bagnara case tok::identifier: 3976206d53f67613958ae1b023aba337ebb46f11a8bAbramo Bagnara if (Line.First.is(tok::kw_for) && 3986206d53f67613958ae1b023aba337ebb46f11a8bAbramo Bagnara Tok->FormatTok.Tok.getIdentifierInfo() == &Ident_in) 3996206d53f67613958ae1b023aba337ebb46f11a8bAbramo Bagnara Tok->Type = TT_ObjCForIn; 4006206d53f67613958ae1b023aba337ebb46f11a8bAbramo Bagnara break; 4016206d53f67613958ae1b023aba337ebb46f11a8bAbramo Bagnara default: 4026206d53f67613958ae1b023aba337ebb46f11a8bAbramo Bagnara break; 4038dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor } 4048dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor return true; 405a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall } 406561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor 407836adf6771d5170d936599dfcce21687e37e9bbfDouglas Gregor void parseIncludeDirective() { 40807fb6bef6242c0f2ab47f059583edbdef924823eJohn McCall next(); 40907fb6bef6242c0f2ab47f059583edbdef924823eJohn McCall if (CurrentToken != NULL && CurrentToken->is(tok::less)) { 41007fb6bef6242c0f2ab47f059583edbdef924823eJohn McCall next(); 411a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall while (CurrentToken != NULL) { 41207fb6bef6242c0f2ab47f059583edbdef924823eJohn McCall if (CurrentToken->isNot(tok::comment) || 41307fb6bef6242c0f2ab47f059583edbdef924823eJohn McCall !CurrentToken->Children.empty()) 4148dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor CurrentToken->Type = TT_ImplicitStringLiteral; 4158dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor next(); 4168dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor } 4178dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor } else { 4188dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor while (CurrentToken != NULL) { 4198dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor if (CurrentToken->is(tok::string_literal)) 4208dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor // Mark these string literals as "implicit" literals, too, so that 42107fb6bef6242c0f2ab47f059583edbdef924823eJohn McCall // they are not split or line-wrapped. 4228dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor CurrentToken->Type = TT_ImplicitStringLiteral; 4238dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor next(); 424b4eeaff1595b7d0a8fbc2b3c8bec7dc63f48b7fdDouglas Gregor } 425b4eeaff1595b7d0a8fbc2b3c8bec7dc63f48b7fdDouglas Gregor } 4268dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor } 4278dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor 4288dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor void parseWarningOrError() { 4298dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor next(); 4308dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor // We still want to format the whitespace left of the first token of the 4318dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor // warning or error. 432f6702a3927147655206ae729a84339c4fda4c651Richard Smith next(); 433f6702a3927147655206ae729a84339c4fda4c651Richard Smith while (CurrentToken != NULL) { 434f6702a3927147655206ae729a84339c4fda4c651Richard Smith CurrentToken->Type = TT_ImplicitStringLiteral; 4351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump next(); 43660d7b3a319d84d688752be3870615ac0f111fb16John McCall } 437ce3ff2bd3a3386dbc209d3cba4b8769173b274c1John McCall } 4388dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor 4398dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor void parsePreprocessorDirective() { 4408dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor next(); 4418dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor if (CurrentToken == NULL) 442e9146f2e9f1c4e281544e8c080934c72d41012caAnders Carlsson return; 4438dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor // Hashes in the middle of a line can lead to any strange token 4448dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor // sequence. 44507fb6bef6242c0f2ab47f059583edbdef924823eJohn McCall if (CurrentToken->FormatTok.Tok.getIdentifierInfo() == NULL) 44607fb6bef6242c0f2ab47f059583edbdef924823eJohn McCall return; 4471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump switch (CurrentToken->FormatTok.Tok.getIdentifierInfo()->getPPKeywordID()) { 4488dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor case tok::pp_include: 4498dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor case tok::pp_import: 4508dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor parseIncludeDirective(); 451ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith break; 452703b6015176550eefc91f3e2f19cd19beacbc592Richard Smith case tok::pp_error: 4538dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor case tok::pp_warning: 4548dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor parseWarningOrError(); 455663b5a0be7261c29bc4c526a71cffcfa02d4153eDouglas Gregor break; 456663b5a0be7261c29bc4c526a71cffcfa02d4153eDouglas Gregor default: 457f4b5f5c6a1487317aab9aa30d97bccfd57c82c98Anders Carlsson break; 458663b5a0be7261c29bc4c526a71cffcfa02d4153eDouglas Gregor } 4591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump while (CurrentToken != NULL) 46023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins next(); 461a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi } 462f4b5f5c6a1487317aab9aa30d97bccfd57c82c98Anders Carlsson 463f4b5f5c6a1487317aab9aa30d97bccfd57c82c98Anders Carlssonpublic: 4641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump LineType parseLine() { 465f4b5f5c6a1487317aab9aa30d97bccfd57c82c98Anders Carlsson int PeriodsAndArrows = 0; 466f4b5f5c6a1487317aab9aa30d97bccfd57c82c98Anders Carlsson bool CanBeBuilderTypeStmt = true; 467f4b5f5c6a1487317aab9aa30d97bccfd57c82c98Anders Carlsson if (CurrentToken->is(tok::hash)) { 468a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi parsePreprocessorDirective(); 4699901c57806f7e36736ed1616e6ab3eebcc99b78cDouglas Gregor return LT_PreprocessorDirective; 4709901c57806f7e36736ed1616e6ab3eebcc99b78cDouglas Gregor } 4717a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl while (CurrentToken != NULL) { 4729901c57806f7e36736ed1616e6ab3eebcc99b78cDouglas Gregor if (CurrentToken->is(tok::kw_virtual)) 4738dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor KeywordVirtualFound = true; 4741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (CurrentToken->is(tok::period) || CurrentToken->is(tok::arrow)) 475f4b5f5c6a1487317aab9aa30d97bccfd57c82c98Anders Carlsson ++PeriodsAndArrows; 47646460a68f6508775e98c19b4bb8454bb471aac24John McCall AnnotatedToken *TheToken = CurrentToken; 477f4b5f5c6a1487317aab9aa30d97bccfd57c82c98Anders Carlsson if (!consumeToken()) 4788dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor return LT_Invalid; 4798dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor if (getPrecedence(*TheToken) > prec::Assignment && 4808dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor TheToken->Type == TT_BinaryOperator) 4818dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor CanBeBuilderTypeStmt = false; 48287c2e121cf0522fc266efe2922b58091cd2e0182Francois Pichet } 48387c2e121cf0522fc266efe2922b58091cd2e0182Francois Pichet if (KeywordVirtualFound) 48487c2e121cf0522fc266efe2922b58091cd2e0182Francois Pichet return LT_VirtualFunctionDecl; 48587c2e121cf0522fc266efe2922b58091cd2e0182Francois Pichet 48687c2e121cf0522fc266efe2922b58091cd2e0182Francois Pichet // Assume a builder-type call if there are 2 or more "." and "->". 48787c2e121cf0522fc266efe2922b58091cd2e0182Francois Pichet if (PeriodsAndArrows >= 2 && CanBeBuilderTypeStmt) 48887c2e121cf0522fc266efe2922b58091cd2e0182Francois Pichet return LT_BuilderTypeCall; 489b710722d2348cd0945d2b4f02062c7f685146eb0Douglas Gregor 490a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi if (Line.First.Type == TT_ObjCMethodSpecifier) { 491b710722d2348cd0945d2b4f02062c7f685146eb0Douglas Gregor if (Contexts.back().FirstObjCSelectorName != NULL) 492b710722d2348cd0945d2b4f02062c7f685146eb0Douglas Gregor Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 493b710722d2348cd0945d2b4f02062c7f685146eb0Douglas Gregor Contexts.back().LongestObjCSelectorName; 494a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi return LT_ObjCMethodDecl; 495b710722d2348cd0945d2b4f02062c7f685146eb0Douglas Gregor } 496b710722d2348cd0945d2b4f02062c7f685146eb0Douglas Gregor 49787c2e121cf0522fc266efe2922b58091cd2e0182Francois Pichet return LT_Other; 49840e17752086c2c497951d64f5ac6ab5039466113Francois Pichet } 49987c2e121cf0522fc266efe2922b58091cd2e0182Francois Pichet 50087c2e121cf0522fc266efe2922b58091cd2e0182Francois Pichetprivate: 50140e17752086c2c497951d64f5ac6ab5039466113Francois Pichet void next() { 50287c2e121cf0522fc266efe2922b58091cd2e0182Francois Pichet if (CurrentToken != NULL) { 50387c2e121cf0522fc266efe2922b58091cd2e0182Francois Pichet determineTokenType(*CurrentToken); 50487c2e121cf0522fc266efe2922b58091cd2e0182Francois Pichet CurrentToken->BindingStrength = Contexts.back().BindingStrength; 50587c2e121cf0522fc266efe2922b58091cd2e0182Francois Pichet } 50687c2e121cf0522fc266efe2922b58091cd2e0182Francois Pichet 50787c2e121cf0522fc266efe2922b58091cd2e0182Francois Pichet if (CurrentToken != NULL && !CurrentToken->Children.empty()) 50887c2e121cf0522fc266efe2922b58091cd2e0182Francois Pichet CurrentToken = &CurrentToken->Children[0]; 50987c2e121cf0522fc266efe2922b58091cd2e0182Francois Pichet else 51087c2e121cf0522fc266efe2922b58091cd2e0182Francois Pichet CurrentToken = NULL; 51102cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall 51202cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall // Reset token type in case we have already looked at it and then recovered 51306245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas Gregor // from an error (e.g. failure to find the matching >). 51432f2fb53d9d7c28c94d8569fd0fcf06cccee0c3dJohn McCall if (CurrentToken != NULL) 5154fb86f8c4585e53c21c847ad3de9e3b2de123cd9Chandler Carruth CurrentToken->Type = TT_Unknown; 5164fb86f8c4585e53c21c847ad3de9e3b2de123cd9Chandler Carruth } 5174fb86f8c4585e53c21c847ad3de9e3b2de123cd9Chandler Carruth 5184fb86f8c4585e53c21c847ad3de9e3b2de123cd9Chandler Carruth /// \brief A struct to hold information valid in a specific context, e.g. 5194fb86f8c4585e53c21c847ad3de9e3b2de123cd9Chandler Carruth /// a pair of parenthesis. 5204fb86f8c4585e53c21c847ad3de9e3b2de123cd9Chandler Carruth struct Context { 5214fb86f8c4585e53c21c847ad3de9e3b2de123cd9Chandler Carruth Context(unsigned BindingStrength, bool IsExpression) 5224fb86f8c4585e53c21c847ad3de9e3b2de123cd9Chandler Carruth : BindingStrength(BindingStrength), LongestObjCSelectorName(0), 5234fb86f8c4585e53c21c847ad3de9e3b2de123cd9Chandler Carruth ColonIsForRangeExpr(false), ColonIsObjCMethodExpr(false), 5244fb86f8c4585e53c21c847ad3de9e3b2de123cd9Chandler Carruth FirstObjCSelectorName(NULL), IsExpression(IsExpression) {} 5254fb86f8c4585e53c21c847ad3de9e3b2de123cd9Chandler Carruth 5264fb86f8c4585e53c21c847ad3de9e3b2de123cd9Chandler Carruth unsigned BindingStrength; 52706245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas Gregor unsigned LongestObjCSelectorName; 528fd810b1386ed29b250e7d522ea826a65c815e49dJohn McCall bool ColonIsForRangeExpr; 529d6f80daa84164ceeb8900da07f43b6a150edf713Richard Smith bool ColonIsObjCMethodExpr; 5300216df8fd3ce58f5a68ef2ab141ea34c96c11164Abramo Bagnara AnnotatedToken *FirstObjCSelectorName; 53106245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas Gregor bool IsExpression; 53206245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas Gregor }; 533a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi 53406245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas Gregor /// \brief Puts a new \c Context onto the stack \c Contexts for the lifetime 5359a34edb710917798aa30263374f624f13b594605John McCall /// of each instance. 53606245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas Gregor struct ScopedContextCreator { 53706245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas Gregor AnnotatingParser &P; 538a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi 539a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi ScopedContextCreator(AnnotatingParser &P, unsigned Increase) : P(P) { 54006245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas Gregor P.Contexts.push_back(Context(P.Contexts.back().BindingStrength + Increase, 54106245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas Gregor P.Contexts.back().IsExpression)); 54232f2fb53d9d7c28c94d8569fd0fcf06cccee0c3dJohn McCall } 543af2094e7cecadf36667deb61a83587ffdd979bd3John McCall 544af2094e7cecadf36667deb61a83587ffdd979bd3John McCall ~ScopedContextCreator() { P.Contexts.pop_back(); } 545af2094e7cecadf36667deb61a83587ffdd979bd3John McCall }; 546af2094e7cecadf36667deb61a83587ffdd979bd3John McCall 547af2094e7cecadf36667deb61a83587ffdd979bd3John McCall void determineTokenType(AnnotatedToken &Current) { 54806245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas Gregor if (getPrecedence(Current) == prec::Assignment) { 5491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Contexts.back().IsExpression = true; 55002cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall for (AnnotatedToken *Previous = Current.Parent; 551a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi Previous && Previous->isNot(tok::comma); 55206245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas Gregor Previous = Previous->Parent) { 5535fee110ac106370f75592df024001de73edced2aJohn McCall if (Previous->Type == TT_BinaryOperator && 5549a34edb710917798aa30263374f624f13b594605John McCall (Previous->is(tok::star) || Previous->is(tok::amp))) { 55502cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall Previous->Type = TT_PointerOrReference; 55602cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall } 557fd810b1386ed29b250e7d522ea826a65c815e49dJohn McCall } 558fd810b1386ed29b250e7d522ea826a65c815e49dJohn McCall } else if (Current.is(tok::kw_return) || Current.is(tok::kw_throw) || 5598dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor (Current.is(tok::l_paren) && !Line.MustBeDeclaration && 5608dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor (!Current.Parent || Current.Parent->isNot(tok::kw_for)))) { 5611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Contexts.back().IsExpression = true; 562f6702a3927147655206ae729a84339c4fda4c651Richard Smith } else if (Current.is(tok::r_paren) || Current.is(tok::greater) || 563f6702a3927147655206ae729a84339c4fda4c651Richard Smith Current.is(tok::comma)) { 564f6702a3927147655206ae729a84339c4fda4c651Richard Smith for (AnnotatedToken *Previous = Current.Parent; 5651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Previous && (Previous->is(tok::star) || Previous->is(tok::amp)); 56660d7b3a319d84d688752be3870615ac0f111fb16John McCall Previous = Previous->Parent) 567ce3ff2bd3a3386dbc209d3cba4b8769173b274c1John McCall Previous->Type = TT_PointerOrReference; 5688dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor } else if (Current.Parent && 5698dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor Current.Parent->Type == TT_CtorInitializerColon) { 5708dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor Contexts.back().IsExpression = true; 571e3f470a718ec00eb8b546e405fa59bc2df2d7c46Richard Smith } 5729ae2f076ca5ab1feb3ba95629099ec2319833701John McCall 573e3f470a718ec00eb8b546e405fa59bc2df2d7c46Richard Smith if (Current.Type == TT_Unknown) { 574e3f470a718ec00eb8b546e405fa59bc2df2d7c46Richard Smith if (Current.Parent && Current.is(tok::identifier) && 575e3f470a718ec00eb8b546e405fa59bc2df2d7c46Richard Smith ((Current.Parent->is(tok::identifier) && 5768dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor Current.Parent->FormatTok.Tok.getIdentifierInfo() 5778dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor ->getPPKeywordID() == tok::pp_not_keyword) || 5788dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor Current.Parent->Type == TT_PointerOrReference || 57938f0df352fadc546c5666079fb22de5ec1819d92Richard Smith Current.Parent->Type == TT_TemplateCloser)) { 58038f0df352fadc546c5666079fb22de5ec1819d92Richard Smith Current.Type = TT_StartOfName; 58138f0df352fadc546c5666079fb22de5ec1819d92Richard Smith } else if (Current.is(tok::star) || Current.is(tok::amp)) { 58238f0df352fadc546c5666079fb22de5ec1819d92Richard Smith Current.Type = 58338f0df352fadc546c5666079fb22de5ec1819d92Richard Smith determineStarAmpUsage(Current, Contexts.back().IsExpression); 58438f0df352fadc546c5666079fb22de5ec1819d92Richard Smith } else if (Current.is(tok::minus) || Current.is(tok::plus) || 58538f0df352fadc546c5666079fb22de5ec1819d92Richard Smith Current.is(tok::caret)) { 58638f0df352fadc546c5666079fb22de5ec1819d92Richard Smith Current.Type = determinePlusMinusCaretUsage(Current); 58738f0df352fadc546c5666079fb22de5ec1819d92Richard Smith } else if (Current.is(tok::minusminus) || Current.is(tok::plusplus)) { 588ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara Current.Type = determineIncrementUsage(Current); 5898dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor } else if (Current.is(tok::exclaim)) { 59038f0df352fadc546c5666079fb22de5ec1819d92Richard Smith Current.Type = TT_UnaryOperator; 591a88cefd266c428be33cc06f7e8b00ff8fc97c1ffAbramo Bagnara } else if (isBinaryOperator(Current)) { 5921274ccd90aec0b205fc838c3d504821ccfb55482Douglas Gregor Current.Type = TT_BinaryOperator; 593f1c66b40213784a1c4612f04c14cafa2b0e89988Richard Smith } else if (Current.is(tok::comment)) { 5941274ccd90aec0b205fc838c3d504821ccfb55482Douglas Gregor std::string Data(Lexer::getSpelling(Current.FormatTok.Tok, SourceMgr, 5951274ccd90aec0b205fc838c3d504821ccfb55482Douglas Gregor Lex.getLangOpts())); 5961274ccd90aec0b205fc838c3d504821ccfb55482Douglas Gregor if (StringRef(Data).startswith("//")) 5971274ccd90aec0b205fc838c3d504821ccfb55482Douglas Gregor Current.Type = TT_LineComment; 598f1c66b40213784a1c4612f04c14cafa2b0e89988Richard Smith else 599f1c66b40213784a1c4612f04c14cafa2b0e89988Richard Smith Current.Type = TT_BlockComment; 600f1c66b40213784a1c4612f04c14cafa2b0e89988Richard Smith } else if (Current.is(tok::r_paren)) { 6011274ccd90aec0b205fc838c3d504821ccfb55482Douglas Gregor bool ParensNotExpr = !Current.Parent || 602f1c66b40213784a1c4612f04c14cafa2b0e89988Richard Smith Current.Parent->Type == TT_PointerOrReference || 603f1c66b40213784a1c4612f04c14cafa2b0e89988Richard Smith Current.Parent->Type == TT_TemplateCloser; 604f1c66b40213784a1c4612f04c14cafa2b0e89988Richard Smith bool ParensCouldEndDecl = 6051274ccd90aec0b205fc838c3d504821ccfb55482Douglas Gregor !Current.Children.empty() && (Current.Children[0].is(tok::equal) || 6061274ccd90aec0b205fc838c3d504821ccfb55482Douglas Gregor Current.Children[0].is(tok::semi) || 6071274ccd90aec0b205fc838c3d504821ccfb55482Douglas Gregor Current.Children[0].is(tok::l_brace)); 6081274ccd90aec0b205fc838c3d504821ccfb55482Douglas Gregor if (ParensNotExpr && !ParensCouldEndDecl && 6091274ccd90aec0b205fc838c3d504821ccfb55482Douglas Gregor Contexts.back().IsExpression) 6101274ccd90aec0b205fc838c3d504821ccfb55482Douglas Gregor // FIXME: We need to get smarter and understand more cases of casts. 6115b629aa86c987f276d00453b6c9ab8424f7903feJohn McCall Current.Type = TT_CastRParen; 6125b629aa86c987f276d00453b6c9ab8424f7903feJohn McCall } else if (Current.is(tok::at) && Current.Children.size()) { 613f1c66b40213784a1c4612f04c14cafa2b0e89988Richard Smith switch (Current.Children[0].FormatTok.Tok.getObjCKeywordID()) { 61406c0fecd197fef21e265a41bca8dc5022de1f864Douglas Gregor case tok::objc_interface: 615b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall case tok::objc_implementation: 61617945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis case tok::objc_protocol: 617f1c66b40213784a1c4612f04c14cafa2b0e89988Richard Smith Current.Type = TT_ObjCDecl; 6184ca93d9978aac02b01814b4f749d6903a1f87ee5Richard Smith break; 6194ca93d9978aac02b01814b4f749d6903a1f87ee5Richard Smith case tok::objc_property: 6204ca93d9978aac02b01814b4f749d6903a1f87ee5Richard Smith Current.Type = TT_ObjCProperty; 6214ca93d9978aac02b01814b4f749d6903a1f87ee5Richard Smith break; 6224ca93d9978aac02b01814b4f749d6903a1f87ee5Richard Smith default: 6234ca93d9978aac02b01814b4f749d6903a1f87ee5Richard Smith break; 6244ca93d9978aac02b01814b4f749d6903a1f87ee5Richard Smith } 6254ca93d9978aac02b01814b4f749d6903a1f87ee5Richard Smith } 6264ca93d9978aac02b01814b4f749d6903a1f87ee5Richard Smith } 6274ca93d9978aac02b01814b4f749d6903a1f87ee5Richard Smith } 6284ca93d9978aac02b01814b4f749d6903a1f87ee5Richard Smith 6294ca93d9978aac02b01814b4f749d6903a1f87ee5Richard Smith /// \brief Return the type of the given token assuming it is * or &. 6304ca93d9978aac02b01814b4f749d6903a1f87ee5Richard Smith TokenType 6314ca93d9978aac02b01814b4f749d6903a1f87ee5Richard Smith determineStarAmpUsage(const AnnotatedToken &Tok, bool IsExpression) { 6328dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor const AnnotatedToken *PrevToken = getPreviousToken(Tok); 63396084f171f4824397dc48453146f0a9719cb9247Douglas Gregor if (PrevToken == NULL) 63496084f171f4824397dc48453146f0a9719cb9247Douglas Gregor return TT_UnaryOperator; 635a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi 636f1c66b40213784a1c4612f04c14cafa2b0e89988Richard Smith const AnnotatedToken *NextToken = getNextToken(Tok); 637f1c66b40213784a1c4612f04c14cafa2b0e89988Richard Smith if (NextToken == NULL) 638f1c66b40213784a1c4612f04c14cafa2b0e89988Richard Smith return TT_Unknown; 639f1c66b40213784a1c4612f04c14cafa2b0e89988Richard Smith 64038f0df352fadc546c5666079fb22de5ec1819d92Richard Smith if (PrevToken->is(tok::l_paren) || PrevToken->is(tok::l_square) || 64138f0df352fadc546c5666079fb22de5ec1819d92Richard Smith PrevToken->is(tok::l_brace) || PrevToken->is(tok::comma) || 64238f0df352fadc546c5666079fb22de5ec1819d92Richard Smith PrevToken->is(tok::kw_return) || PrevToken->is(tok::colon) || 64338f0df352fadc546c5666079fb22de5ec1819d92Richard Smith PrevToken->is(tok::equal) || PrevToken->Type == TT_BinaryOperator || 64438f0df352fadc546c5666079fb22de5ec1819d92Richard Smith PrevToken->Type == TT_UnaryOperator || PrevToken->Type == TT_CastRParen) 6454ca93d9978aac02b01814b4f749d6903a1f87ee5Richard Smith return TT_UnaryOperator; 646f1c66b40213784a1c4612f04c14cafa2b0e89988Richard Smith 647f1c66b40213784a1c4612f04c14cafa2b0e89988Richard Smith if (NextToken->is(tok::l_square)) 648f1c66b40213784a1c4612f04c14cafa2b0e89988Richard Smith return TT_PointerOrReference; 649f1c66b40213784a1c4612f04c14cafa2b0e89988Richard Smith 650f1c66b40213784a1c4612f04c14cafa2b0e89988Richard Smith if (PrevToken->FormatTok.Tok.isLiteral() || PrevToken->is(tok::r_paren) || 651f1c66b40213784a1c4612f04c14cafa2b0e89988Richard Smith PrevToken->is(tok::r_square) || NextToken->FormatTok.Tok.isLiteral() || 652f1c66b40213784a1c4612f04c14cafa2b0e89988Richard Smith isUnaryOperator(*NextToken) || NextToken->is(tok::l_paren) || 653f1c66b40213784a1c4612f04c14cafa2b0e89988Richard Smith NextToken->is(tok::l_square)) 6541af83c444e5a2f6f50a6e1c15e6ebc618ae18a5fRichard Smith return TT_BinaryOperator; 6551af83c444e5a2f6f50a6e1c15e6ebc618ae18a5fRichard Smith 6561af83c444e5a2f6f50a6e1c15e6ebc618ae18a5fRichard Smith // It is very unlikely that we are going to find a pointer or reference type 6575f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner // definition on the RHS of an assignment. 6588dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor if (IsExpression) 6598dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor return TT_BinaryOperator; 660f1c66b40213784a1c4612f04c14cafa2b0e89988Richard Smith 661f1c66b40213784a1c4612f04c14cafa2b0e89988Richard Smith return TT_PointerOrReference; 6628dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor } 6638dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor 66460d7b3a319d84d688752be3870615ac0f111fb16John McCall TokenType determinePlusMinusCaretUsage(const AnnotatedToken &Tok) { 665ac7610dad6653bad02dd42de198ca358b6fb1f1dDouglas Gregor const AnnotatedToken *PrevToken = getPreviousToken(Tok); 666f6702a3927147655206ae729a84339c4fda4c651Richard Smith if (PrevToken == NULL) 6671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return TT_UnaryOperator; 668f6702a3927147655206ae729a84339c4fda4c651Richard Smith 6691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Use heuristics to recognize unary operators. 670ce3ff2bd3a3386dbc209d3cba4b8769173b274c1John McCall if (PrevToken->is(tok::equal) || PrevToken->is(tok::l_paren) || 671ac7610dad6653bad02dd42de198ca358b6fb1f1dDouglas Gregor PrevToken->is(tok::comma) || PrevToken->is(tok::l_square) || 6728dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor PrevToken->is(tok::question) || PrevToken->is(tok::colon) || 6738dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor PrevToken->is(tok::kw_return) || PrevToken->is(tok::kw_case) || 6748dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor PrevToken->is(tok::at) || PrevToken->is(tok::l_brace)) 6758dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor return TT_UnaryOperator; 6768dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor 6778dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor // There can't be two consecutive binary operators. 6788dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor if (PrevToken->Type == TT_BinaryOperator) 6798dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor return TT_UnaryOperator; 6801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6818dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor // Fall back to marking the token as binary operator. 6828dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor return TT_BinaryOperator; 6839ae2f076ca5ab1feb3ba95629099ec2319833701John McCall } 6848dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor 6858dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor /// \brief Determine whether ++/-- are pre- or post-increments/-decrements. 6868dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor TokenType determineIncrementUsage(const AnnotatedToken &Tok) { 6878dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor const AnnotatedToken *PrevToken = getPreviousToken(Tok); 6888dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor if (PrevToken == NULL) 6898dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor return TT_UnaryOperator; 6908dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor if (PrevToken->is(tok::r_paren) || PrevToken->is(tok::r_square) || 6918dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor PrevToken->is(tok::identifier)) 692581deb3da481053c4993c7600f97acf7768caac5David Blaikie return TT_TrailingUnaryOperator; 6935b629aa86c987f276d00453b6c9ab8424f7903feJohn McCall 6943b85ecf2049c8670eba30d0c06f28f64168af9b8John McCall return TT_UnaryOperator; 69517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis } 696d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall 6978dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor SmallVector<Context, 8> Contexts; 698a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi 699f1c66b40213784a1c4612f04c14cafa2b0e89988Richard Smith SourceManager &SourceMgr; 700f1c66b40213784a1c4612f04c14cafa2b0e89988Richard Smith Lexer &Lex; 70196084f171f4824397dc48453146f0a9719cb9247Douglas Gregor AnnotatedLine &Line; 70296084f171f4824397dc48453146f0a9719cb9247Douglas Gregor AnnotatedToken *CurrentToken; 703581deb3da481053c4993c7600f97acf7768caac5David Blaikie bool KeywordVirtualFound; 70496084f171f4824397dc48453146f0a9719cb9247Douglas Gregor IdentifierInfo &Ident_in; 7058dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor}; 7068dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor 7071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// \brief Parses binary expressions by inserting fake parenthesis based on 708f1c66b40213784a1c4612f04c14cafa2b0e89988Richard Smith/// operator precedence. 709f1c66b40213784a1c4612f04c14cafa2b0e89988Richard Smithclass ExpressionParser { 710f1c66b40213784a1c4612f04c14cafa2b0e89988Richard Smithpublic: 711de7a0fcdf9f30cb5a97aab614f3975d93cd9926fEli Friedman ExpressionParser(AnnotatedLine &Line) : Current(&Line.First) {} 712fee13819693c8492f0c364bc704645e844ef737aEdward O'Callaghan 7138dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor /// \brief Parse expressions with the given operatore precedence. 7148dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor void parse(int Precedence = 0) { 7156477b69cc93e0a0ff15036d60d604f3544da0f29Douglas Gregor if (Precedence > prec::PointerToMember || Current == NULL) 716b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie return; 7176477b69cc93e0a0ff15036d60d604f3544da0f29Douglas Gregor 7186477b69cc93e0a0ff15036d60d604f3544da0f29Douglas Gregor // Skip over "return" until we can properly parse it. 719e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall if (Current->is(tok::kw_return)) 72093ba8579c341d5329175f1413cdc3b35a36592d2John McCall next(); 72193ba8579c341d5329175f1413cdc3b35a36592d2John McCall 722550d9b28fd586db541eb6dd36f3c10d114e483d8Douglas Gregor // Eagerly consume trailing comments. 723550d9b28fd586db541eb6dd36f3c10d114e483d8Douglas Gregor while (isTrailingComment(Current)) { 7242a7fb27913999d132cf9e10e03dc5271faa2e9d3John McCall next(); 725e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall } 726ce3ff2bd3a3386dbc209d3cba4b8769173b274c1John McCall 7271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump AnnotatedToken *Start = Current; 728d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor bool OperatorFound = false; 729e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall 730e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall while (Current) { 73193ba8579c341d5329175f1413cdc3b35a36592d2John McCall // Consume operators with higher precedence. 73293ba8579c341d5329175f1413cdc3b35a36592d2John McCall parse(prec::Level(Precedence + 1)); 73393ba8579c341d5329175f1413cdc3b35a36592d2John McCall 73493ba8579c341d5329175f1413cdc3b35a36592d2John McCall int CurrentPrecedence = 0; 735c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor if (Current) { 736c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor if (Current->Type == TT_ConditionalExpr) 737c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor CurrentPrecedence = 1 + (int) prec::Conditional; 738c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor else if (Current->is(tok::semi)) 739c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor CurrentPrecedence = 1; 740c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor else if (Current->Type == TT_BinaryOperator || Current->is(tok::comma)) 74193ba8579c341d5329175f1413cdc3b35a36592d2John McCall CurrentPrecedence = 1 + (int) getPrecedence(*Current); 74293ba8579c341d5329175f1413cdc3b35a36592d2John McCall } 74393ba8579c341d5329175f1413cdc3b35a36592d2John McCall 74493ba8579c341d5329175f1413cdc3b35a36592d2John McCall // At the end of the line or when an operator with higher precedence is 74593ba8579c341d5329175f1413cdc3b35a36592d2John McCall // found, insert fake parenthesis and return. 746ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor if (Current == NULL || closesScope(*Current) || 74737574f55cd637340f651330f5cfda69742880d36Nick Lewycky (CurrentPrecedence != 0 && CurrentPrecedence < Precedence)) { 74837574f55cd637340f651330f5cfda69742880d36Nick Lewycky if (OperatorFound) { 74937574f55cd637340f651330f5cfda69742880d36Nick Lewycky ++Start->FakeLParens; 75037574f55cd637340f651330f5cfda69742880d36Nick Lewycky if (Current) 75137574f55cd637340f651330f5cfda69742880d36Nick Lewycky ++Current->Parent->FakeRParens; 75237574f55cd637340f651330f5cfda69742880d36Nick Lewycky } 75337574f55cd637340f651330f5cfda69742880d36Nick Lewycky return; 75437574f55cd637340f651330f5cfda69742880d36Nick Lewycky } 75593ba8579c341d5329175f1413cdc3b35a36592d2John McCall 75693ba8579c341d5329175f1413cdc3b35a36592d2John McCall // Consume scopes: (), [], <> and {} 75793ba8579c341d5329175f1413cdc3b35a36592d2John McCall if (opensScope(*Current)) { 75893ba8579c341d5329175f1413cdc3b35a36592d2John McCall AnnotatedToken *Left = Current; 75993ba8579c341d5329175f1413cdc3b35a36592d2John McCall while (Current && !closesScope(*Current)) { 76093ba8579c341d5329175f1413cdc3b35a36592d2John McCall next(); 761c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor parse(); 76293ba8579c341d5329175f1413cdc3b35a36592d2John McCall } 763c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor // Remove fake parens that just duplicate the real parens. 76493ba8579c341d5329175f1413cdc3b35a36592d2John McCall if (Current && Left->Children[0].FakeLParens > 0 && 76593ba8579c341d5329175f1413cdc3b35a36592d2John McCall Current->Parent->FakeRParens > 0) { 76693ba8579c341d5329175f1413cdc3b35a36592d2John McCall --Left->Children[0].FakeLParens; 76793ba8579c341d5329175f1413cdc3b35a36592d2John McCall --Current->Parent->FakeRParens; 76893ba8579c341d5329175f1413cdc3b35a36592d2John McCall } 76993ba8579c341d5329175f1413cdc3b35a36592d2John McCall next(); 77093ba8579c341d5329175f1413cdc3b35a36592d2John McCall } else { 77193ba8579c341d5329175f1413cdc3b35a36592d2John McCall // Operator found. 77293ba8579c341d5329175f1413cdc3b35a36592d2John McCall if (CurrentPrecedence == Precedence) 77393ba8579c341d5329175f1413cdc3b35a36592d2John McCall OperatorFound = true; 77493ba8579c341d5329175f1413cdc3b35a36592d2John McCall 77593ba8579c341d5329175f1413cdc3b35a36592d2John McCall next(); 77693ba8579c341d5329175f1413cdc3b35a36592d2John McCall } 77793ba8579c341d5329175f1413cdc3b35a36592d2John McCall } 77893ba8579c341d5329175f1413cdc3b35a36592d2John McCall } 77993ba8579c341d5329175f1413cdc3b35a36592d2John McCall 78093ba8579c341d5329175f1413cdc3b35a36592d2John McCallprivate: 78193ba8579c341d5329175f1413cdc3b35a36592d2John McCall void next() { 78293ba8579c341d5329175f1413cdc3b35a36592d2John McCall if (Current != NULL) 78393ba8579c341d5329175f1413cdc3b35a36592d2John McCall Current = Current->Children.empty() ? NULL : &Current->Children[0]; 784c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor } 78593ba8579c341d5329175f1413cdc3b35a36592d2John McCall 7861eabb7d0c30f6a876b0fd03ad4656c096c26b8d0Douglas Gregor bool closesScope(const AnnotatedToken &Tok) { 787c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor return Current->is(tok::r_paren) || Current->Type == TT_TemplateCloser || 78893ba8579c341d5329175f1413cdc3b35a36592d2John McCall Current->is(tok::r_brace) || Current->is(tok::r_square); 78993ba8579c341d5329175f1413cdc3b35a36592d2John McCall } 79093ba8579c341d5329175f1413cdc3b35a36592d2John McCall 791c53d0d762010217d02da5aa14be171817d63e3feDouglas Gregor bool opensScope(const AnnotatedToken &Tok) { 79293ba8579c341d5329175f1413cdc3b35a36592d2John McCall return Current->is(tok::l_paren) || Current->Type == TT_TemplateOpener || 793c53d0d762010217d02da5aa14be171817d63e3feDouglas Gregor Current->is(tok::l_brace) || Current->is(tok::l_square); 794c53d0d762010217d02da5aa14be171817d63e3feDouglas Gregor } 795c53d0d762010217d02da5aa14be171817d63e3feDouglas Gregor 796c53d0d762010217d02da5aa14be171817d63e3feDouglas Gregor AnnotatedToken *Current; 797c53d0d762010217d02da5aa14be171817d63e3feDouglas Gregor}; 798c53d0d762010217d02da5aa14be171817d63e3feDouglas Gregor 799c53d0d762010217d02da5aa14be171817d63e3feDouglas Gregorvoid TokenAnnotator::annotate(AnnotatedLine &Line) { 800c53d0d762010217d02da5aa14be171817d63e3feDouglas Gregor AnnotatingParser Parser(SourceMgr, Lex, Line, Ident_in); 801a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi Line.Type = Parser.parseLine(); 802c53d0d762010217d02da5aa14be171817d63e3feDouglas Gregor if (Line.Type == LT_Invalid) 803c53d0d762010217d02da5aa14be171817d63e3feDouglas Gregor return; 804c53d0d762010217d02da5aa14be171817d63e3feDouglas Gregor 805c53d0d762010217d02da5aa14be171817d63e3feDouglas Gregor ExpressionParser ExprParser(Line); 806c53d0d762010217d02da5aa14be171817d63e3feDouglas Gregor ExprParser.parse(); 807c53d0d762010217d02da5aa14be171817d63e3feDouglas Gregor 808c53d0d762010217d02da5aa14be171817d63e3feDouglas Gregor if (Line.First.Type == TT_ObjCMethodSpecifier) 809c53d0d762010217d02da5aa14be171817d63e3feDouglas Gregor Line.Type = LT_ObjCMethodDecl; 810c53d0d762010217d02da5aa14be171817d63e3feDouglas Gregor else if (Line.First.Type == TT_ObjCDecl) 811c53d0d762010217d02da5aa14be171817d63e3feDouglas Gregor Line.Type = LT_ObjCDecl; 812c53d0d762010217d02da5aa14be171817d63e3feDouglas Gregor else if (Line.First.Type == TT_ObjCProperty) 813c53d0d762010217d02da5aa14be171817d63e3feDouglas Gregor Line.Type = LT_ObjCProperty; 814c53d0d762010217d02da5aa14be171817d63e3feDouglas Gregor 815c53d0d762010217d02da5aa14be171817d63e3feDouglas Gregor Line.First.SpacesRequiredBefore = 1; 816c53d0d762010217d02da5aa14be171817d63e3feDouglas Gregor Line.First.MustBreakBefore = Line.First.FormatTok.MustBreakBefore; 817c53d0d762010217d02da5aa14be171817d63e3feDouglas Gregor Line.First.CanBreakBefore = Line.First.MustBreakBefore; 818c53d0d762010217d02da5aa14be171817d63e3feDouglas Gregor 81993ba8579c341d5329175f1413cdc3b35a36592d2John McCall Line.First.TotalLength = Line.First.FormatTok.TokenLength; 82093ba8579c341d5329175f1413cdc3b35a36592d2John McCall} 82193ba8579c341d5329175f1413cdc3b35a36592d2John McCall 82293ba8579c341d5329175f1413cdc3b35a36592d2John McCallvoid TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) { 82393ba8579c341d5329175f1413cdc3b35a36592d2John McCall if (Line.First.Children.empty()) 824a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi return; 825c53d0d762010217d02da5aa14be171817d63e3feDouglas Gregor AnnotatedToken *Current = &Line.First.Children[0]; 826c53d0d762010217d02da5aa14be171817d63e3feDouglas Gregor while (Current != NULL) { 827c53d0d762010217d02da5aa14be171817d63e3feDouglas Gregor if (Current->Type == TT_LineComment) 828c53d0d762010217d02da5aa14be171817d63e3feDouglas Gregor Current->SpacesRequiredBefore = Style.SpacesBeforeTrailingComments; 829c53d0d762010217d02da5aa14be171817d63e3feDouglas Gregor else 830c53d0d762010217d02da5aa14be171817d63e3feDouglas Gregor Current->SpacesRequiredBefore = 831c53d0d762010217d02da5aa14be171817d63e3feDouglas Gregor spaceRequiredBefore(Line, *Current) ? 1 : 0; 83293ba8579c341d5329175f1413cdc3b35a36592d2John McCall 83393ba8579c341d5329175f1413cdc3b35a36592d2John McCall if (Current->FormatTok.MustBreakBefore) { 83493ba8579c341d5329175f1413cdc3b35a36592d2John McCall Current->MustBreakBefore = true; 835c53d0d762010217d02da5aa14be171817d63e3feDouglas Gregor } else if (Current->Type == TT_LineComment) { 836c53d0d762010217d02da5aa14be171817d63e3feDouglas Gregor Current->MustBreakBefore = Current->FormatTok.NewlinesBefore > 0; 83793ba8579c341d5329175f1413cdc3b35a36592d2John McCall } else if (isTrailingComment(Current->Parent) || 83893ba8579c341d5329175f1413cdc3b35a36592d2John McCall (Current->is(tok::string_literal) && 83993ba8579c341d5329175f1413cdc3b35a36592d2John McCall Current->Parent->is(tok::string_literal))) { 84093ba8579c341d5329175f1413cdc3b35a36592d2John McCall Current->MustBreakBefore = true; 84193ba8579c341d5329175f1413cdc3b35a36592d2John McCall } else if (Current->is(tok::lessless) && !Current->Children.empty() && 842e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall Current->Parent->is(tok::string_literal) && 84393ba8579c341d5329175f1413cdc3b35a36592d2John McCall Current->Children[0].is(tok::string_literal)) { 844ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara Current->MustBreakBefore = true; 845ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara } else { 846f0510d49a6985e9284d30cfc36a0df2a6292a638Douglas Gregor Current->MustBreakBefore = false; 847e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall } 848c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor Current->CanBreakBefore = 849c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor Current->MustBreakBefore || canBreakBefore(Line, *Current); 850b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall if (Current->MustBreakBefore) 851e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall Current->TotalLength = Current->Parent->TotalLength + Style.ColumnLimit; 85293ba8579c341d5329175f1413cdc3b35a36592d2John McCall else 85393ba8579c341d5329175f1413cdc3b35a36592d2John McCall Current->TotalLength = 85493ba8579c341d5329175f1413cdc3b35a36592d2John McCall Current->Parent->TotalLength + Current->FormatTok.TokenLength + 855e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall Current->SpacesRequiredBefore; 856ea7390c7b384ce607bfc8fc13c01f37cfc3776f0John McCall // FIXME: Only calculate this if CanBreakBefore is true once static 85793ba8579c341d5329175f1413cdc3b35a36592d2John McCall // initializers etc. are sorted out. 858ea7390c7b384ce607bfc8fc13c01f37cfc3776f0John McCall // FIXME: Move magic numbers to a better place. 859ea7390c7b384ce607bfc8fc13c01f37cfc3776f0John McCall Current->SplitPenalty = 860ea7390c7b384ce607bfc8fc13c01f37cfc3776f0John McCall 20 * Current->BindingStrength + splitPenalty(Line, *Current); 861ea7390c7b384ce607bfc8fc13c01f37cfc3776f0John McCall 862ea7390c7b384ce607bfc8fc13c01f37cfc3776f0John McCall Current = Current->Children.empty() ? NULL : &Current->Children[0]; 86393ba8579c341d5329175f1413cdc3b35a36592d2John McCall } 86493ba8579c341d5329175f1413cdc3b35a36592d2John McCall} 86593ba8579c341d5329175f1413cdc3b35a36592d2John McCall 86693ba8579c341d5329175f1413cdc3b35a36592d2John McCallunsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line, 867e8c01bdb56549adcecd71ce39160eea54b2c51c8Douglas Gregor const AnnotatedToken &Tok) { 86837574f55cd637340f651330f5cfda69742880d36Nick Lewycky const AnnotatedToken &Left = *Tok.Parent; 86937574f55cd637340f651330f5cfda69742880d36Nick Lewycky const AnnotatedToken &Right = Tok; 87093ba8579c341d5329175f1413cdc3b35a36592d2John McCall 871a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi if (Right.Type == TT_StartOfName) { 872f0510d49a6985e9284d30cfc36a0df2a6292a638Douglas Gregor if (Line.First.is(tok::kw_for)) 8733cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall return 3; 87424bae92f08ae098cc50a602d8cf1273b423e14daDouglas Gregor else if (Line.MightBeFunctionDecl && Right.BindingStrength == 1) 875ea7390c7b384ce607bfc8fc13c01f37cfc3776f0John McCall // FIXME: Clean up hack of using BindingStrength to find top-level names. 876259571e27e513cfaf691cc7447e09b31a47d5438Douglas Gregor return Style.PenaltyReturnTypeOnItsOwnLine; 87793ba8579c341d5329175f1413cdc3b35a36592d2John McCall else 8781b7f9cbed1b96b58a6e5f7808ebc9345a76a0936Richard Smith return 100; 8794c51548271d2f8385127e1d943764ae8939d7794Abramo Bagnara } 8804c51548271d2f8385127e1d943764ae8939d7794Abramo Bagnara if (Left.is(tok::l_brace) && Right.isNot(tok::l_brace)) 881e8c01bdb56549adcecd71ce39160eea54b2c51c8Douglas Gregor return 50; 882259571e27e513cfaf691cc7447e09b31a47d5438Douglas Gregor if (Left.is(tok::equal) && Right.is(tok::l_brace)) 883a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi return 150; 8844c51548271d2f8385127e1d943764ae8939d7794Abramo Bagnara if (Left.is(tok::coloncolon)) 8854c51548271d2f8385127e1d943764ae8939d7794Abramo Bagnara return 500; 8864c51548271d2f8385127e1d943764ae8939d7794Abramo Bagnara 8874c51548271d2f8385127e1d943764ae8939d7794Abramo Bagnara if (Left.Type == TT_RangeBasedForLoopColon || 8884c51548271d2f8385127e1d943764ae8939d7794Abramo Bagnara Left.Type == TT_InheritanceColon) 889e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall return 2; 890d65587f7a6d38965fa37158d3f57990a7faf3836Douglas Gregor 891d65587f7a6d38965fa37158d3f57990a7faf3836Douglas Gregor if (Right.is(tok::arrow) || Right.is(tok::period)) { 892d65587f7a6d38965fa37158d3f57990a7faf3836Douglas Gregor if (Line.Type == LT_BuilderTypeCall) 893d65587f7a6d38965fa37158d3f57990a7faf3836Douglas Gregor return 5; // Should be smaller than breaking at a nested comma. 894d65587f7a6d38965fa37158d3f57990a7faf3836Douglas Gregor if ((Left.is(tok::r_paren) || Left.is(tok::r_square)) && 8955f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner Left.MatchingParen && Left.MatchingParen->ParameterCount > 0) 896d65587f7a6d38965fa37158d3f57990a7faf3836Douglas Gregor return 10; 897d65587f7a6d38965fa37158d3f57990a7faf3836Douglas Gregor return 150; 898d65587f7a6d38965fa37158d3f57990a7faf3836Douglas Gregor } 899d65587f7a6d38965fa37158d3f57990a7faf3836Douglas Gregor 900d65587f7a6d38965fa37158d3f57990a7faf3836Douglas Gregor // In for-loops, prefer breaking at ',' and ';'. 901d65587f7a6d38965fa37158d3f57990a7faf3836Douglas Gregor if (Line.First.is(tok::kw_for) && Left.is(tok::equal)) 902e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall return 4; 903e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall 904e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall if (Left.is(tok::semi)) 905d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor return 0; 9067974c3b7062f85bb7c0ada34526cdefe1d30f89bDouglas Gregor if (Left.is(tok::comma)) 9077974c3b7062f85bb7c0ada34526cdefe1d30f89bDouglas Gregor return 1; 908ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor 909a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi // In Objective-C method expressions, prefer breaking before "param:" over 910ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor // breaking after it. 911ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor if (Right.Type == TT_ObjCSelectorName) 912ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor return 0; 913ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor if (Left.is(tok::colon) && Left.Type == TT_ObjCMethodExpr) 914ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor return 20; 915ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor 916a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi if (Left.is(tok::l_paren) || Left.is(tok::l_square) || 917ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor Left.Type == TT_TemplateOpener) 918ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor return 20; 919ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor 920ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor if (Right.is(tok::lessless)) { 921a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi if (Left.is(tok::string_literal)) { 922d65587f7a6d38965fa37158d3f57990a7faf3836Douglas Gregor char LastChar = 923d65587f7a6d38965fa37158d3f57990a7faf3836Douglas Gregor StringRef(Left.FormatTok.Tok.getLiteralData(), 924d65587f7a6d38965fa37158d3f57990a7faf3836Douglas Gregor Left.FormatTok.TokenLength).drop_back(1).rtrim().back(); 925d65587f7a6d38965fa37158d3f57990a7faf3836Douglas Gregor if (LastChar == ':' || LastChar == '=') 926d65587f7a6d38965fa37158d3f57990a7faf3836Douglas Gregor return 100; 9277974c3b7062f85bb7c0ada34526cdefe1d30f89bDouglas Gregor } 9287974c3b7062f85bb7c0ada34526cdefe1d30f89bDouglas Gregor return prec::Shift; 9297974c3b7062f85bb7c0ada34526cdefe1d30f89bDouglas Gregor } 930d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor if (Left.Type == TT_ConditionalExpr) 931550d9b28fd586db541eb6dd36f3c10d114e483d8Douglas Gregor return prec::Assignment; 932550d9b28fd586db541eb6dd36f3c10d114e483d8Douglas Gregor prec::Level Level = getPrecedence(Left); 933a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi 934550d9b28fd586db541eb6dd36f3c10d114e483d8Douglas Gregor if (Level != prec::Unknown) 9352a7fb27913999d132cf9e10e03dc5271faa2e9d3John McCall return Level; 936895162da2d52f4243f61081d7436de66af4503fcDouglas Gregor 937d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor return 3; 938d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor} 9391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 940d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregorbool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, 941a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi const AnnotatedToken &Left, 942a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregor const AnnotatedToken &Right) { 943a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregor if (Right.is(tok::hashhash)) 944a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi return Left.is(tok::hash); 945a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregor if (Left.is(tok::hashhash) || Left.is(tok::hash)) 946a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregor return Right.is(tok::hash); 947a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregor if (Right.is(tok::r_paren) || Right.is(tok::semi) || Right.is(tok::comma)) 948a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi return false; 949a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregor if (Right.is(tok::less) && 950a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi (Left.is(tok::kw_template) || 951a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregor (Line.Type == LT_ObjCDecl && Style.ObjCSpaceBeforeProtocolList))) 952d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor return true; 953d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor if (Left.is(tok::arrow) || Right.is(tok::arrow)) 9541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return false; 955d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor if (Left.is(tok::exclaim) || Left.is(tok::tilde)) 956a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi return false; 957a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregor if (Left.is(tok::at) && 95837d68185088947322a97eabdc1c0714b0debd929Douglas Gregor (Right.is(tok::identifier) || Right.is(tok::string_literal) || 959a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi Right.is(tok::char_constant) || Right.is(tok::numeric_constant) || 960a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregor Right.is(tok::l_paren) || Right.is(tok::l_brace) || 961e976ffe18ee60b81641423f42ff6feec2f5e3cb7John McCall Right.is(tok::kw_true) || Right.is(tok::kw_false))) 962b1a56e767cfb645fcb25027ab728dd5824d92615John McCall return false; 963b1a56e767cfb645fcb25027ab728dd5824d92615John McCall if (Left.is(tok::coloncolon)) 964e976ffe18ee60b81641423f42ff6feec2f5e3cb7John McCall return false; 965e976ffe18ee60b81641423f42ff6feec2f5e3cb7John McCall if (Right.is(tok::coloncolon)) 966e976ffe18ee60b81641423f42ff6feec2f5e3cb7John McCall return Left.isNot(tok::identifier) && Left.isNot(tok::greater) && 967b1a56e767cfb645fcb25027ab728dd5824d92615John McCall Left.isNot(tok::l_paren); 968a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregor if (Left.is(tok::less) || Right.is(tok::greater) || Right.is(tok::less)) 969a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi return false; 970b1a56e767cfb645fcb25027ab728dd5824d92615John McCall if (Right.is(tok::amp) || Right.is(tok::star)) 9711f2e1a96bec2ba6418ae7f2d2b525a3575203b6aJohn McCall return Left.FormatTok.Tok.isLiteral() || 972a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregor (Left.isNot(tok::star) && Left.isNot(tok::amp) && 9731f2e1a96bec2ba6418ae7f2d2b525a3575203b6aJohn McCall Left.isNot(tok::l_paren) && !Style.PointerBindsToType); 9741f2e1a96bec2ba6418ae7f2d2b525a3575203b6aJohn McCall if (Left.is(tok::amp) || Left.is(tok::star)) 9751f2e1a96bec2ba6418ae7f2d2b525a3575203b6aJohn McCall return Right.FormatTok.Tok.isLiteral() || 9761f2e1a96bec2ba6418ae7f2d2b525a3575203b6aJohn McCall (Right.isNot(tok::star) && Right.isNot(tok::amp) && 977b1a56e767cfb645fcb25027ab728dd5824d92615John McCall Style.PointerBindsToType); 978d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor if (Right.is(tok::star) && Left.is(tok::l_paren)) 979d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor return false; 980d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor if (Left.is(tok::l_square)) 981d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor return Left.Type == TT_ObjCArrayLiteral && Right.isNot(tok::r_square); 982d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor if (Right.is(tok::r_square)) 983d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor return Right.Type == TT_ObjCArrayLiteral; 984d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor if (Right.is(tok::l_square) && Right.Type != TT_ObjCMethodExpr) 985ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor return false; 9867c1e98f1cb37b40e619a0c8aee8b337f037b432bDouglas Gregor if (Left.is(tok::period) || Right.is(tok::period)) 987ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor return false; 9886c1c1b8c6ca743a5b6b4c81f9ac56392c12c7457John McCall if (Left.is(tok::colon)) 9896c1c1b8c6ca743a5b6b4c81f9ac56392c12c7457John McCall return Left.Type != TT_ObjCMethodExpr; 9906c1c1b8c6ca743a5b6b4c81f9ac56392c12c7457John McCall if (Right.is(tok::colon)) 9916c1c1b8c6ca743a5b6b4c81f9ac56392c12c7457John McCall return Right.Type != TT_ObjCMethodExpr; 992d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor if (Left.is(tok::l_paren)) 993d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor return false; 9941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (Right.is(tok::l_paren)) { 995ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara return Line.Type == LT_ObjCDecl || Left.is(tok::kw_if) || 996ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara Left.is(tok::kw_for) || Left.is(tok::kw_while) || 997b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall Left.is(tok::kw_switch) || Left.is(tok::kw_return) || 998b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall Left.is(tok::kw_catch) || Left.is(tok::kw_new) || 999b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall Left.is(tok::kw_delete); 1000b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall } 1001b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall if (Left.is(tok::at) && 1002d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor Right.FormatTok.Tok.getObjCKeywordID() != tok::objc_not_keyword) 1003eaba1af8529c381d7bfd4dd0a8b48d2c01647972Eli Friedman return false; 1004eaba1af8529c381d7bfd4dd0a8b48d2c01647972Eli Friedman if (Left.is(tok::l_brace) && Right.is(tok::r_brace)) 1005eaba1af8529c381d7bfd4dd0a8b48d2c01647972Eli Friedman return false; 1006eaba1af8529c381d7bfd4dd0a8b48d2c01647972Eli Friedman return true; 1007eaba1af8529c381d7bfd4dd0a8b48d2c01647972Eli Friedman} 1008d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor 1009f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas Gregorbool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, 1010d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor const AnnotatedToken &Tok) { 101102cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall if (Tok.FormatTok.Tok.getIdentifierInfo() && 101202cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall Tok.Parent->FormatTok.Tok.getIdentifierInfo()) 101302cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall return true; // Never ever merge two identifiers. 101402cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall if (Line.Type == LT_ObjCMethodDecl) { 101502cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall if (Tok.Parent->Type == TT_ObjCMethodSpecifier) 10169901c57806f7e36736ed1616e6ab3eebcc99b78cDouglas Gregor return true; 10179901c57806f7e36736ed1616e6ab3eebcc99b78cDouglas Gregor if (Tok.Parent->is(tok::r_paren) && Tok.is(tok::identifier)) 10189901c57806f7e36736ed1616e6ab3eebcc99b78cDouglas Gregor // Don't space between ')' and <id> 10197a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl return false; 10209901c57806f7e36736ed1616e6ab3eebcc99b78cDouglas Gregor } 10219901c57806f7e36736ed1616e6ab3eebcc99b78cDouglas Gregor if (Line.Type == LT_ObjCProperty && 1022d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson (Tok.is(tok::equal) || Tok.Parent->is(tok::equal))) 102317945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis return false; 1024d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor 1025d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor if (Tok.Parent->is(tok::comma)) 1026d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor return true; 102771074fdf40a8f5b53810712102b58c27efc30759Douglas Gregor if (Tok.Type == TT_CtorInitializerColon || Tok.Type == TT_ObjCBlockLParen) 102871074fdf40a8f5b53810712102b58c27efc30759Douglas Gregor return true; 102971074fdf40a8f5b53810712102b58c27efc30759Douglas Gregor if (Tok.Parent->FormatTok.Tok.is(tok::kw_operator)) 103071074fdf40a8f5b53810712102b58c27efc30759Douglas Gregor return false; 103171074fdf40a8f5b53810712102b58c27efc30759Douglas Gregor if (Tok.Type == TT_OverloadedOperatorLParen) 103271074fdf40a8f5b53810712102b58c27efc30759Douglas Gregor return false; 103371074fdf40a8f5b53810712102b58c27efc30759Douglas Gregor if (Tok.is(tok::colon)) 103471074fdf40a8f5b53810712102b58c27efc30759Douglas Gregor return Line.First.isNot(tok::kw_case) && !Tok.Children.empty() && 103571074fdf40a8f5b53810712102b58c27efc30759Douglas Gregor Tok.Type != TT_ObjCMethodExpr; 1036bed51fef5773f043db2ad13aa2b6d2f8a8bdbdbaDouglas Gregor if (Tok.Parent->Type == TT_UnaryOperator || Tok.Parent->Type == TT_CastRParen) 1037bed51fef5773f043db2ad13aa2b6d2f8a8bdbdbaDouglas Gregor return false; 1038bed51fef5773f043db2ad13aa2b6d2f8a8bdbdbaDouglas Gregor if (Tok.Type == TT_UnaryOperator) 1039bed51fef5773f043db2ad13aa2b6d2f8a8bdbdbaDouglas Gregor return Tok.Parent->isNot(tok::l_paren) && 1040bed51fef5773f043db2ad13aa2b6d2f8a8bdbdbaDouglas Gregor Tok.Parent->isNot(tok::l_square) && Tok.Parent->isNot(tok::at) && 1041bed51fef5773f043db2ad13aa2b6d2f8a8bdbdbaDouglas Gregor (Tok.Parent->isNot(tok::colon) || 1042bed51fef5773f043db2ad13aa2b6d2f8a8bdbdbaDouglas Gregor Tok.Parent->Type != TT_ObjCMethodExpr); 1043bed51fef5773f043db2ad13aa2b6d2f8a8bdbdbaDouglas Gregor if (Tok.Parent->is(tok::greater) && Tok.is(tok::greater)) { 1044bed51fef5773f043db2ad13aa2b6d2f8a8bdbdbaDouglas Gregor return Tok.Type == TT_TemplateCloser && 1045bed51fef5773f043db2ad13aa2b6d2f8a8bdbdbaDouglas Gregor Tok.Parent->Type == TT_TemplateCloser && 1046bed51fef5773f043db2ad13aa2b6d2f8a8bdbdbaDouglas Gregor Style.Standard != FormatStyle::LS_Cpp11; 1047bed51fef5773f043db2ad13aa2b6d2f8a8bdbdbaDouglas Gregor } 1048bed51fef5773f043db2ad13aa2b6d2f8a8bdbdbaDouglas Gregor if (Tok.Type == TT_BinaryOperator || Tok.Parent->Type == TT_BinaryOperator) 104971074fdf40a8f5b53810712102b58c27efc30759Douglas Gregor return true; 105071074fdf40a8f5b53810712102b58c27efc30759Douglas Gregor if (Tok.Parent->Type == TT_TemplateCloser && Tok.is(tok::l_paren)) 105102cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall return false; 105202cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall if (Tok.is(tok::less) && Line.First.is(tok::hash)) 105302cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall return true; 105402cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall if (Tok.Type == TT_TrailingUnaryOperator) 105502cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall return false; 10567557a1348d2821dce126a778aa7acd7a00b814fdDouglas Gregor return spaceRequiredBetween(Line, *Tok.Parent, Tok); 1057a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregor} 1058127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor 1059127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorbool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, 1060127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor const AnnotatedToken &Right) { 1061b0cb022daec8671406ab25f4b5d5a6d48d823bc4John McCall const AnnotatedToken &Left = *Right.Parent; 1062a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi if (Right.Type == TT_StartOfName) 106324bae92f08ae098cc50a602d8cf1273b423e14daDouglas Gregor return true; 10641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (Right.is(tok::colon) && Right.Type == TT_ObjCMethodExpr) 10651e1e9722cb4ea6027e2c4885c7a8f26d3726ca7dDouglas Gregor return false; 10662c853e401ca406d417eb916e867226050e7be06bArgyrios Kyrtzidis if (Left.is(tok::colon) && Left.Type == TT_ObjCMethodExpr) 10672c853e401ca406d417eb916e867226050e7be06bArgyrios Kyrtzidis return true; 10682c853e401ca406d417eb916e867226050e7be06bArgyrios Kyrtzidis if (Right.Type == TT_ObjCSelectorName) 10691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return true; 1070127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor if (Left.ClosesTemplateDeclaration) 10712c853e401ca406d417eb916e867226050e7be06bArgyrios Kyrtzidis return true; 10722c853e401ca406d417eb916e867226050e7be06bArgyrios Kyrtzidis if (Right.Type == TT_ConditionalExpr || Right.is(tok::question)) 1073127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor return true; 10741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (Right.Type == TT_RangeBasedForLoopColon || 1075b0cb022daec8671406ab25f4b5d5a6d48d823bc4John McCall Right.Type == TT_InheritanceColon) 1076b0cb022daec8671406ab25f4b5d5a6d48d823bc4John McCall return false; 1077b0cb022daec8671406ab25f4b5d5a6d48d823bc4John McCall if (Left.Type == TT_RangeBasedForLoopColon || 1078b0cb022daec8671406ab25f4b5d5a6d48d823bc4John McCall Left.Type == TT_InheritanceColon) 1079b0cb022daec8671406ab25f4b5d5a6d48d823bc4John McCall return true; 1080b0cb022daec8671406ab25f4b5d5a6d48d823bc4John McCall if (Right.Type == TT_RangeBasedForLoopColon) 108179c2278a66d8fc0943774d1b7c71a32f7764e1e2Douglas Gregor return false; 1082b212d9a8e10308cde5b7a1ce07bd59d8df14fa06Douglas Gregor if (Left.Type == TT_PointerOrReference || Left.Type == TT_TemplateCloser || 1083a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi Left.Type == TT_UnaryOperator || Left.Type == TT_ConditionalExpr || 108479c2278a66d8fc0943774d1b7c71a32f7764e1e2Douglas Gregor Left.is(tok::question) || Left.is(tok::kw_operator)) 10852a7fb27913999d132cf9e10e03dc5271faa2e9d3John McCall return false; 10861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (Left.is(tok::equal) && Line.Type == LT_VirtualFunctionDecl) 10875f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner return false; 108864b4b43a23aa8b8009470e3cc451333f623d7d58David Blaikie 108921ef0fa27b0783ec0bc6aa5b524feb2ec840f952John McCall if (Right.Type == TT_LineComment) 10902dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor // We rely on MustBreakBefore being set correctly here as we should not 109171074fdf40a8f5b53810712102b58c27efc30759Douglas Gregor // change the "binding" behavior of a comment. 1092fd810b1386ed29b250e7d522ea826a65c815e49dJohn McCall return false; 1093c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor 1094c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor // Allow breaking after a trailing 'const', e.g. after a method declaration, 1095c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor // unless it is follow by ';', '{' or '='. 1096c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor if (Left.is(tok::kw_const) && Left.Parent != NULL && 1097c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor Left.Parent->is(tok::r_paren)) 1098c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor return Right.isNot(tok::l_brace) && Right.isNot(tok::semi) && 1099d325daa506338ab86f9dd468b48fd010673f49a6John McCall Right.isNot(tok::equal); 1100d325daa506338ab86f9dd468b48fd010673f49a6John McCall 110168b6b87b6beb7922fc2c8ab923ba2ce125490363John McCall // We only break before r_brace if there was a corresponding break before 110268b6b87b6beb7922fc2c8ab923ba2ce125490363John McCall // the l_brace, which is tracked by BreakBeforeClosingBrace. 110368b6b87b6beb7922fc2c8ab923ba2ce125490363John McCall if (Right.is(tok::r_brace)) 110468b6b87b6beb7922fc2c8ab923ba2ce125490363John McCall return false; 110568b6b87b6beb7922fc2c8ab923ba2ce125490363John McCall 1106c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor if (Right.is(tok::r_paren) || Right.is(tok::greater)) 1107d325daa506338ab86f9dd468b48fd010673f49a6John McCall return false; 1108c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor if (Left.is(tok::identifier) && Right.is(tok::string_literal)) 1109d325daa506338ab86f9dd468b48fd010673f49a6John McCall return true; 1110d325daa506338ab86f9dd468b48fd010673f49a6John McCall return (isBinaryOperator(Left) && Left.isNot(tok::lessless)) || 1111d325daa506338ab86f9dd468b48fd010673f49a6John McCall Left.is(tok::comma) || Right.is(tok::lessless) || 1112a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi Right.is(tok::arrow) || Right.is(tok::period) || 11137c1e98f1cb37b40e619a0c8aee8b337f037b432bDouglas Gregor Right.is(tok::colon) || Left.is(tok::coloncolon) || 1114d325daa506338ab86f9dd468b48fd010673f49a6John McCall Left.is(tok::semi) || Left.is(tok::l_brace) || 111568b6b87b6beb7922fc2c8ab923ba2ce125490363John McCall (Left.is(tok::r_paren) && Left.Type != TT_CastRParen && 111602cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall Right.is(tok::identifier)) || 1117ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara (Left.is(tok::l_paren) && !Right.is(tok::r_paren)) || 1118635311f94e8fd4ff153130d91046ff78ffe97b06Abramo Bagnara (Left.is(tok::l_square) && !Right.is(tok::r_square)); 111916573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor} 1120af1fc7af351758b0ea0d285bdfe5640128109a4eRichard Smith 112186c3ae46250cdcc57778c27826060779a92f3815Richard Smith} // namespace format 1122b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall} // namespace clang 1123c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor