1249261Sdim//===--- UnwrappedLineParser.cpp - Format C++ code ------------------------===// 2249261Sdim// 3249261Sdim// The LLVM Compiler Infrastructure 4249261Sdim// 5249261Sdim// This file is distributed under the University of Illinois Open Source 6249261Sdim// License. See LICENSE.TXT for details. 7249261Sdim// 8249261Sdim//===----------------------------------------------------------------------===// 9249261Sdim/// 10249261Sdim/// \file 11249261Sdim/// \brief This file contains the implementation of the UnwrappedLineParser, 12249261Sdim/// which turns a stream of tokens into UnwrappedLines. 13249261Sdim/// 14249261Sdim//===----------------------------------------------------------------------===// 15249261Sdim 16249261Sdim#define DEBUG_TYPE "format-parser" 17249261Sdim 18249261Sdim#include "UnwrappedLineParser.h" 19249261Sdim#include "llvm/Support/Debug.h" 20249261Sdim 21249261Sdimnamespace clang { 22249261Sdimnamespace format { 23249261Sdim 24263509Sdimclass FormatTokenSource { 25263509Sdimpublic: 26263509Sdim virtual ~FormatTokenSource() {} 27263509Sdim virtual FormatToken *getNextToken() = 0; 28263509Sdim 29263509Sdim virtual unsigned getPosition() = 0; 30263509Sdim virtual FormatToken *setPosition(unsigned Position) = 0; 31263509Sdim}; 32263509Sdim 33263509Sdimnamespace { 34263509Sdim 35249261Sdimclass ScopedDeclarationState { 36249261Sdimpublic: 37249261Sdim ScopedDeclarationState(UnwrappedLine &Line, std::vector<bool> &Stack, 38249261Sdim bool MustBeDeclaration) 39249261Sdim : Line(Line), Stack(Stack) { 40249261Sdim Line.MustBeDeclaration = MustBeDeclaration; 41249261Sdim Stack.push_back(MustBeDeclaration); 42249261Sdim } 43249261Sdim ~ScopedDeclarationState() { 44249261Sdim Stack.pop_back(); 45249261Sdim if (!Stack.empty()) 46249261Sdim Line.MustBeDeclaration = Stack.back(); 47249261Sdim else 48249261Sdim Line.MustBeDeclaration = true; 49249261Sdim } 50263509Sdim 51249261Sdimprivate: 52249261Sdim UnwrappedLine &Line; 53249261Sdim std::vector<bool> &Stack; 54249261Sdim}; 55249261Sdim 56249261Sdimclass ScopedMacroState : public FormatTokenSource { 57249261Sdimpublic: 58249261Sdim ScopedMacroState(UnwrappedLine &Line, FormatTokenSource *&TokenSource, 59263509Sdim FormatToken *&ResetToken, bool &StructuralError) 60249261Sdim : Line(Line), TokenSource(TokenSource), ResetToken(ResetToken), 61252723Sdim PreviousLineLevel(Line.Level), PreviousTokenSource(TokenSource), 62252723Sdim StructuralError(StructuralError), 63263509Sdim PreviousStructuralError(StructuralError), Token(NULL) { 64249261Sdim TokenSource = this; 65249261Sdim Line.Level = 0; 66249261Sdim Line.InPPDirective = true; 67249261Sdim } 68249261Sdim 69249261Sdim ~ScopedMacroState() { 70249261Sdim TokenSource = PreviousTokenSource; 71249261Sdim ResetToken = Token; 72249261Sdim Line.InPPDirective = false; 73249261Sdim Line.Level = PreviousLineLevel; 74252723Sdim StructuralError = PreviousStructuralError; 75249261Sdim } 76249261Sdim 77263509Sdim virtual FormatToken *getNextToken() { 78249261Sdim // The \c UnwrappedLineParser guards against this by never calling 79249261Sdim // \c getNextToken() after it has encountered the first eof token. 80249261Sdim assert(!eof()); 81249261Sdim Token = PreviousTokenSource->getNextToken(); 82249261Sdim if (eof()) 83263509Sdim return getFakeEOF(); 84249261Sdim return Token; 85249261Sdim } 86249261Sdim 87263509Sdim virtual unsigned getPosition() { return PreviousTokenSource->getPosition(); } 88263509Sdim 89263509Sdim virtual FormatToken *setPosition(unsigned Position) { 90263509Sdim Token = PreviousTokenSource->setPosition(Position); 91263509Sdim return Token; 92263509Sdim } 93263509Sdim 94249261Sdimprivate: 95263509Sdim bool eof() { return Token && Token->HasUnescapedNewline; } 96249261Sdim 97263509Sdim FormatToken *getFakeEOF() { 98263509Sdim static bool EOFInitialized = false; 99263509Sdim static FormatToken FormatTok; 100263509Sdim if (!EOFInitialized) { 101263509Sdim FormatTok.Tok.startToken(); 102263509Sdim FormatTok.Tok.setKind(tok::eof); 103263509Sdim EOFInitialized = true; 104263509Sdim } 105263509Sdim return &FormatTok; 106249261Sdim } 107249261Sdim 108249261Sdim UnwrappedLine &Line; 109249261Sdim FormatTokenSource *&TokenSource; 110263509Sdim FormatToken *&ResetToken; 111249261Sdim unsigned PreviousLineLevel; 112249261Sdim FormatTokenSource *PreviousTokenSource; 113252723Sdim bool &StructuralError; 114252723Sdim bool PreviousStructuralError; 115249261Sdim 116263509Sdim FormatToken *Token; 117249261Sdim}; 118249261Sdim 119263509Sdim} // end anonymous namespace 120263509Sdim 121249261Sdimclass ScopedLineState { 122249261Sdimpublic: 123249261Sdim ScopedLineState(UnwrappedLineParser &Parser, 124249261Sdim bool SwitchToPreprocessorLines = false) 125263509Sdim : Parser(Parser) { 126263509Sdim OriginalLines = Parser.CurrentLines; 127249261Sdim if (SwitchToPreprocessorLines) 128249261Sdim Parser.CurrentLines = &Parser.PreprocessorDirectives; 129263509Sdim else if (!Parser.Line->Tokens.empty()) 130263509Sdim Parser.CurrentLines = &Parser.Line->Tokens.back().Children; 131249261Sdim PreBlockLine = Parser.Line.take(); 132249261Sdim Parser.Line.reset(new UnwrappedLine()); 133249261Sdim Parser.Line->Level = PreBlockLine->Level; 134249261Sdim Parser.Line->InPPDirective = PreBlockLine->InPPDirective; 135249261Sdim } 136249261Sdim 137249261Sdim ~ScopedLineState() { 138249261Sdim if (!Parser.Line->Tokens.empty()) { 139249261Sdim Parser.addUnwrappedLine(); 140249261Sdim } 141249261Sdim assert(Parser.Line->Tokens.empty()); 142249261Sdim Parser.Line.reset(PreBlockLine); 143263509Sdim if (Parser.CurrentLines == &Parser.PreprocessorDirectives) 144263509Sdim Parser.MustBreakBeforeNextToken = true; 145263509Sdim Parser.CurrentLines = OriginalLines; 146249261Sdim } 147249261Sdim 148249261Sdimprivate: 149249261Sdim UnwrappedLineParser &Parser; 150249261Sdim 151249261Sdim UnwrappedLine *PreBlockLine; 152263509Sdim SmallVectorImpl<UnwrappedLine> *OriginalLines; 153249261Sdim}; 154249261Sdim 155263509Sdimnamespace { 156263509Sdim 157263509Sdimclass IndexedTokenSource : public FormatTokenSource { 158263509Sdimpublic: 159263509Sdim IndexedTokenSource(ArrayRef<FormatToken *> Tokens) 160263509Sdim : Tokens(Tokens), Position(-1) {} 161263509Sdim 162263509Sdim virtual FormatToken *getNextToken() { 163263509Sdim ++Position; 164263509Sdim return Tokens[Position]; 165263509Sdim } 166263509Sdim 167263509Sdim virtual unsigned getPosition() { 168263509Sdim assert(Position >= 0); 169263509Sdim return Position; 170263509Sdim } 171263509Sdim 172263509Sdim virtual FormatToken *setPosition(unsigned P) { 173263509Sdim Position = P; 174263509Sdim return Tokens[Position]; 175263509Sdim } 176263509Sdim 177263509Sdim void reset() { Position = -1; } 178263509Sdim 179263509Sdimprivate: 180263509Sdim ArrayRef<FormatToken *> Tokens; 181263509Sdim int Position; 182263509Sdim}; 183263509Sdim 184263509Sdim} // end anonymous namespace 185263509Sdim 186263509SdimUnwrappedLineParser::UnwrappedLineParser(const FormatStyle &Style, 187263509Sdim ArrayRef<FormatToken *> Tokens, 188263509Sdim UnwrappedLineConsumer &Callback) 189249261Sdim : Line(new UnwrappedLine), MustBreakBeforeNextToken(false), 190263509Sdim CurrentLines(&Lines), StructuralError(false), Style(Style), Tokens(NULL), 191263509Sdim Callback(Callback), AllTokens(Tokens), PPBranchLevel(-1) {} 192249261Sdim 193263509Sdimvoid UnwrappedLineParser::reset() { 194263509Sdim PPBranchLevel = -1; 195263509Sdim Line.reset(new UnwrappedLine); 196263509Sdim CommentsBeforeNextToken.clear(); 197263509Sdim FormatTok = NULL; 198263509Sdim MustBreakBeforeNextToken = false; 199263509Sdim PreprocessorDirectives.clear(); 200263509Sdim CurrentLines = &Lines; 201263509Sdim DeclarationScopeStack.clear(); 202263509Sdim StructuralError = false; 203263509Sdim PPStack.clear(); 204263509Sdim} 205263509Sdim 206249261Sdimbool UnwrappedLineParser::parse() { 207263509Sdim IndexedTokenSource TokenSource(AllTokens); 208263509Sdim do { 209263509Sdim DEBUG(llvm::dbgs() << "----\n"); 210263509Sdim reset(); 211263509Sdim Tokens = &TokenSource; 212263509Sdim TokenSource.reset(); 213249261Sdim 214263509Sdim readToken(); 215263509Sdim parseFile(); 216263509Sdim // Create line with eof token. 217263509Sdim pushToken(FormatTok); 218263509Sdim addUnwrappedLine(); 219263509Sdim 220263509Sdim for (SmallVectorImpl<UnwrappedLine>::iterator I = Lines.begin(), 221263509Sdim E = Lines.end(); 222263509Sdim I != E; ++I) { 223263509Sdim Callback.consumeUnwrappedLine(*I); 224263509Sdim } 225263509Sdim Callback.finishRun(); 226263509Sdim Lines.clear(); 227263509Sdim while (!PPLevelBranchIndex.empty() && 228263509Sdim PPLevelBranchIndex.back() + 1 >= PPLevelBranchCount.back()) { 229263509Sdim PPLevelBranchIndex.resize(PPLevelBranchIndex.size() - 1); 230263509Sdim PPLevelBranchCount.resize(PPLevelBranchCount.size() - 1); 231263509Sdim } 232263509Sdim if (!PPLevelBranchIndex.empty()) { 233263509Sdim ++PPLevelBranchIndex.back(); 234263509Sdim assert(PPLevelBranchIndex.size() == PPLevelBranchCount.size()); 235263509Sdim assert(PPLevelBranchIndex.back() <= PPLevelBranchCount.back()); 236263509Sdim } 237263509Sdim } while (!PPLevelBranchIndex.empty()); 238263509Sdim 239252723Sdim return StructuralError; 240249261Sdim} 241249261Sdim 242252723Sdimvoid UnwrappedLineParser::parseFile() { 243249261Sdim ScopedDeclarationState DeclarationState( 244249261Sdim *Line, DeclarationScopeStack, 245249261Sdim /*MustBeDeclaration=*/ !Line->InPPDirective); 246263509Sdim parseLevel(/*HasOpeningBrace=*/false); 247249261Sdim // Make sure to format the remaining tokens. 248249261Sdim flushComments(true); 249249261Sdim addUnwrappedLine(); 250249261Sdim} 251249261Sdim 252252723Sdimvoid UnwrappedLineParser::parseLevel(bool HasOpeningBrace) { 253263509Sdim bool SwitchLabelEncountered = false; 254249261Sdim do { 255263509Sdim switch (FormatTok->Tok.getKind()) { 256249261Sdim case tok::comment: 257249261Sdim nextToken(); 258249261Sdim addUnwrappedLine(); 259249261Sdim break; 260249261Sdim case tok::l_brace: 261249261Sdim // FIXME: Add parameter whether this can happen - if this happens, we must 262249261Sdim // be in a non-declaration context. 263263509Sdim parseBlock(/*MustBeDeclaration=*/false); 264249261Sdim addUnwrappedLine(); 265249261Sdim break; 266249261Sdim case tok::r_brace: 267252723Sdim if (HasOpeningBrace) 268252723Sdim return; 269252723Sdim StructuralError = true; 270252723Sdim nextToken(); 271252723Sdim addUnwrappedLine(); 272249261Sdim break; 273263509Sdim case tok::kw_default: 274263509Sdim case tok::kw_case: 275263509Sdim if (!SwitchLabelEncountered && 276263509Sdim (Style.IndentCaseLabels || (Line->InPPDirective && Line->Level == 1))) 277263509Sdim ++Line->Level; 278263509Sdim SwitchLabelEncountered = true; 279263509Sdim parseStructuralElement(); 280263509Sdim break; 281249261Sdim default: 282249261Sdim parseStructuralElement(); 283249261Sdim break; 284249261Sdim } 285249261Sdim } while (!eof()); 286249261Sdim} 287249261Sdim 288263509Sdimvoid UnwrappedLineParser::calculateBraceTypes() { 289263509Sdim // We'll parse forward through the tokens until we hit 290263509Sdim // a closing brace or eof - note that getNextToken() will 291263509Sdim // parse macros, so this will magically work inside macro 292263509Sdim // definitions, too. 293263509Sdim unsigned StoredPosition = Tokens->getPosition(); 294263509Sdim unsigned Position = StoredPosition; 295263509Sdim FormatToken *Tok = FormatTok; 296263509Sdim // Keep a stack of positions of lbrace tokens. We will 297263509Sdim // update information about whether an lbrace starts a 298263509Sdim // braced init list or a different block during the loop. 299263509Sdim SmallVector<FormatToken *, 8> LBraceStack; 300263509Sdim assert(Tok->Tok.is(tok::l_brace)); 301263509Sdim do { 302263509Sdim // Get next none-comment token. 303263509Sdim FormatToken *NextTok; 304263509Sdim unsigned ReadTokens = 0; 305263509Sdim do { 306263509Sdim NextTok = Tokens->getNextToken(); 307263509Sdim ++ReadTokens; 308263509Sdim } while (NextTok->is(tok::comment)); 309263509Sdim 310263509Sdim switch (Tok->Tok.getKind()) { 311263509Sdim case tok::l_brace: 312263509Sdim LBraceStack.push_back(Tok); 313263509Sdim break; 314263509Sdim case tok::r_brace: 315263509Sdim if (!LBraceStack.empty()) { 316263509Sdim if (LBraceStack.back()->BlockKind == BK_Unknown) { 317263509Sdim // If there is a comma, semicolon or right paren after the closing 318263509Sdim // brace, we assume this is a braced initializer list. Note that 319263509Sdim // regardless how we mark inner braces here, we will overwrite the 320263509Sdim // BlockKind later if we parse a braced list (where all blocks inside 321263509Sdim // are by default braced lists), or when we explicitly detect blocks 322263509Sdim // (for example while parsing lambdas). 323263509Sdim // 324263509Sdim // We exclude + and - as they can be ObjC visibility modifiers. 325263509Sdim if (NextTok->isOneOf(tok::comma, tok::semi, tok::r_paren, 326263509Sdim tok::r_square, tok::l_brace, tok::colon) || 327263509Sdim (NextTok->isBinaryOperator() && 328263509Sdim !NextTok->isOneOf(tok::plus, tok::minus))) { 329263509Sdim Tok->BlockKind = BK_BracedInit; 330263509Sdim LBraceStack.back()->BlockKind = BK_BracedInit; 331263509Sdim } else { 332263509Sdim Tok->BlockKind = BK_Block; 333263509Sdim LBraceStack.back()->BlockKind = BK_Block; 334263509Sdim } 335263509Sdim } 336263509Sdim LBraceStack.pop_back(); 337263509Sdim } 338263509Sdim break; 339263509Sdim case tok::semi: 340263509Sdim case tok::kw_if: 341263509Sdim case tok::kw_while: 342263509Sdim case tok::kw_for: 343263509Sdim case tok::kw_switch: 344263509Sdim case tok::kw_try: 345263509Sdim if (!LBraceStack.empty()) 346263509Sdim LBraceStack.back()->BlockKind = BK_Block; 347263509Sdim break; 348263509Sdim default: 349263509Sdim break; 350263509Sdim } 351263509Sdim Tok = NextTok; 352263509Sdim Position += ReadTokens; 353263509Sdim } while (Tok->Tok.isNot(tok::eof) && !LBraceStack.empty()); 354263509Sdim // Assume other blocks for all unclosed opening braces. 355263509Sdim for (unsigned i = 0, e = LBraceStack.size(); i != e; ++i) { 356263509Sdim if (LBraceStack[i]->BlockKind == BK_Unknown) 357263509Sdim LBraceStack[i]->BlockKind = BK_Block; 358263509Sdim } 359263509Sdim 360263509Sdim FormatTok = Tokens->setPosition(StoredPosition); 361263509Sdim} 362263509Sdim 363263509Sdimvoid UnwrappedLineParser::parseBlock(bool MustBeDeclaration, bool AddLevel, 364263509Sdim bool MunchSemi) { 365263509Sdim assert(FormatTok->Tok.is(tok::l_brace) && "'{' expected"); 366263509Sdim unsigned InitialLevel = Line->Level; 367249261Sdim nextToken(); 368249261Sdim 369249261Sdim addUnwrappedLine(); 370249261Sdim 371249261Sdim ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack, 372249261Sdim MustBeDeclaration); 373263509Sdim if (AddLevel) 374263509Sdim ++Line->Level; 375263509Sdim parseLevel(/*HasOpeningBrace=*/true); 376249261Sdim 377263509Sdim if (!FormatTok->Tok.is(tok::r_brace)) { 378263509Sdim Line->Level = InitialLevel; 379252723Sdim StructuralError = true; 380252723Sdim return; 381249261Sdim } 382249261Sdim 383249261Sdim nextToken(); // Munch the closing brace. 384263509Sdim if (MunchSemi && FormatTok->Tok.is(tok::semi)) 385263509Sdim nextToken(); 386263509Sdim Line->Level = InitialLevel; 387249261Sdim} 388249261Sdim 389263509Sdimvoid UnwrappedLineParser::parseChildBlock() { 390263509Sdim FormatTok->BlockKind = BK_Block; 391263509Sdim nextToken(); 392263509Sdim { 393263509Sdim ScopedLineState LineState(*this); 394263509Sdim ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack, 395263509Sdim /*MustBeDeclaration=*/false); 396263509Sdim Line->Level += 1; 397263509Sdim parseLevel(/*HasOpeningBrace=*/true); 398263509Sdim Line->Level -= 1; 399263509Sdim } 400263509Sdim nextToken(); 401263509Sdim} 402263509Sdim 403249261Sdimvoid UnwrappedLineParser::parsePPDirective() { 404263509Sdim assert(FormatTok->Tok.is(tok::hash) && "'#' expected"); 405252723Sdim ScopedMacroState MacroState(*Line, Tokens, FormatTok, StructuralError); 406249261Sdim nextToken(); 407249261Sdim 408263509Sdim if (FormatTok->Tok.getIdentifierInfo() == NULL) { 409249261Sdim parsePPUnknown(); 410249261Sdim return; 411249261Sdim } 412249261Sdim 413263509Sdim switch (FormatTok->Tok.getIdentifierInfo()->getPPKeywordID()) { 414249261Sdim case tok::pp_define: 415249261Sdim parsePPDefine(); 416263509Sdim return; 417263509Sdim case tok::pp_if: 418263509Sdim parsePPIf(/*IfDef=*/false); 419249261Sdim break; 420263509Sdim case tok::pp_ifdef: 421263509Sdim case tok::pp_ifndef: 422263509Sdim parsePPIf(/*IfDef=*/true); 423263509Sdim break; 424263509Sdim case tok::pp_else: 425263509Sdim parsePPElse(); 426263509Sdim break; 427263509Sdim case tok::pp_elif: 428263509Sdim parsePPElIf(); 429263509Sdim break; 430263509Sdim case tok::pp_endif: 431263509Sdim parsePPEndIf(); 432263509Sdim break; 433249261Sdim default: 434249261Sdim parsePPUnknown(); 435249261Sdim break; 436249261Sdim } 437249261Sdim} 438249261Sdim 439263509Sdimvoid UnwrappedLineParser::pushPPConditional() { 440263509Sdim if (!PPStack.empty() && PPStack.back() == PP_Unreachable) 441263509Sdim PPStack.push_back(PP_Unreachable); 442263509Sdim else 443263509Sdim PPStack.push_back(PP_Conditional); 444263509Sdim} 445263509Sdim 446263509Sdimvoid UnwrappedLineParser::parsePPIf(bool IfDef) { 447263509Sdim ++PPBranchLevel; 448263509Sdim assert(PPBranchLevel >= 0 && PPBranchLevel <= (int)PPLevelBranchIndex.size()); 449263509Sdim if (PPBranchLevel == (int)PPLevelBranchIndex.size()) { 450263509Sdim PPLevelBranchIndex.push_back(0); 451263509Sdim PPLevelBranchCount.push_back(0); 452263509Sdim } 453263509Sdim PPChainBranchIndex.push(0); 454263509Sdim nextToken(); 455263509Sdim bool IsLiteralFalse = (FormatTok->Tok.isLiteral() && 456263509Sdim StringRef(FormatTok->Tok.getLiteralData(), 457263509Sdim FormatTok->Tok.getLength()) == "0") || 458263509Sdim FormatTok->Tok.is(tok::kw_false); 459263509Sdim if ((!IfDef && IsLiteralFalse) || PPLevelBranchIndex[PPBranchLevel] > 0) { 460263509Sdim PPStack.push_back(PP_Unreachable); 461263509Sdim } else { 462263509Sdim pushPPConditional(); 463263509Sdim } 464263509Sdim parsePPUnknown(); 465263509Sdim} 466263509Sdim 467263509Sdimvoid UnwrappedLineParser::parsePPElse() { 468263509Sdim if (!PPStack.empty()) 469263509Sdim PPStack.pop_back(); 470263509Sdim assert(PPBranchLevel < (int)PPLevelBranchIndex.size()); 471263509Sdim if (!PPChainBranchIndex.empty()) 472263509Sdim ++PPChainBranchIndex.top(); 473263509Sdim if (PPBranchLevel >= 0 && !PPChainBranchIndex.empty() && 474263509Sdim PPLevelBranchIndex[PPBranchLevel] != PPChainBranchIndex.top()) { 475263509Sdim PPStack.push_back(PP_Unreachable); 476263509Sdim } else { 477263509Sdim pushPPConditional(); 478263509Sdim } 479263509Sdim parsePPUnknown(); 480263509Sdim} 481263509Sdim 482263509Sdimvoid UnwrappedLineParser::parsePPElIf() { parsePPElse(); } 483263509Sdim 484263509Sdimvoid UnwrappedLineParser::parsePPEndIf() { 485263509Sdim assert(PPBranchLevel < (int)PPLevelBranchIndex.size()); 486263509Sdim if (PPBranchLevel >= 0 && !PPChainBranchIndex.empty()) { 487263509Sdim if (PPChainBranchIndex.top() + 1 > PPLevelBranchCount[PPBranchLevel]) { 488263509Sdim PPLevelBranchCount[PPBranchLevel] = PPChainBranchIndex.top() + 1; 489263509Sdim } 490263509Sdim } 491263509Sdim --PPBranchLevel; 492263509Sdim if (!PPChainBranchIndex.empty()) 493263509Sdim PPChainBranchIndex.pop(); 494263509Sdim if (!PPStack.empty()) 495263509Sdim PPStack.pop_back(); 496263509Sdim parsePPUnknown(); 497263509Sdim} 498263509Sdim 499249261Sdimvoid UnwrappedLineParser::parsePPDefine() { 500249261Sdim nextToken(); 501249261Sdim 502263509Sdim if (FormatTok->Tok.getKind() != tok::identifier) { 503249261Sdim parsePPUnknown(); 504249261Sdim return; 505249261Sdim } 506249261Sdim nextToken(); 507263509Sdim if (FormatTok->Tok.getKind() == tok::l_paren && 508263509Sdim FormatTok->WhitespaceRange.getBegin() == 509263509Sdim FormatTok->WhitespaceRange.getEnd()) { 510249261Sdim parseParens(); 511249261Sdim } 512249261Sdim addUnwrappedLine(); 513249261Sdim Line->Level = 1; 514249261Sdim 515249261Sdim // Errors during a preprocessor directive can only affect the layout of the 516249261Sdim // preprocessor directive, and thus we ignore them. An alternative approach 517249261Sdim // would be to use the same approach we use on the file level (no 518249261Sdim // re-indentation if there was a structural error) within the macro 519249261Sdim // definition. 520249261Sdim parseFile(); 521249261Sdim} 522249261Sdim 523249261Sdimvoid UnwrappedLineParser::parsePPUnknown() { 524249261Sdim do { 525249261Sdim nextToken(); 526249261Sdim } while (!eof()); 527249261Sdim addUnwrappedLine(); 528249261Sdim} 529249261Sdim 530252723Sdim// Here we blacklist certain tokens that are not usually the first token in an 531252723Sdim// unwrapped line. This is used in attempt to distinguish macro calls without 532252723Sdim// trailing semicolons from other constructs split to several lines. 533252723Sdimbool tokenCanStartNewLine(clang::Token Tok) { 534252723Sdim // Semicolon can be a null-statement, l_square can be a start of a macro or 535252723Sdim // a C++11 attribute, but this doesn't seem to be common. 536252723Sdim return Tok.isNot(tok::semi) && Tok.isNot(tok::l_brace) && 537252723Sdim Tok.isNot(tok::l_square) && 538252723Sdim // Tokens that can only be used as binary operators and a part of 539252723Sdim // overloaded operator names. 540252723Sdim Tok.isNot(tok::period) && Tok.isNot(tok::periodstar) && 541252723Sdim Tok.isNot(tok::arrow) && Tok.isNot(tok::arrowstar) && 542252723Sdim Tok.isNot(tok::less) && Tok.isNot(tok::greater) && 543252723Sdim Tok.isNot(tok::slash) && Tok.isNot(tok::percent) && 544252723Sdim Tok.isNot(tok::lessless) && Tok.isNot(tok::greatergreater) && 545252723Sdim Tok.isNot(tok::equal) && Tok.isNot(tok::plusequal) && 546252723Sdim Tok.isNot(tok::minusequal) && Tok.isNot(tok::starequal) && 547252723Sdim Tok.isNot(tok::slashequal) && Tok.isNot(tok::percentequal) && 548252723Sdim Tok.isNot(tok::ampequal) && Tok.isNot(tok::pipeequal) && 549252723Sdim Tok.isNot(tok::caretequal) && Tok.isNot(tok::greatergreaterequal) && 550252723Sdim Tok.isNot(tok::lesslessequal) && 551252723Sdim // Colon is used in labels, base class lists, initializer lists, 552252723Sdim // range-based for loops, ternary operator, but should never be the 553252723Sdim // first token in an unwrapped line. 554252723Sdim Tok.isNot(tok::colon); 555252723Sdim} 556252723Sdim 557249261Sdimvoid UnwrappedLineParser::parseStructuralElement() { 558263509Sdim assert(!FormatTok->Tok.is(tok::l_brace)); 559263509Sdim switch (FormatTok->Tok.getKind()) { 560249261Sdim case tok::at: 561249261Sdim nextToken(); 562263509Sdim if (FormatTok->Tok.is(tok::l_brace)) { 563249261Sdim parseBracedList(); 564249261Sdim break; 565249261Sdim } 566263509Sdim switch (FormatTok->Tok.getObjCKeywordID()) { 567249261Sdim case tok::objc_public: 568249261Sdim case tok::objc_protected: 569249261Sdim case tok::objc_package: 570249261Sdim case tok::objc_private: 571249261Sdim return parseAccessSpecifier(); 572249261Sdim case tok::objc_interface: 573249261Sdim case tok::objc_implementation: 574249261Sdim return parseObjCInterfaceOrImplementation(); 575249261Sdim case tok::objc_protocol: 576249261Sdim return parseObjCProtocol(); 577249261Sdim case tok::objc_end: 578249261Sdim return; // Handled by the caller. 579249261Sdim case tok::objc_optional: 580249261Sdim case tok::objc_required: 581249261Sdim nextToken(); 582249261Sdim addUnwrappedLine(); 583249261Sdim return; 584249261Sdim default: 585249261Sdim break; 586249261Sdim } 587249261Sdim break; 588249261Sdim case tok::kw_namespace: 589249261Sdim parseNamespace(); 590249261Sdim return; 591249261Sdim case tok::kw_inline: 592249261Sdim nextToken(); 593263509Sdim if (FormatTok->Tok.is(tok::kw_namespace)) { 594249261Sdim parseNamespace(); 595249261Sdim return; 596249261Sdim } 597249261Sdim break; 598249261Sdim case tok::kw_public: 599249261Sdim case tok::kw_protected: 600249261Sdim case tok::kw_private: 601249261Sdim parseAccessSpecifier(); 602249261Sdim return; 603249261Sdim case tok::kw_if: 604249261Sdim parseIfThenElse(); 605249261Sdim return; 606249261Sdim case tok::kw_for: 607249261Sdim case tok::kw_while: 608249261Sdim parseForOrWhileLoop(); 609249261Sdim return; 610249261Sdim case tok::kw_do: 611249261Sdim parseDoWhile(); 612249261Sdim return; 613249261Sdim case tok::kw_switch: 614249261Sdim parseSwitch(); 615249261Sdim return; 616249261Sdim case tok::kw_default: 617249261Sdim nextToken(); 618249261Sdim parseLabel(); 619249261Sdim return; 620249261Sdim case tok::kw_case: 621249261Sdim parseCaseLabel(); 622249261Sdim return; 623249261Sdim case tok::kw_return: 624249261Sdim parseReturn(); 625249261Sdim return; 626249261Sdim case tok::kw_extern: 627249261Sdim nextToken(); 628263509Sdim if (FormatTok->Tok.is(tok::string_literal)) { 629249261Sdim nextToken(); 630263509Sdim if (FormatTok->Tok.is(tok::l_brace)) { 631263509Sdim parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/false); 632249261Sdim addUnwrappedLine(); 633249261Sdim return; 634249261Sdim } 635249261Sdim } 636249261Sdim // In all other cases, parse the declaration. 637249261Sdim break; 638249261Sdim default: 639249261Sdim break; 640249261Sdim } 641249261Sdim do { 642263509Sdim switch (FormatTok->Tok.getKind()) { 643249261Sdim case tok::at: 644249261Sdim nextToken(); 645263509Sdim if (FormatTok->Tok.is(tok::l_brace)) 646249261Sdim parseBracedList(); 647249261Sdim break; 648249261Sdim case tok::kw_enum: 649249261Sdim parseEnum(); 650249261Sdim break; 651249261Sdim case tok::kw_struct: 652249261Sdim case tok::kw_union: 653249261Sdim case tok::kw_class: 654249261Sdim parseRecord(); 655249261Sdim // A record declaration or definition is always the start of a structural 656249261Sdim // element. 657249261Sdim break; 658249261Sdim case tok::semi: 659249261Sdim nextToken(); 660249261Sdim addUnwrappedLine(); 661249261Sdim return; 662249261Sdim case tok::r_brace: 663249261Sdim addUnwrappedLine(); 664249261Sdim return; 665249261Sdim case tok::l_paren: 666249261Sdim parseParens(); 667249261Sdim break; 668263509Sdim case tok::caret: 669263509Sdim nextToken(); 670263509Sdim if (FormatTok->is(tok::l_brace)) { 671263509Sdim parseChildBlock(); 672263509Sdim } 673263509Sdim break; 674249261Sdim case tok::l_brace: 675263509Sdim if (!tryToParseBracedList()) { 676263509Sdim // A block outside of parentheses must be the last part of a 677263509Sdim // structural element. 678263509Sdim // FIXME: Figure out cases where this is not true, and add projections 679263509Sdim // for them (the one we know is missing are lambdas). 680263509Sdim if (Style.BreakBeforeBraces == FormatStyle::BS_Linux || 681263509Sdim Style.BreakBeforeBraces == FormatStyle::BS_Stroustrup || 682263509Sdim Style.BreakBeforeBraces == FormatStyle::BS_Allman) 683263509Sdim addUnwrappedLine(); 684263509Sdim parseBlock(/*MustBeDeclaration=*/false); 685263509Sdim addUnwrappedLine(); 686263509Sdim return; 687263509Sdim } 688263509Sdim // Otherwise this was a braced init list, and the structural 689263509Sdim // element continues. 690263509Sdim break; 691263509Sdim case tok::identifier: { 692263509Sdim StringRef Text = FormatTok->TokenText; 693249261Sdim nextToken(); 694252723Sdim if (Line->Tokens.size() == 1) { 695263509Sdim if (FormatTok->Tok.is(tok::colon)) { 696252723Sdim parseLabel(); 697252723Sdim return; 698252723Sdim } 699252723Sdim // Recognize function-like macro usages without trailing semicolon. 700263509Sdim if (FormatTok->Tok.is(tok::l_paren)) { 701252723Sdim parseParens(); 702263509Sdim if (FormatTok->HasUnescapedNewline && 703263509Sdim tokenCanStartNewLine(FormatTok->Tok)) { 704252723Sdim addUnwrappedLine(); 705252723Sdim return; 706252723Sdim } 707263509Sdim } else if (FormatTok->HasUnescapedNewline && Text.size() >= 5 && 708263509Sdim Text == Text.upper()) { 709263509Sdim // Recognize free-standing macros like Q_OBJECT. 710263509Sdim addUnwrappedLine(); 711263509Sdim return; 712252723Sdim } 713249261Sdim } 714249261Sdim break; 715263509Sdim } 716249261Sdim case tok::equal: 717249261Sdim nextToken(); 718263509Sdim if (FormatTok->Tok.is(tok::l_brace)) { 719249261Sdim parseBracedList(); 720249261Sdim } 721249261Sdim break; 722263509Sdim case tok::l_square: 723263509Sdim tryToParseLambda(); 724263509Sdim break; 725249261Sdim default: 726249261Sdim nextToken(); 727249261Sdim break; 728249261Sdim } 729249261Sdim } while (!eof()); 730249261Sdim} 731249261Sdim 732263509Sdimvoid UnwrappedLineParser::tryToParseLambda() { 733263509Sdim // FIXME: This is a dirty way to access the previous token. Find a better 734263509Sdim // solution. 735263509Sdim if (!Line->Tokens.empty() && 736263509Sdim Line->Tokens.back().Tok->isOneOf(tok::identifier, tok::kw_operator)) { 737263509Sdim nextToken(); 738263509Sdim return; 739263509Sdim } 740263509Sdim assert(FormatTok->is(tok::l_square)); 741263509Sdim FormatToken &LSquare = *FormatTok; 742263509Sdim if (!tryToParseLambdaIntroducer()) 743263509Sdim return; 744263509Sdim 745263509Sdim while (FormatTok->isNot(tok::l_brace)) { 746263509Sdim switch (FormatTok->Tok.getKind()) { 747263509Sdim case tok::l_brace: 748263509Sdim break; 749263509Sdim case tok::l_paren: 750263509Sdim parseParens(); 751263509Sdim break; 752263509Sdim case tok::identifier: 753263509Sdim case tok::kw_mutable: 754263509Sdim nextToken(); 755263509Sdim break; 756263509Sdim default: 757263509Sdim return; 758263509Sdim } 759263509Sdim } 760263509Sdim LSquare.Type = TT_LambdaLSquare; 761263509Sdim parseChildBlock(); 762263509Sdim} 763263509Sdim 764263509Sdimbool UnwrappedLineParser::tryToParseLambdaIntroducer() { 765249261Sdim nextToken(); 766263509Sdim if (FormatTok->is(tok::equal)) { 767263509Sdim nextToken(); 768263509Sdim if (FormatTok->is(tok::r_square)) { 769263509Sdim nextToken(); 770263509Sdim return true; 771263509Sdim } 772263509Sdim if (FormatTok->isNot(tok::comma)) 773263509Sdim return false; 774263509Sdim nextToken(); 775263509Sdim } else if (FormatTok->is(tok::amp)) { 776263509Sdim nextToken(); 777263509Sdim if (FormatTok->is(tok::r_square)) { 778263509Sdim nextToken(); 779263509Sdim return true; 780263509Sdim } 781263509Sdim if (!FormatTok->isOneOf(tok::comma, tok::identifier)) { 782263509Sdim return false; 783263509Sdim } 784263509Sdim if (FormatTok->is(tok::comma)) 785263509Sdim nextToken(); 786263509Sdim } else if (FormatTok->is(tok::r_square)) { 787263509Sdim nextToken(); 788263509Sdim return true; 789263509Sdim } 790263509Sdim do { 791263509Sdim if (FormatTok->is(tok::amp)) 792263509Sdim nextToken(); 793263509Sdim if (!FormatTok->isOneOf(tok::identifier, tok::kw_this)) 794263509Sdim return false; 795263509Sdim nextToken(); 796263509Sdim if (FormatTok->is(tok::comma)) { 797263509Sdim nextToken(); 798263509Sdim } else if (FormatTok->is(tok::r_square)) { 799263509Sdim nextToken(); 800263509Sdim return true; 801263509Sdim } else { 802263509Sdim return false; 803263509Sdim } 804263509Sdim } while (!eof()); 805263509Sdim return false; 806263509Sdim} 807249261Sdim 808263509Sdimbool UnwrappedLineParser::tryToParseBracedList() { 809263509Sdim if (FormatTok->BlockKind == BK_Unknown) 810263509Sdim calculateBraceTypes(); 811263509Sdim assert(FormatTok->BlockKind != BK_Unknown); 812263509Sdim if (FormatTok->BlockKind == BK_Block) 813263509Sdim return false; 814263509Sdim parseBracedList(); 815263509Sdim return true; 816263509Sdim} 817263509Sdim 818263509Sdimbool UnwrappedLineParser::parseBracedList(bool ContinueOnSemicolons) { 819263509Sdim bool HasError = false; 820263509Sdim nextToken(); 821263509Sdim 822252723Sdim // FIXME: Once we have an expression parser in the UnwrappedLineParser, 823252723Sdim // replace this by using parseAssigmentExpression() inside. 824249261Sdim do { 825252723Sdim // FIXME: When we start to support lambdas, we'll want to parse them away 826252723Sdim // here, otherwise our bail-out scenarios below break. The better solution 827252723Sdim // might be to just implement a more or less complete expression parser. 828263509Sdim switch (FormatTok->Tok.getKind()) { 829263509Sdim case tok::caret: 830263509Sdim nextToken(); 831263509Sdim if (FormatTok->is(tok::l_brace)) { 832263509Sdim parseChildBlock(); 833263509Sdim } 834263509Sdim break; 835263509Sdim case tok::l_square: 836263509Sdim tryToParseLambda(); 837263509Sdim break; 838249261Sdim case tok::l_brace: 839263509Sdim // Assume there are no blocks inside a braced init list apart 840263509Sdim // from the ones we explicitly parse out (like lambdas). 841263509Sdim FormatTok->BlockKind = BK_BracedInit; 842249261Sdim parseBracedList(); 843249261Sdim break; 844249261Sdim case tok::r_brace: 845249261Sdim nextToken(); 846263509Sdim return !HasError; 847252723Sdim case tok::semi: 848263509Sdim HasError = true; 849263509Sdim if (!ContinueOnSemicolons) 850263509Sdim return !HasError; 851263509Sdim nextToken(); 852263509Sdim break; 853252723Sdim case tok::comma: 854252723Sdim nextToken(); 855252723Sdim break; 856249261Sdim default: 857249261Sdim nextToken(); 858249261Sdim break; 859249261Sdim } 860249261Sdim } while (!eof()); 861263509Sdim return false; 862249261Sdim} 863249261Sdim 864249261Sdimvoid UnwrappedLineParser::parseReturn() { 865249261Sdim nextToken(); 866249261Sdim 867249261Sdim do { 868263509Sdim switch (FormatTok->Tok.getKind()) { 869249261Sdim case tok::l_brace: 870249261Sdim parseBracedList(); 871263509Sdim if (FormatTok->Tok.isNot(tok::semi)) { 872252723Sdim // Assume missing ';'. 873252723Sdim addUnwrappedLine(); 874252723Sdim return; 875252723Sdim } 876249261Sdim break; 877249261Sdim case tok::l_paren: 878249261Sdim parseParens(); 879249261Sdim break; 880249261Sdim case tok::r_brace: 881249261Sdim // Assume missing ';'. 882249261Sdim addUnwrappedLine(); 883249261Sdim return; 884249261Sdim case tok::semi: 885249261Sdim nextToken(); 886249261Sdim addUnwrappedLine(); 887249261Sdim return; 888263509Sdim case tok::l_square: 889263509Sdim tryToParseLambda(); 890263509Sdim break; 891249261Sdim default: 892249261Sdim nextToken(); 893249261Sdim break; 894249261Sdim } 895249261Sdim } while (!eof()); 896249261Sdim} 897249261Sdim 898249261Sdimvoid UnwrappedLineParser::parseParens() { 899263509Sdim assert(FormatTok->Tok.is(tok::l_paren) && "'(' expected."); 900249261Sdim nextToken(); 901249261Sdim do { 902263509Sdim switch (FormatTok->Tok.getKind()) { 903249261Sdim case tok::l_paren: 904249261Sdim parseParens(); 905249261Sdim break; 906249261Sdim case tok::r_paren: 907249261Sdim nextToken(); 908249261Sdim return; 909263509Sdim case tok::r_brace: 910263509Sdim // A "}" inside parenthesis is an error if there wasn't a matching "{". 911263509Sdim return; 912263509Sdim case tok::l_square: 913263509Sdim tryToParseLambda(); 914263509Sdim break; 915249261Sdim case tok::l_brace: { 916263509Sdim if (!tryToParseBracedList()) { 917263509Sdim parseChildBlock(); 918263509Sdim } 919249261Sdim break; 920249261Sdim } 921249261Sdim case tok::at: 922249261Sdim nextToken(); 923263509Sdim if (FormatTok->Tok.is(tok::l_brace)) 924249261Sdim parseBracedList(); 925249261Sdim break; 926249261Sdim default: 927249261Sdim nextToken(); 928249261Sdim break; 929249261Sdim } 930249261Sdim } while (!eof()); 931249261Sdim} 932249261Sdim 933249261Sdimvoid UnwrappedLineParser::parseIfThenElse() { 934263509Sdim assert(FormatTok->Tok.is(tok::kw_if) && "'if' expected"); 935249261Sdim nextToken(); 936263509Sdim if (FormatTok->Tok.is(tok::l_paren)) 937249261Sdim parseParens(); 938249261Sdim bool NeedsUnwrappedLine = false; 939263509Sdim if (FormatTok->Tok.is(tok::l_brace)) { 940263509Sdim if (Style.BreakBeforeBraces == FormatStyle::BS_Allman) 941263509Sdim addUnwrappedLine(); 942263509Sdim parseBlock(/*MustBeDeclaration=*/false); 943263509Sdim if (Style.BreakBeforeBraces == FormatStyle::BS_Allman) 944263509Sdim addUnwrappedLine(); 945263509Sdim else 946263509Sdim NeedsUnwrappedLine = true; 947249261Sdim } else { 948249261Sdim addUnwrappedLine(); 949249261Sdim ++Line->Level; 950249261Sdim parseStructuralElement(); 951249261Sdim --Line->Level; 952249261Sdim } 953263509Sdim if (FormatTok->Tok.is(tok::kw_else)) { 954249261Sdim nextToken(); 955263509Sdim if (FormatTok->Tok.is(tok::l_brace)) { 956263509Sdim if (Style.BreakBeforeBraces == FormatStyle::BS_Allman) 957263509Sdim addUnwrappedLine(); 958263509Sdim parseBlock(/*MustBeDeclaration=*/false); 959249261Sdim addUnwrappedLine(); 960263509Sdim } else if (FormatTok->Tok.is(tok::kw_if)) { 961249261Sdim parseIfThenElse(); 962249261Sdim } else { 963249261Sdim addUnwrappedLine(); 964249261Sdim ++Line->Level; 965249261Sdim parseStructuralElement(); 966249261Sdim --Line->Level; 967249261Sdim } 968249261Sdim } else if (NeedsUnwrappedLine) { 969249261Sdim addUnwrappedLine(); 970249261Sdim } 971249261Sdim} 972249261Sdim 973249261Sdimvoid UnwrappedLineParser::parseNamespace() { 974263509Sdim assert(FormatTok->Tok.is(tok::kw_namespace) && "'namespace' expected"); 975249261Sdim nextToken(); 976263509Sdim if (FormatTok->Tok.is(tok::identifier)) 977249261Sdim nextToken(); 978263509Sdim if (FormatTok->Tok.is(tok::l_brace)) { 979263509Sdim if (Style.BreakBeforeBraces == FormatStyle::BS_Linux || 980263509Sdim Style.BreakBeforeBraces == FormatStyle::BS_Allman) 981263509Sdim addUnwrappedLine(); 982263509Sdim 983263509Sdim bool AddLevel = Style.NamespaceIndentation == FormatStyle::NI_All || 984263509Sdim (Style.NamespaceIndentation == FormatStyle::NI_Inner && 985263509Sdim DeclarationScopeStack.size() > 1); 986263509Sdim parseBlock(/*MustBeDeclaration=*/true, AddLevel); 987249261Sdim // Munch the semicolon after a namespace. This is more common than one would 988249261Sdim // think. Puttin the semicolon into its own line is very ugly. 989263509Sdim if (FormatTok->Tok.is(tok::semi)) 990249261Sdim nextToken(); 991249261Sdim addUnwrappedLine(); 992249261Sdim } 993249261Sdim // FIXME: Add error handling. 994249261Sdim} 995249261Sdim 996249261Sdimvoid UnwrappedLineParser::parseForOrWhileLoop() { 997263509Sdim assert((FormatTok->Tok.is(tok::kw_for) || FormatTok->Tok.is(tok::kw_while)) && 998249261Sdim "'for' or 'while' expected"); 999249261Sdim nextToken(); 1000263509Sdim if (FormatTok->Tok.is(tok::l_paren)) 1001249261Sdim parseParens(); 1002263509Sdim if (FormatTok->Tok.is(tok::l_brace)) { 1003263509Sdim if (Style.BreakBeforeBraces == FormatStyle::BS_Allman) 1004263509Sdim addUnwrappedLine(); 1005263509Sdim parseBlock(/*MustBeDeclaration=*/false); 1006249261Sdim addUnwrappedLine(); 1007249261Sdim } else { 1008249261Sdim addUnwrappedLine(); 1009249261Sdim ++Line->Level; 1010249261Sdim parseStructuralElement(); 1011249261Sdim --Line->Level; 1012249261Sdim } 1013249261Sdim} 1014249261Sdim 1015249261Sdimvoid UnwrappedLineParser::parseDoWhile() { 1016263509Sdim assert(FormatTok->Tok.is(tok::kw_do) && "'do' expected"); 1017249261Sdim nextToken(); 1018263509Sdim if (FormatTok->Tok.is(tok::l_brace)) { 1019263509Sdim if (Style.BreakBeforeBraces == FormatStyle::BS_Allman) 1020263509Sdim addUnwrappedLine(); 1021263509Sdim parseBlock(/*MustBeDeclaration=*/false); 1022249261Sdim } else { 1023249261Sdim addUnwrappedLine(); 1024249261Sdim ++Line->Level; 1025249261Sdim parseStructuralElement(); 1026249261Sdim --Line->Level; 1027249261Sdim } 1028249261Sdim 1029249261Sdim // FIXME: Add error handling. 1030263509Sdim if (!FormatTok->Tok.is(tok::kw_while)) { 1031249261Sdim addUnwrappedLine(); 1032249261Sdim return; 1033249261Sdim } 1034249261Sdim 1035249261Sdim nextToken(); 1036249261Sdim parseStructuralElement(); 1037249261Sdim} 1038249261Sdim 1039249261Sdimvoid UnwrappedLineParser::parseLabel() { 1040249261Sdim nextToken(); 1041249261Sdim unsigned OldLineLevel = Line->Level; 1042249261Sdim if (Line->Level > 1 || (!Line->InPPDirective && Line->Level > 0)) 1043249261Sdim --Line->Level; 1044263509Sdim if (CommentsBeforeNextToken.empty() && FormatTok->Tok.is(tok::l_brace)) { 1045263509Sdim if (Style.BreakBeforeBraces == FormatStyle::BS_Allman) 1046263509Sdim addUnwrappedLine(); 1047263509Sdim parseBlock(/*MustBeDeclaration=*/false); 1048263509Sdim if (FormatTok->Tok.is(tok::kw_break)) { 1049263509Sdim // "break;" after "}" on its own line only for BS_Allman 1050263509Sdim if (Style.BreakBeforeBraces == FormatStyle::BS_Allman) 1051263509Sdim addUnwrappedLine(); 1052263509Sdim parseStructuralElement(); 1053263509Sdim } 1054249261Sdim } 1055249261Sdim addUnwrappedLine(); 1056249261Sdim Line->Level = OldLineLevel; 1057249261Sdim} 1058249261Sdim 1059249261Sdimvoid UnwrappedLineParser::parseCaseLabel() { 1060263509Sdim assert(FormatTok->Tok.is(tok::kw_case) && "'case' expected"); 1061249261Sdim // FIXME: fix handling of complex expressions here. 1062249261Sdim do { 1063249261Sdim nextToken(); 1064263509Sdim } while (!eof() && !FormatTok->Tok.is(tok::colon)); 1065249261Sdim parseLabel(); 1066249261Sdim} 1067249261Sdim 1068249261Sdimvoid UnwrappedLineParser::parseSwitch() { 1069263509Sdim assert(FormatTok->Tok.is(tok::kw_switch) && "'switch' expected"); 1070249261Sdim nextToken(); 1071263509Sdim if (FormatTok->Tok.is(tok::l_paren)) 1072249261Sdim parseParens(); 1073263509Sdim if (FormatTok->Tok.is(tok::l_brace)) { 1074263509Sdim if (Style.BreakBeforeBraces == FormatStyle::BS_Allman) 1075263509Sdim addUnwrappedLine(); 1076263509Sdim parseBlock(/*MustBeDeclaration=*/false); 1077249261Sdim addUnwrappedLine(); 1078249261Sdim } else { 1079249261Sdim addUnwrappedLine(); 1080263509Sdim ++Line->Level; 1081249261Sdim parseStructuralElement(); 1082263509Sdim --Line->Level; 1083249261Sdim } 1084249261Sdim} 1085249261Sdim 1086249261Sdimvoid UnwrappedLineParser::parseAccessSpecifier() { 1087249261Sdim nextToken(); 1088249261Sdim // Otherwise, we don't know what it is, and we'd better keep the next token. 1089263509Sdim if (FormatTok->Tok.is(tok::colon)) 1090249261Sdim nextToken(); 1091249261Sdim addUnwrappedLine(); 1092249261Sdim} 1093249261Sdim 1094249261Sdimvoid UnwrappedLineParser::parseEnum() { 1095249261Sdim nextToken(); 1096263509Sdim // Eat up enum class ... 1097263509Sdim if (FormatTok->Tok.is(tok::kw_class) || 1098263509Sdim FormatTok->Tok.is(tok::kw_struct)) 1099263509Sdim nextToken(); 1100263509Sdim while (FormatTok->Tok.getIdentifierInfo() || 1101263509Sdim FormatTok->isOneOf(tok::colon, tok::coloncolon)) { 1102249261Sdim nextToken(); 1103249261Sdim // We can have macros or attributes in between 'enum' and the enum name. 1104263509Sdim if (FormatTok->Tok.is(tok::l_paren)) { 1105249261Sdim parseParens(); 1106249261Sdim } 1107263509Sdim if (FormatTok->Tok.is(tok::identifier)) 1108249261Sdim nextToken(); 1109249261Sdim } 1110263509Sdim if (FormatTok->Tok.is(tok::l_brace)) { 1111263509Sdim FormatTok->BlockKind = BK_Block; 1112263509Sdim bool HasError = !parseBracedList(/*ContinueOnSemicolons=*/true); 1113263509Sdim if (HasError) { 1114263509Sdim if (FormatTok->is(tok::semi)) 1115249261Sdim nextToken(); 1116263509Sdim addUnwrappedLine(); 1117263509Sdim } 1118249261Sdim } 1119249261Sdim // We fall through to parsing a structural element afterwards, so that in 1120249261Sdim // enum A {} n, m; 1121249261Sdim // "} n, m;" will end up in one unwrapped line. 1122249261Sdim} 1123249261Sdim 1124249261Sdimvoid UnwrappedLineParser::parseRecord() { 1125249261Sdim nextToken(); 1126263509Sdim if (FormatTok->Tok.is(tok::identifier) || 1127263509Sdim FormatTok->Tok.is(tok::kw___attribute) || 1128263509Sdim FormatTok->Tok.is(tok::kw___declspec) || 1129263509Sdim FormatTok->Tok.is(tok::kw_alignas)) { 1130249261Sdim nextToken(); 1131249261Sdim // We can have macros or attributes in between 'class' and the class name. 1132263509Sdim if (FormatTok->Tok.is(tok::l_paren)) { 1133249261Sdim parseParens(); 1134249261Sdim } 1135249261Sdim // The actual identifier can be a nested name specifier, and in macros 1136249261Sdim // it is often token-pasted. 1137263509Sdim while (FormatTok->Tok.is(tok::identifier) || 1138263509Sdim FormatTok->Tok.is(tok::coloncolon) || 1139263509Sdim FormatTok->Tok.is(tok::hashhash)) 1140249261Sdim nextToken(); 1141249261Sdim 1142249261Sdim // Note that parsing away template declarations here leads to incorrectly 1143249261Sdim // accepting function declarations as record declarations. 1144249261Sdim // In general, we cannot solve this problem. Consider: 1145249261Sdim // class A<int> B() {} 1146249261Sdim // which can be a function definition or a class definition when B() is a 1147249261Sdim // macro. If we find enough real-world cases where this is a problem, we 1148249261Sdim // can parse for the 'template' keyword in the beginning of the statement, 1149249261Sdim // and thus rule out the record production in case there is no template 1150249261Sdim // (this would still leave us with an ambiguity between template function 1151249261Sdim // and class declarations). 1152263509Sdim if (FormatTok->Tok.is(tok::colon) || FormatTok->Tok.is(tok::less)) { 1153263509Sdim while (!eof() && FormatTok->Tok.isNot(tok::l_brace)) { 1154263509Sdim if (FormatTok->Tok.is(tok::semi)) 1155249261Sdim return; 1156249261Sdim nextToken(); 1157249261Sdim } 1158249261Sdim } 1159249261Sdim } 1160263509Sdim if (FormatTok->Tok.is(tok::l_brace)) { 1161263509Sdim if (Style.BreakBeforeBraces == FormatStyle::BS_Linux || 1162263509Sdim Style.BreakBeforeBraces == FormatStyle::BS_Allman) 1163263509Sdim addUnwrappedLine(); 1164263509Sdim 1165263509Sdim parseBlock(/*MustBeDeclaration=*/true, /*Addlevel=*/true, 1166263509Sdim /*MunchSemi=*/false); 1167263509Sdim } 1168249261Sdim // We fall through to parsing a structural element afterwards, so 1169249261Sdim // class A {} n, m; 1170249261Sdim // will end up in one unwrapped line. 1171249261Sdim} 1172249261Sdim 1173249261Sdimvoid UnwrappedLineParser::parseObjCProtocolList() { 1174263509Sdim assert(FormatTok->Tok.is(tok::less) && "'<' expected."); 1175249261Sdim do 1176249261Sdim nextToken(); 1177263509Sdim while (!eof() && FormatTok->Tok.isNot(tok::greater)); 1178249261Sdim nextToken(); // Skip '>'. 1179249261Sdim} 1180249261Sdim 1181249261Sdimvoid UnwrappedLineParser::parseObjCUntilAtEnd() { 1182249261Sdim do { 1183263509Sdim if (FormatTok->Tok.isObjCAtKeyword(tok::objc_end)) { 1184249261Sdim nextToken(); 1185249261Sdim addUnwrappedLine(); 1186249261Sdim break; 1187249261Sdim } 1188263509Sdim if (FormatTok->is(tok::l_brace)) { 1189263509Sdim parseBlock(/*MustBeDeclaration=*/false); 1190263509Sdim // In ObjC interfaces, nothing should be following the "}". 1191263509Sdim addUnwrappedLine(); 1192263509Sdim } else { 1193263509Sdim parseStructuralElement(); 1194263509Sdim } 1195249261Sdim } while (!eof()); 1196249261Sdim} 1197249261Sdim 1198249261Sdimvoid UnwrappedLineParser::parseObjCInterfaceOrImplementation() { 1199249261Sdim nextToken(); 1200249261Sdim nextToken(); // interface name 1201249261Sdim 1202249261Sdim // @interface can be followed by either a base class, or a category. 1203263509Sdim if (FormatTok->Tok.is(tok::colon)) { 1204249261Sdim nextToken(); 1205249261Sdim nextToken(); // base class name 1206263509Sdim } else if (FormatTok->Tok.is(tok::l_paren)) 1207249261Sdim // Skip category, if present. 1208249261Sdim parseParens(); 1209249261Sdim 1210263509Sdim if (FormatTok->Tok.is(tok::less)) 1211249261Sdim parseObjCProtocolList(); 1212249261Sdim 1213249261Sdim // If instance variables are present, keep the '{' on the first line too. 1214263509Sdim if (FormatTok->Tok.is(tok::l_brace)) 1215263509Sdim parseBlock(/*MustBeDeclaration=*/true); 1216249261Sdim 1217249261Sdim // With instance variables, this puts '}' on its own line. Without instance 1218249261Sdim // variables, this ends the @interface line. 1219249261Sdim addUnwrappedLine(); 1220249261Sdim 1221249261Sdim parseObjCUntilAtEnd(); 1222249261Sdim} 1223249261Sdim 1224249261Sdimvoid UnwrappedLineParser::parseObjCProtocol() { 1225249261Sdim nextToken(); 1226249261Sdim nextToken(); // protocol name 1227249261Sdim 1228263509Sdim if (FormatTok->Tok.is(tok::less)) 1229249261Sdim parseObjCProtocolList(); 1230249261Sdim 1231249261Sdim // Check for protocol declaration. 1232263509Sdim if (FormatTok->Tok.is(tok::semi)) { 1233249261Sdim nextToken(); 1234249261Sdim return addUnwrappedLine(); 1235249261Sdim } 1236249261Sdim 1237249261Sdim addUnwrappedLine(); 1238249261Sdim parseObjCUntilAtEnd(); 1239249261Sdim} 1240249261Sdim 1241263509SdimLLVM_ATTRIBUTE_UNUSED static void printDebugInfo(const UnwrappedLine &Line, 1242263509Sdim StringRef Prefix = "") { 1243263509Sdim llvm::dbgs() << Prefix << "Line(" << Line.Level << ")" 1244263509Sdim << (Line.InPPDirective ? " MACRO" : "") << ": "; 1245263509Sdim for (std::list<UnwrappedLineNode>::const_iterator I = Line.Tokens.begin(), 1246263509Sdim E = Line.Tokens.end(); 1247263509Sdim I != E; ++I) { 1248263509Sdim llvm::dbgs() << I->Tok->Tok.getName() << "[" << I->Tok->Type << "] "; 1249263509Sdim } 1250263509Sdim for (std::list<UnwrappedLineNode>::const_iterator I = Line.Tokens.begin(), 1251263509Sdim E = Line.Tokens.end(); 1252263509Sdim I != E; ++I) { 1253263509Sdim const UnwrappedLineNode &Node = *I; 1254263509Sdim for (SmallVectorImpl<UnwrappedLine>::const_iterator 1255263509Sdim I = Node.Children.begin(), 1256263509Sdim E = Node.Children.end(); 1257263509Sdim I != E; ++I) { 1258263509Sdim printDebugInfo(*I, "\nChild: "); 1259263509Sdim } 1260263509Sdim } 1261263509Sdim llvm::dbgs() << "\n"; 1262263509Sdim} 1263263509Sdim 1264249261Sdimvoid UnwrappedLineParser::addUnwrappedLine() { 1265249261Sdim if (Line->Tokens.empty()) 1266249261Sdim return; 1267249261Sdim DEBUG({ 1268263509Sdim if (CurrentLines == &Lines) 1269263509Sdim printDebugInfo(*Line); 1270249261Sdim }); 1271249261Sdim CurrentLines->push_back(*Line); 1272249261Sdim Line->Tokens.clear(); 1273249261Sdim if (CurrentLines == &Lines && !PreprocessorDirectives.empty()) { 1274263509Sdim for (SmallVectorImpl<UnwrappedLine>::iterator 1275249261Sdim I = PreprocessorDirectives.begin(), 1276249261Sdim E = PreprocessorDirectives.end(); 1277249261Sdim I != E; ++I) { 1278249261Sdim CurrentLines->push_back(*I); 1279249261Sdim } 1280249261Sdim PreprocessorDirectives.clear(); 1281249261Sdim } 1282249261Sdim} 1283249261Sdim 1284263509Sdimbool UnwrappedLineParser::eof() const { return FormatTok->Tok.is(tok::eof); } 1285249261Sdim 1286249261Sdimvoid UnwrappedLineParser::flushComments(bool NewlineBeforeNext) { 1287249261Sdim bool JustComments = Line->Tokens.empty(); 1288263509Sdim for (SmallVectorImpl<FormatToken *>::const_iterator 1289249261Sdim I = CommentsBeforeNextToken.begin(), 1290249261Sdim E = CommentsBeforeNextToken.end(); 1291249261Sdim I != E; ++I) { 1292263509Sdim if ((*I)->NewlinesBefore && JustComments) { 1293249261Sdim addUnwrappedLine(); 1294249261Sdim } 1295249261Sdim pushToken(*I); 1296249261Sdim } 1297249261Sdim if (NewlineBeforeNext && JustComments) { 1298249261Sdim addUnwrappedLine(); 1299249261Sdim } 1300249261Sdim CommentsBeforeNextToken.clear(); 1301249261Sdim} 1302249261Sdim 1303249261Sdimvoid UnwrappedLineParser::nextToken() { 1304249261Sdim if (eof()) 1305249261Sdim return; 1306263509Sdim flushComments(FormatTok->NewlinesBefore > 0); 1307249261Sdim pushToken(FormatTok); 1308249261Sdim readToken(); 1309249261Sdim} 1310249261Sdim 1311249261Sdimvoid UnwrappedLineParser::readToken() { 1312249261Sdim bool CommentsInCurrentLine = true; 1313249261Sdim do { 1314249261Sdim FormatTok = Tokens->getNextToken(); 1315263509Sdim while (!Line->InPPDirective && FormatTok->Tok.is(tok::hash) && 1316263509Sdim (FormatTok->HasUnescapedNewline || FormatTok->IsFirst)) { 1317249261Sdim // If there is an unfinished unwrapped line, we flush the preprocessor 1318249261Sdim // directives only after that unwrapped line was finished later. 1319249261Sdim bool SwitchToPreprocessorLines = 1320249261Sdim !Line->Tokens.empty() && CurrentLines == &Lines; 1321249261Sdim ScopedLineState BlockState(*this, SwitchToPreprocessorLines); 1322249261Sdim // Comments stored before the preprocessor directive need to be output 1323249261Sdim // before the preprocessor directive, at the same level as the 1324249261Sdim // preprocessor directive, as we consider them to apply to the directive. 1325263509Sdim flushComments(FormatTok->NewlinesBefore > 0); 1326249261Sdim parsePPDirective(); 1327249261Sdim } 1328263509Sdim 1329263509Sdim if (!PPStack.empty() && (PPStack.back() == PP_Unreachable) && 1330263509Sdim !Line->InPPDirective) { 1331263509Sdim continue; 1332263509Sdim } 1333263509Sdim 1334263509Sdim if (!FormatTok->Tok.is(tok::comment)) 1335249261Sdim return; 1336263509Sdim if (FormatTok->NewlinesBefore > 0 || FormatTok->IsFirst) { 1337249261Sdim CommentsInCurrentLine = false; 1338249261Sdim } 1339249261Sdim if (CommentsInCurrentLine) { 1340249261Sdim pushToken(FormatTok); 1341249261Sdim } else { 1342249261Sdim CommentsBeforeNextToken.push_back(FormatTok); 1343249261Sdim } 1344249261Sdim } while (!eof()); 1345249261Sdim} 1346249261Sdim 1347263509Sdimvoid UnwrappedLineParser::pushToken(FormatToken *Tok) { 1348263509Sdim Line->Tokens.push_back(UnwrappedLineNode(Tok)); 1349249261Sdim if (MustBreakBeforeNextToken) { 1350263509Sdim Line->Tokens.back().Tok->MustBreakBefore = true; 1351249261Sdim MustBreakBeforeNextToken = false; 1352249261Sdim } 1353249261Sdim} 1354249261Sdim 1355249261Sdim} // end namespace format 1356249261Sdim} // end namespace clang 1357