void UnwrappedLineParser::calculateBraceTypes() { // We'll parse forward through the tokens until we hit // a closing brace or eof - note that getNextToken() will // parse macros, so this will magically work inside macro // definitions, too. unsigned StoredPosition = Tokens->getPosition(); unsigned Position = StoredPosition; FormatToken *Tok = FormatTok; // Keep a stack of positions of lbrace tokens. We will // update information about whether an lbrace starts a // braced init list or a different block during the loop. SmallVector<FormatToken *, 8> LBraceStack; assert(Tok->Tok.is(tok::l_brace)); do { // Get next none-comment token. FormatToken *NextTok; unsigned ReadTokens = 0; do { NextTok = Tokens->getNextToken(); ++ReadTokens; } while (NextTok->is(tok::comment)); switch (Tok->Tok.getKind()) { case tok::l_brace: LBraceStack.push_back(Tok); break; case tok::r_brace: if (!LBraceStack.empty()) { if (LBraceStack.back()->BlockKind == BK_Unknown) { bool ProbablyBracedList = false; if (Style.Language == FormatStyle::LK_Proto) { ProbablyBracedList = NextTok->isOneOf(tok::comma, tok::r_square); } else { // Using OriginalColumn to distinguish between ObjC methods and // binary operators is a bit hacky. bool NextIsObjCMethod = NextTok->isOneOf(tok::plus, tok::minus) && NextTok->OriginalColumn == 0; // If there is a comma, semicolon or right paren after the closing // brace, we assume this is a braced initializer list. Note that // regardless how we mark inner braces here, we will overwrite the // BlockKind later if we parse a braced list (where all blocks // inside are by default braced lists), or when we explicitly detect // blocks (for example while parsing lambdas). // // We exclude + and - as they can be ObjC visibility modifiers. ProbablyBracedList = NextTok->isOneOf(tok::comma, tok::semi, tok::period, tok::colon, tok::r_paren, tok::r_square, tok::l_brace, tok::l_paren) || (NextTok->isBinaryOperator() && !NextIsObjCMethod); } if (ProbablyBracedList) { Tok->BlockKind = BK_BracedInit; LBraceStack.back()->BlockKind = BK_BracedInit; } else { Tok->BlockKind = BK_Block; LBraceStack.back()->BlockKind = BK_Block; } } LBraceStack.pop_back(); } break; case tok::at: case tok::semi: case tok::kw_if: case tok::kw_while: case tok::kw_for: case tok::kw_switch: case tok::kw_try: if (!LBraceStack.empty()) LBraceStack.back()->BlockKind = BK_Block; break; default: break; } Tok = NextTok; Position += ReadTokens; } while (Tok->Tok.isNot(tok::eof) && !LBraceStack.empty()); // Assume other blocks for all unclosed opening braces. for (unsigned i = 0, e = LBraceStack.size(); i != e; ++i) { if (LBraceStack[i]->BlockKind == BK_Unknown) LBraceStack[i]->BlockKind = BK_Block; } FormatTok = Tokens->setPosition(StoredPosition); }
void UnwrappedLineParser::calculateBraceTypes() { // We'll parse forward through the tokens until we hit // a closing brace or eof - note that getNextToken() will // parse macros, so this will magically work inside macro // definitions, too. unsigned StoredPosition = Tokens->getPosition(); unsigned Position = StoredPosition; FormatToken *Tok = FormatTok; // Keep a stack of positions of lbrace tokens. We will // update information about whether an lbrace starts a // braced init list or a different block during the loop. SmallVector<FormatToken *, 8> LBraceStack; assert(Tok->Tok.is(tok::l_brace)); do { // Get next none-comment token. FormatToken *NextTok; unsigned ReadTokens = 0; do { NextTok = Tokens->getNextToken(); ++ReadTokens; } while (NextTok->is(tok::comment)); switch (Tok->Tok.getKind()) { case tok::l_brace: LBraceStack.push_back(Tok); break; case tok::r_brace: if (!LBraceStack.empty()) { if (LBraceStack.back()->BlockKind == BK_Unknown) { // If there is a comma, semicolon or right paren after the closing // brace, we assume this is a braced initializer list. // FIXME: Note that this currently works only because we do not // use the brace information while inside a braced init list. // Thus, if the parent is a braced init list, we consider all // brace blocks inside it braced init list. That works good enough // for now, but we will need to fix it to correctly handle lambdas. if (NextTok->isOneOf(tok::comma, tok::semi, tok::r_paren, tok::l_brace, tok::colon)) { Tok->BlockKind = BK_BracedInit; LBraceStack.back()->BlockKind = BK_BracedInit; } else { Tok->BlockKind = BK_Block; LBraceStack.back()->BlockKind = BK_Block; } } LBraceStack.pop_back(); } break; case tok::semi: case tok::kw_if: case tok::kw_while: case tok::kw_for: case tok::kw_switch: case tok::kw_try: if (!LBraceStack.empty()) LBraceStack.back()->BlockKind = BK_Block; break; default: break; } Tok = NextTok; Position += ReadTokens; } while (Tok->Tok.isNot(tok::eof)); // Assume other blocks for all unclosed opening braces. for (unsigned i = 0, e = LBraceStack.size(); i != e; ++i) { if (LBraceStack[i]->BlockKind == BK_Unknown) LBraceStack[i]->BlockKind = BK_Block; } FormatTok = Tokens->setPosition(StoredPosition); }