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 24263508Sdimclass FormatTokenSource { 25263508Sdimpublic: 26263508Sdim virtual ~FormatTokenSource() {} 27263508Sdim virtual FormatToken *getNextToken() = 0; 28263508Sdim 29263508Sdim virtual unsigned getPosition() = 0; 30263508Sdim virtual FormatToken *setPosition(unsigned Position) = 0; 31263508Sdim}; 32263508Sdim 33263508Sdimnamespace { 34263508Sdim 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 } 50263508Sdim 51249261Sdimprivate: 52249261Sdim UnwrappedLine &Line; 53249261Sdim std::vector<bool> &Stack; 54249261Sdim}; 55249261Sdim 56249261Sdimclass ScopedMacroState : public FormatTokenSource { 57249261Sdimpublic: 58249261Sdim ScopedMacroState(UnwrappedLine &Line, FormatTokenSource *&TokenSource, 59263508Sdim FormatToken *&ResetToken, bool &StructuralError) 60249261Sdim : Line(Line), TokenSource(TokenSource), ResetToken(ResetToken), 61251662Sdim PreviousLineLevel(Line.Level), PreviousTokenSource(TokenSource), 62251662Sdim StructuralError(StructuralError), 63263508Sdim 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; 74251662Sdim StructuralError = PreviousStructuralError; 75249261Sdim } 76249261Sdim 77263508Sdim 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()) 83263508Sdim return getFakeEOF(); 84249261Sdim return Token; 85249261Sdim } 86249261Sdim 87263508Sdim virtual unsigned getPosition() { return PreviousTokenSource->getPosition(); } 88263508Sdim 89263508Sdim virtual FormatToken *setPosition(unsigned Position) { 90263508Sdim Token = PreviousTokenSource->setPosition(Position); 91263508Sdim return Token; 92263508Sdim } 93263508Sdim 94249261Sdimprivate: 95263508Sdim bool eof() { return Token && Token->HasUnescapedNewline; } 96249261Sdim 97263508Sdim FormatToken *getFakeEOF() { 98263508Sdim static bool EOFInitialized = false; 99263508Sdim static FormatToken FormatTok; 100263508Sdim if (!EOFInitialized) { 101263508Sdim FormatTok.Tok.startToken(); 102263508Sdim FormatTok.Tok.setKind(tok::eof); 103263508Sdim EOFInitialized = true; 104263508Sdim } 105263508Sdim return &FormatTok; 106249261Sdim } 107249261Sdim 108249261Sdim UnwrappedLine &Line; 109249261Sdim FormatTokenSource *&TokenSource; 110263508Sdim FormatToken *&ResetToken; 111249261Sdim unsigned PreviousLineLevel; 112249261Sdim FormatTokenSource *PreviousTokenSource; 113251662Sdim bool &StructuralError; 114251662Sdim bool PreviousStructuralError; 115249261Sdim 116263508Sdim FormatToken *Token; 117249261Sdim}; 118249261Sdim 119263508Sdim} // end anonymous namespace 120263508Sdim 121249261Sdimclass ScopedLineState { 122249261Sdimpublic: 123249261Sdim ScopedLineState(UnwrappedLineParser &Parser, 124249261Sdim bool SwitchToPreprocessorLines = false) 125263508Sdim : Parser(Parser) { 126263508Sdim OriginalLines = Parser.CurrentLines; 127249261Sdim if (SwitchToPreprocessorLines) 128249261Sdim Parser.CurrentLines = &Parser.PreprocessorDirectives; 129263508Sdim else if (!Parser.Line->Tokens.empty()) 130263508Sdim 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); 143263508Sdim if (Parser.CurrentLines == &Parser.PreprocessorDirectives) 144263508Sdim Parser.MustBreakBeforeNextToken = true; 145263508Sdim Parser.CurrentLines = OriginalLines; 146249261Sdim } 147249261Sdim 148249261Sdimprivate: 149249261Sdim UnwrappedLineParser &Parser; 150249261Sdim 151249261Sdim UnwrappedLine *PreBlockLine; 152263508Sdim SmallVectorImpl<UnwrappedLine> *OriginalLines; 153249261Sdim}; 154249261Sdim 155263508Sdimnamespace { 156263508Sdim 157263508Sdimclass IndexedTokenSource : public FormatTokenSource { 158263508Sdimpublic: 159263508Sdim IndexedTokenSource(ArrayRef<FormatToken *> Tokens) 160263508Sdim : Tokens(Tokens), Position(-1) {} 161263508Sdim 162263508Sdim virtual FormatToken *getNextToken() { 163263508Sdim ++Position; 164263508Sdim return Tokens[Position]; 165263508Sdim } 166263508Sdim 167263508Sdim virtual unsigned getPosition() { 168263508Sdim assert(Position >= 0); 169263508Sdim return Position; 170263508Sdim } 171263508Sdim 172263508Sdim virtual FormatToken *setPosition(unsigned P) { 173263508Sdim Position = P; 174263508Sdim return Tokens[Position]; 175263508Sdim } 176263508Sdim 177263508Sdim void reset() { Position = -1; } 178263508Sdim 179263508Sdimprivate: 180263508Sdim ArrayRef<FormatToken *> Tokens; 181263508Sdim int Position; 182263508Sdim}; 183263508Sdim 184263508Sdim} // end anonymous namespace 185263508Sdim 186263508SdimUnwrappedLineParser::UnwrappedLineParser(const FormatStyle &Style, 187263508Sdim ArrayRef<FormatToken *> Tokens, 188263508Sdim UnwrappedLineConsumer &Callback) 189249261Sdim : Line(new UnwrappedLine), MustBreakBeforeNextToken(false), 190263508Sdim CurrentLines(&Lines), StructuralError(false), Style(Style), Tokens(NULL), 191263508Sdim Callback(Callback), AllTokens(Tokens), PPBranchLevel(-1) {} 192249261Sdim 193263508Sdimvoid UnwrappedLineParser::reset() { 194263508Sdim PPBranchLevel = -1; 195263508Sdim Line.reset(new UnwrappedLine); 196263508Sdim CommentsBeforeNextToken.clear(); 197263508Sdim FormatTok = NULL; 198263508Sdim MustBreakBeforeNextToken = false; 199263508Sdim PreprocessorDirectives.clear(); 200263508Sdim CurrentLines = &Lines; 201263508Sdim DeclarationScopeStack.clear(); 202263508Sdim StructuralError = false; 203263508Sdim PPStack.clear(); 204263508Sdim} 205263508Sdim 206249261Sdimbool UnwrappedLineParser::parse() { 207263508Sdim IndexedTokenSource TokenSource(AllTokens); 208263508Sdim do { 209263508Sdim DEBUG(llvm::dbgs() << "----\n"); 210263508Sdim reset(); 211263508Sdim Tokens = &TokenSource; 212263508Sdim TokenSource.reset(); 213249261Sdim 214263508Sdim readToken(); 215263508Sdim parseFile(); 216263508Sdim // Create line with eof token. 217263508Sdim pushToken(FormatTok); 218263508Sdim addUnwrappedLine(); 219263508Sdim 220263508Sdim for (SmallVectorImpl<UnwrappedLine>::iterator I = Lines.begin(), 221263508Sdim E = Lines.end(); 222263508Sdim I != E; ++I) { 223263508Sdim Callback.consumeUnwrappedLine(*I); 224263508Sdim } 225263508Sdim Callback.finishRun(); 226263508Sdim Lines.clear(); 227263508Sdim while (!PPLevelBranchIndex.empty() && 228263508Sdim PPLevelBranchIndex.back() + 1 >= PPLevelBranchCount.back()) { 229263508Sdim PPLevelBranchIndex.resize(PPLevelBranchIndex.size() - 1); 230263508Sdim PPLevelBranchCount.resize(PPLevelBranchCount.size() - 1); 231263508Sdim } 232263508Sdim if (!PPLevelBranchIndex.empty()) { 233263508Sdim ++PPLevelBranchIndex.back(); 234263508Sdim assert(PPLevelBranchIndex.size() == PPLevelBranchCount.size()); 235263508Sdim assert(PPLevelBranchIndex.back() <= PPLevelBranchCount.back()); 236263508Sdim } 237263508Sdim } while (!PPLevelBranchIndex.empty()); 238263508Sdim 239251662Sdim return StructuralError; 240249261Sdim} 241249261Sdim 242251662Sdimvoid UnwrappedLineParser::parseFile() { 243249261Sdim ScopedDeclarationState DeclarationState( 244249261Sdim *Line, DeclarationScopeStack, 245249261Sdim /*MustBeDeclaration=*/ !Line->InPPDirective); 246263508Sdim parseLevel(/*HasOpeningBrace=*/false); 247249261Sdim // Make sure to format the remaining tokens. 248249261Sdim flushComments(true); 249249261Sdim addUnwrappedLine(); 250249261Sdim} 251249261Sdim 252251662Sdimvoid UnwrappedLineParser::parseLevel(bool HasOpeningBrace) { 253263508Sdim bool SwitchLabelEncountered = false; 254249261Sdim do { 255263508Sdim 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. 263263508Sdim parseBlock(/*MustBeDeclaration=*/false); 264249261Sdim addUnwrappedLine(); 265249261Sdim break; 266249261Sdim case tok::r_brace: 267251662Sdim if (HasOpeningBrace) 268251662Sdim return; 269251662Sdim StructuralError = true; 270251662Sdim nextToken(); 271251662Sdim addUnwrappedLine(); 272249261Sdim break; 273263508Sdim case tok::kw_default: 274263508Sdim case tok::kw_case: 275263508Sdim if (!SwitchLabelEncountered && 276263508Sdim (Style.IndentCaseLabels || (Line->InPPDirective && Line->Level == 1))) 277263508Sdim ++Line->Level; 278263508Sdim SwitchLabelEncountered = true; 279263508Sdim parseStructuralElement(); 280263508Sdim break; 281249261Sdim default: 282249261Sdim parseStructuralElement(); 283249261Sdim break; 284249261Sdim } 285249261Sdim } while (!eof()); 286249261Sdim} 287249261Sdim 288263508Sdimvoid UnwrappedLineParser::calculateBraceTypes() { 289263508Sdim // We'll parse forward through the tokens until we hit 290263508Sdim // a closing brace or eof - note that getNextToken() will 291263508Sdim // parse macros, so this will magically work inside macro 292263508Sdim // definitions, too. 293263508Sdim unsigned StoredPosition = Tokens->getPosition(); 294263508Sdim unsigned Position = StoredPosition; 295263508Sdim FormatToken *Tok = FormatTok; 296263508Sdim // Keep a stack of positions of lbrace tokens. We will 297263508Sdim // update information about whether an lbrace starts a 298263508Sdim // braced init list or a different block during the loop. 299263508Sdim SmallVector<FormatToken *, 8> LBraceStack; 300263508Sdim assert(Tok->Tok.is(tok::l_brace)); 301263508Sdim do { 302263508Sdim // Get next none-comment token. 303263508Sdim FormatToken *NextTok; 304263508Sdim unsigned ReadTokens = 0; 305263508Sdim do { 306263508Sdim NextTok = Tokens->getNextToken(); 307263508Sdim ++ReadTokens; 308263508Sdim } while (NextTok->is(tok::comment)); 309263508Sdim 310263508Sdim switch (Tok->Tok.getKind()) { 311263508Sdim case tok::l_brace: 312263508Sdim LBraceStack.push_back(Tok); 313263508Sdim break; 314263508Sdim case tok::r_brace: 315263508Sdim if (!LBraceStack.empty()) { 316263508Sdim if (LBraceStack.back()->BlockKind == BK_Unknown) { 317263508Sdim // If there is a comma, semicolon or right paren after the closing 318263508Sdim // brace, we assume this is a braced initializer list. Note that 319263508Sdim // regardless how we mark inner braces here, we will overwrite the 320263508Sdim // BlockKind later if we parse a braced list (where all blocks inside 321263508Sdim // are by default braced lists), or when we explicitly detect blocks 322263508Sdim // (for example while parsing lambdas). 323263508Sdim // 324263508Sdim // We exclude + and - as they can be ObjC visibility modifiers. 325263508Sdim if (NextTok->isOneOf(tok::comma, tok::semi, tok::r_paren, 326263508Sdim tok::r_square, tok::l_brace, tok::colon) || 327263508Sdim (NextTok->isBinaryOperator() && 328263508Sdim !NextTok->isOneOf(tok::plus, tok::minus))) { 329263508Sdim Tok->BlockKind = BK_BracedInit; 330263508Sdim LBraceStack.back()->BlockKind = BK_BracedInit; 331263508Sdim } else { 332263508Sdim Tok->BlockKind = BK_Block; 333263508Sdim LBraceStack.back()->BlockKind = BK_Block; 334263508Sdim } 335263508Sdim } 336263508Sdim LBraceStack.pop_back(); 337263508Sdim } 338263508Sdim break; 339263508Sdim case tok::semi: 340263508Sdim case tok::kw_if: 341263508Sdim case tok::kw_while: 342263508Sdim case tok::kw_for: 343263508Sdim case tok::kw_switch: 344263508Sdim case tok::kw_try: 345263508Sdim if (!LBraceStack.empty()) 346263508Sdim LBraceStack.back()->BlockKind = BK_Block; 347263508Sdim break; 348263508Sdim default: 349263508Sdim break; 350263508Sdim } 351263508Sdim Tok = NextTok; 352263508Sdim Position += ReadTokens; 353263508Sdim } while (Tok->Tok.isNot(tok::eof) && !LBraceStack.empty()); 354263508Sdim // Assume other blocks for all unclosed opening braces. 355263508Sdim for (unsigned i = 0, e = LBraceStack.size(); i != e; ++i) { 356263508Sdim if (LBraceStack[i]->BlockKind == BK_Unknown) 357263508Sdim LBraceStack[i]->BlockKind = BK_Block; 358263508Sdim } 359263508Sdim 360263508Sdim FormatTok = Tokens->setPosition(StoredPosition); 361263508Sdim} 362263508Sdim 363263508Sdimvoid UnwrappedLineParser::parseBlock(bool MustBeDeclaration, bool AddLevel, 364263508Sdim bool MunchSemi) { 365263508Sdim assert(FormatTok->Tok.is(tok::l_brace) && "'{' expected"); 366263508Sdim unsigned InitialLevel = Line->Level; 367249261Sdim nextToken(); 368249261Sdim 369249261Sdim addUnwrappedLine(); 370249261Sdim 371249261Sdim ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack, 372249261Sdim MustBeDeclaration); 373263508Sdim if (AddLevel) 374263508Sdim ++Line->Level; 375263508Sdim parseLevel(/*HasOpeningBrace=*/true); 376249261Sdim 377263508Sdim if (!FormatTok->Tok.is(tok::r_brace)) { 378263508Sdim Line->Level = InitialLevel; 379251662Sdim StructuralError = true; 380251662Sdim return; 381249261Sdim } 382249261Sdim 383249261Sdim nextToken(); // Munch the closing brace. 384263508Sdim if (MunchSemi && FormatTok->Tok.is(tok::semi)) 385263508Sdim nextToken(); 386263508Sdim Line->Level = InitialLevel; 387249261Sdim} 388249261Sdim 389263508Sdimvoid UnwrappedLineParser::parseChildBlock() { 390263508Sdim FormatTok->BlockKind = BK_Block; 391263508Sdim nextToken(); 392263508Sdim { 393263508Sdim ScopedLineState LineState(*this); 394263508Sdim ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack, 395263508Sdim /*MustBeDeclaration=*/false); 396263508Sdim Line->Level += 1; 397263508Sdim parseLevel(/*HasOpeningBrace=*/true); 398263508Sdim Line->Level -= 1; 399263508Sdim } 400263508Sdim nextToken(); 401263508Sdim} 402263508Sdim 403249261Sdimvoid UnwrappedLineParser::parsePPDirective() { 404263508Sdim assert(FormatTok->Tok.is(tok::hash) && "'#' expected"); 405251662Sdim ScopedMacroState MacroState(*Line, Tokens, FormatTok, StructuralError); 406249261Sdim nextToken(); 407249261Sdim 408263508Sdim if (FormatTok->Tok.getIdentifierInfo() == NULL) { 409249261Sdim parsePPUnknown(); 410249261Sdim return; 411249261Sdim } 412249261Sdim 413263508Sdim switch (FormatTok->Tok.getIdentifierInfo()->getPPKeywordID()) { 414249261Sdim case tok::pp_define: 415249261Sdim parsePPDefine(); 416263508Sdim return; 417263508Sdim case tok::pp_if: 418263508Sdim parsePPIf(/*IfDef=*/false); 419249261Sdim break; 420263508Sdim case tok::pp_ifdef: 421263508Sdim case tok::pp_ifndef: 422263508Sdim parsePPIf(/*IfDef=*/true); 423263508Sdim break; 424263508Sdim case tok::pp_else: 425263508Sdim parsePPElse(); 426263508Sdim break; 427263508Sdim case tok::pp_elif: 428263508Sdim parsePPElIf(); 429263508Sdim break; 430263508Sdim case tok::pp_endif: 431263508Sdim parsePPEndIf(); 432263508Sdim break; 433249261Sdim default: 434249261Sdim parsePPUnknown(); 435249261Sdim break; 436249261Sdim } 437249261Sdim} 438249261Sdim 439263508Sdimvoid UnwrappedLineParser::pushPPConditional() { 440263508Sdim if (!PPStack.empty() && PPStack.back() == PP_Unreachable) 441263508Sdim PPStack.push_back(PP_Unreachable); 442263508Sdim else 443263508Sdim PPStack.push_back(PP_Conditional); 444263508Sdim} 445263508Sdim 446263508Sdimvoid UnwrappedLineParser::parsePPIf(bool IfDef) { 447263508Sdim ++PPBranchLevel; 448263508Sdim assert(PPBranchLevel >= 0 && PPBranchLevel <= (int)PPLevelBranchIndex.size()); 449263508Sdim if (PPBranchLevel == (int)PPLevelBranchIndex.size()) { 450263508Sdim PPLevelBranchIndex.push_back(0); 451263508Sdim PPLevelBranchCount.push_back(0); 452263508Sdim } 453263508Sdim PPChainBranchIndex.push(0); 454263508Sdim nextToken(); 455263508Sdim bool IsLiteralFalse = (FormatTok->Tok.isLiteral() && 456263508Sdim StringRef(FormatTok->Tok.getLiteralData(), 457263508Sdim FormatTok->Tok.getLength()) == "0") || 458263508Sdim FormatTok->Tok.is(tok::kw_false); 459263508Sdim if ((!IfDef && IsLiteralFalse) || PPLevelBranchIndex[PPBranchLevel] > 0) { 460263508Sdim PPStack.push_back(PP_Unreachable); 461263508Sdim } else { 462263508Sdim pushPPConditional(); 463263508Sdim } 464263508Sdim parsePPUnknown(); 465263508Sdim} 466263508Sdim 467263508Sdimvoid UnwrappedLineParser::parsePPElse() { 468263508Sdim if (!PPStack.empty()) 469263508Sdim PPStack.pop_back(); 470263508Sdim assert(PPBranchLevel < (int)PPLevelBranchIndex.size()); 471263508Sdim if (!PPChainBranchIndex.empty()) 472263508Sdim ++PPChainBranchIndex.top(); 473263508Sdim if (PPBranchLevel >= 0 && !PPChainBranchIndex.empty() && 474263508Sdim PPLevelBranchIndex[PPBranchLevel] != PPChainBranchIndex.top()) { 475263508Sdim PPStack.push_back(PP_Unreachable); 476263508Sdim } else { 477263508Sdim pushPPConditional(); 478263508Sdim } 479263508Sdim parsePPUnknown(); 480263508Sdim} 481263508Sdim 482263508Sdimvoid UnwrappedLineParser::parsePPElIf() { parsePPElse(); } 483263508Sdim 484263508Sdimvoid UnwrappedLineParser::parsePPEndIf() { 485263508Sdim assert(PPBranchLevel < (int)PPLevelBranchIndex.size()); 486263508Sdim if (PPBranchLevel >= 0 && !PPChainBranchIndex.empty()) { 487263508Sdim if (PPChainBranchIndex.top() + 1 > PPLevelBranchCount[PPBranchLevel]) { 488263508Sdim PPLevelBranchCount[PPBranchLevel] = PPChainBranchIndex.top() + 1; 489263508Sdim } 490263508Sdim } 491263508Sdim --PPBranchLevel; 492263508Sdim if (!PPChainBranchIndex.empty()) 493263508Sdim PPChainBranchIndex.pop(); 494263508Sdim if (!PPStack.empty()) 495263508Sdim PPStack.pop_back(); 496263508Sdim parsePPUnknown(); 497263508Sdim} 498263508Sdim 499249261Sdimvoid UnwrappedLineParser::parsePPDefine() { 500249261Sdim nextToken(); 501249261Sdim 502263508Sdim if (FormatTok->Tok.getKind() != tok::identifier) { 503249261Sdim parsePPUnknown(); 504249261Sdim return; 505249261Sdim } 506249261Sdim nextToken(); 507263508Sdim if (FormatTok->Tok.getKind() == tok::l_paren && 508263508Sdim FormatTok->WhitespaceRange.getBegin() == 509263508Sdim 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 530251662Sdim// Here we blacklist certain tokens that are not usually the first token in an 531251662Sdim// unwrapped line. This is used in attempt to distinguish macro calls without 532251662Sdim// trailing semicolons from other constructs split to several lines. 533251662Sdimbool tokenCanStartNewLine(clang::Token Tok) { 534251662Sdim // Semicolon can be a null-statement, l_square can be a start of a macro or 535251662Sdim // a C++11 attribute, but this doesn't seem to be common. 536251662Sdim return Tok.isNot(tok::semi) && Tok.isNot(tok::l_brace) && 537251662Sdim Tok.isNot(tok::l_square) && 538251662Sdim // Tokens that can only be used as binary operators and a part of 539251662Sdim // overloaded operator names. 540251662Sdim Tok.isNot(tok::period) && Tok.isNot(tok::periodstar) && 541251662Sdim Tok.isNot(tok::arrow) && Tok.isNot(tok::arrowstar) && 542251662Sdim Tok.isNot(tok::less) && Tok.isNot(tok::greater) && 543251662Sdim Tok.isNot(tok::slash) && Tok.isNot(tok::percent) && 544251662Sdim Tok.isNot(tok::lessless) && Tok.isNot(tok::greatergreater) && 545251662Sdim Tok.isNot(tok::equal) && Tok.isNot(tok::plusequal) && 546251662Sdim Tok.isNot(tok::minusequal) && Tok.isNot(tok::starequal) && 547251662Sdim Tok.isNot(tok::slashequal) && Tok.isNot(tok::percentequal) && 548251662Sdim Tok.isNot(tok::ampequal) && Tok.isNot(tok::pipeequal) && 549251662Sdim Tok.isNot(tok::caretequal) && Tok.isNot(tok::greatergreaterequal) && 550251662Sdim Tok.isNot(tok::lesslessequal) && 551251662Sdim // Colon is used in labels, base class lists, initializer lists, 552251662Sdim // range-based for loops, ternary operator, but should never be the 553251662Sdim // first token in an unwrapped line. 554251662Sdim Tok.isNot(tok::colon); 555251662Sdim} 556251662Sdim 557249261Sdimvoid UnwrappedLineParser::parseStructuralElement() { 558263508Sdim assert(!FormatTok->Tok.is(tok::l_brace)); 559263508Sdim switch (FormatTok->Tok.getKind()) { 560249261Sdim case tok::at: 561249261Sdim nextToken(); 562263508Sdim if (FormatTok->Tok.is(tok::l_brace)) { 563249261Sdim parseBracedList(); 564249261Sdim break; 565249261Sdim } 566263508Sdim 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(); 593263508Sdim 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(); 628263508Sdim if (FormatTok->Tok.is(tok::string_literal)) { 629249261Sdim nextToken(); 630263508Sdim if (FormatTok->Tok.is(tok::l_brace)) { 631263508Sdim 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 { 642263508Sdim switch (FormatTok->Tok.getKind()) { 643249261Sdim case tok::at: 644249261Sdim nextToken(); 645263508Sdim 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; 668263508Sdim case tok::caret: 669263508Sdim nextToken(); 670263508Sdim if (FormatTok->is(tok::l_brace)) { 671263508Sdim parseChildBlock(); 672263508Sdim } 673263508Sdim break; 674249261Sdim case tok::l_brace: 675263508Sdim if (!tryToParseBracedList()) { 676263508Sdim // A block outside of parentheses must be the last part of a 677263508Sdim // structural element. 678263508Sdim // FIXME: Figure out cases where this is not true, and add projections 679263508Sdim // for them (the one we know is missing are lambdas). 680263508Sdim if (Style.BreakBeforeBraces == FormatStyle::BS_Linux || 681263508Sdim Style.BreakBeforeBraces == FormatStyle::BS_Stroustrup || 682263508Sdim Style.BreakBeforeBraces == FormatStyle::BS_Allman) 683263508Sdim addUnwrappedLine(); 684263508Sdim parseBlock(/*MustBeDeclaration=*/false); 685263508Sdim addUnwrappedLine(); 686263508Sdim return; 687263508Sdim } 688263508Sdim // Otherwise this was a braced init list, and the structural 689263508Sdim // element continues. 690263508Sdim break; 691263508Sdim case tok::identifier: { 692263508Sdim StringRef Text = FormatTok->TokenText; 693249261Sdim nextToken(); 694251662Sdim if (Line->Tokens.size() == 1) { 695263508Sdim if (FormatTok->Tok.is(tok::colon)) { 696251662Sdim parseLabel(); 697251662Sdim return; 698251662Sdim } 699251662Sdim // Recognize function-like macro usages without trailing semicolon. 700263508Sdim if (FormatTok->Tok.is(tok::l_paren)) { 701251662Sdim parseParens(); 702263508Sdim if (FormatTok->HasUnescapedNewline && 703263508Sdim tokenCanStartNewLine(FormatTok->Tok)) { 704251662Sdim addUnwrappedLine(); 705251662Sdim return; 706251662Sdim } 707263508Sdim } else if (FormatTok->HasUnescapedNewline && Text.size() >= 5 && 708263508Sdim Text == Text.upper()) { 709263508Sdim // Recognize free-standing macros like Q_OBJECT. 710263508Sdim addUnwrappedLine(); 711263508Sdim return; 712251662Sdim } 713249261Sdim } 714249261Sdim break; 715263508Sdim } 716249261Sdim case tok::equal: 717249261Sdim nextToken(); 718263508Sdim if (FormatTok->Tok.is(tok::l_brace)) { 719249261Sdim parseBracedList(); 720249261Sdim } 721249261Sdim break; 722263508Sdim case tok::l_square: 723263508Sdim tryToParseLambda(); 724263508Sdim break; 725249261Sdim default: 726249261Sdim nextToken(); 727249261Sdim break; 728249261Sdim } 729249261Sdim } while (!eof()); 730249261Sdim} 731249261Sdim 732263508Sdimvoid UnwrappedLineParser::tryToParseLambda() { 733263508Sdim // FIXME: This is a dirty way to access the previous token. Find a better 734263508Sdim // solution. 735263508Sdim if (!Line->Tokens.empty() && 736263508Sdim Line->Tokens.back().Tok->isOneOf(tok::identifier, tok::kw_operator)) { 737263508Sdim nextToken(); 738263508Sdim return; 739263508Sdim } 740263508Sdim assert(FormatTok->is(tok::l_square)); 741263508Sdim FormatToken &LSquare = *FormatTok; 742263508Sdim if (!tryToParseLambdaIntroducer()) 743263508Sdim return; 744263508Sdim 745263508Sdim while (FormatTok->isNot(tok::l_brace)) { 746263508Sdim switch (FormatTok->Tok.getKind()) { 747263508Sdim case tok::l_brace: 748263508Sdim break; 749263508Sdim case tok::l_paren: 750263508Sdim parseParens(); 751263508Sdim break; 752263508Sdim case tok::identifier: 753263508Sdim case tok::kw_mutable: 754263508Sdim nextToken(); 755263508Sdim break; 756263508Sdim default: 757263508Sdim return; 758263508Sdim } 759263508Sdim } 760263508Sdim LSquare.Type = TT_LambdaLSquare; 761263508Sdim parseChildBlock(); 762263508Sdim} 763263508Sdim 764263508Sdimbool UnwrappedLineParser::tryToParseLambdaIntroducer() { 765249261Sdim nextToken(); 766263508Sdim if (FormatTok->is(tok::equal)) { 767263508Sdim nextToken(); 768263508Sdim if (FormatTok->is(tok::r_square)) { 769263508Sdim nextToken(); 770263508Sdim return true; 771263508Sdim } 772263508Sdim if (FormatTok->isNot(tok::comma)) 773263508Sdim return false; 774263508Sdim nextToken(); 775263508Sdim } else if (FormatTok->is(tok::amp)) { 776263508Sdim nextToken(); 777263508Sdim if (FormatTok->is(tok::r_square)) { 778263508Sdim nextToken(); 779263508Sdim return true; 780263508Sdim } 781263508Sdim if (!FormatTok->isOneOf(tok::comma, tok::identifier)) { 782263508Sdim return false; 783263508Sdim } 784263508Sdim if (FormatTok->is(tok::comma)) 785263508Sdim nextToken(); 786263508Sdim } else if (FormatTok->is(tok::r_square)) { 787263508Sdim nextToken(); 788263508Sdim return true; 789263508Sdim } 790263508Sdim do { 791263508Sdim if (FormatTok->is(tok::amp)) 792263508Sdim nextToken(); 793263508Sdim if (!FormatTok->isOneOf(tok::identifier, tok::kw_this)) 794263508Sdim return false; 795263508Sdim nextToken(); 796263508Sdim if (FormatTok->is(tok::comma)) { 797263508Sdim nextToken(); 798263508Sdim } else if (FormatTok->is(tok::r_square)) { 799263508Sdim nextToken(); 800263508Sdim return true; 801263508Sdim } else { 802263508Sdim return false; 803263508Sdim } 804263508Sdim } while (!eof()); 805263508Sdim return false; 806263508Sdim} 807249261Sdim 808263508Sdimbool UnwrappedLineParser::tryToParseBracedList() { 809263508Sdim if (FormatTok->BlockKind == BK_Unknown) 810263508Sdim calculateBraceTypes(); 811263508Sdim assert(FormatTok->BlockKind != BK_Unknown); 812263508Sdim if (FormatTok->BlockKind == BK_Block) 813263508Sdim return false; 814263508Sdim parseBracedList(); 815263508Sdim return true; 816263508Sdim} 817263508Sdim 818263508Sdimbool UnwrappedLineParser::parseBracedList(bool ContinueOnSemicolons) { 819263508Sdim bool HasError = false; 820263508Sdim nextToken(); 821263508Sdim 822251662Sdim // FIXME: Once we have an expression parser in the UnwrappedLineParser, 823251662Sdim // replace this by using parseAssigmentExpression() inside. 824249261Sdim do { 825251662Sdim // FIXME: When we start to support lambdas, we'll want to parse them away 826251662Sdim // here, otherwise our bail-out scenarios below break. The better solution 827251662Sdim // might be to just implement a more or less complete expression parser. 828263508Sdim switch (FormatTok->Tok.getKind()) { 829263508Sdim case tok::caret: 830263508Sdim nextToken(); 831263508Sdim if (FormatTok->is(tok::l_brace)) { 832263508Sdim parseChildBlock(); 833263508Sdim } 834263508Sdim break; 835263508Sdim case tok::l_square: 836263508Sdim tryToParseLambda(); 837263508Sdim break; 838249261Sdim case tok::l_brace: 839263508Sdim // Assume there are no blocks inside a braced init list apart 840263508Sdim // from the ones we explicitly parse out (like lambdas). 841263508Sdim FormatTok->BlockKind = BK_BracedInit; 842249261Sdim parseBracedList(); 843249261Sdim break; 844249261Sdim case tok::r_brace: 845249261Sdim nextToken(); 846263508Sdim return !HasError; 847251662Sdim case tok::semi: 848263508Sdim HasError = true; 849263508Sdim if (!ContinueOnSemicolons) 850263508Sdim return !HasError; 851263508Sdim nextToken(); 852263508Sdim break; 853251662Sdim case tok::comma: 854251662Sdim nextToken(); 855251662Sdim break; 856249261Sdim default: 857249261Sdim nextToken(); 858249261Sdim break; 859249261Sdim } 860249261Sdim } while (!eof()); 861263508Sdim return false; 862249261Sdim} 863249261Sdim 864249261Sdimvoid UnwrappedLineParser::parseReturn() { 865249261Sdim nextToken(); 866249261Sdim 867249261Sdim do { 868263508Sdim switch (FormatTok->Tok.getKind()) { 869249261Sdim case tok::l_brace: 870249261Sdim parseBracedList(); 871263508Sdim if (FormatTok->Tok.isNot(tok::semi)) { 872251662Sdim // Assume missing ';'. 873251662Sdim addUnwrappedLine(); 874251662Sdim return; 875251662Sdim } 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; 888263508Sdim case tok::l_square: 889263508Sdim tryToParseLambda(); 890263508Sdim break; 891249261Sdim default: 892249261Sdim nextToken(); 893249261Sdim break; 894249261Sdim } 895249261Sdim } while (!eof()); 896249261Sdim} 897249261Sdim 898249261Sdimvoid UnwrappedLineParser::parseParens() { 899263508Sdim assert(FormatTok->Tok.is(tok::l_paren) && "'(' expected."); 900249261Sdim nextToken(); 901249261Sdim do { 902263508Sdim switch (FormatTok->Tok.getKind()) { 903249261Sdim case tok::l_paren: 904249261Sdim parseParens(); 905249261Sdim break; 906249261Sdim case tok::r_paren: 907249261Sdim nextToken(); 908249261Sdim return; 909263508Sdim case tok::r_brace: 910263508Sdim // A "}" inside parenthesis is an error if there wasn't a matching "{". 911263508Sdim return; 912263508Sdim case tok::l_square: 913263508Sdim tryToParseLambda(); 914263508Sdim break; 915249261Sdim case tok::l_brace: { 916263508Sdim if (!tryToParseBracedList()) { 917263508Sdim parseChildBlock(); 918263508Sdim } 919249261Sdim break; 920249261Sdim } 921249261Sdim case tok::at: 922249261Sdim nextToken(); 923263508Sdim 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() { 934263508Sdim assert(FormatTok->Tok.is(tok::kw_if) && "'if' expected"); 935249261Sdim nextToken(); 936263508Sdim if (FormatTok->Tok.is(tok::l_paren)) 937249261Sdim parseParens(); 938249261Sdim bool NeedsUnwrappedLine = false; 939263508Sdim if (FormatTok->Tok.is(tok::l_brace)) { 940263508Sdim if (Style.BreakBeforeBraces == FormatStyle::BS_Allman) 941263508Sdim addUnwrappedLine(); 942263508Sdim parseBlock(/*MustBeDeclaration=*/false); 943263508Sdim if (Style.BreakBeforeBraces == FormatStyle::BS_Allman) 944263508Sdim addUnwrappedLine(); 945263508Sdim else 946263508Sdim NeedsUnwrappedLine = true; 947249261Sdim } else { 948249261Sdim addUnwrappedLine(); 949249261Sdim ++Line->Level; 950249261Sdim parseStructuralElement(); 951249261Sdim --Line->Level; 952249261Sdim } 953263508Sdim if (FormatTok->Tok.is(tok::kw_else)) { 954249261Sdim nextToken(); 955263508Sdim if (FormatTok->Tok.is(tok::l_brace)) { 956263508Sdim if (Style.BreakBeforeBraces == FormatStyle::BS_Allman) 957263508Sdim addUnwrappedLine(); 958263508Sdim parseBlock(/*MustBeDeclaration=*/false); 959249261Sdim addUnwrappedLine(); 960263508Sdim } 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() { 974263508Sdim assert(FormatTok->Tok.is(tok::kw_namespace) && "'namespace' expected"); 975249261Sdim nextToken(); 976263508Sdim if (FormatTok->Tok.is(tok::identifier)) 977249261Sdim nextToken(); 978263508Sdim if (FormatTok->Tok.is(tok::l_brace)) { 979263508Sdim if (Style.BreakBeforeBraces == FormatStyle::BS_Linux || 980263508Sdim Style.BreakBeforeBraces == FormatStyle::BS_Allman) 981263508Sdim addUnwrappedLine(); 982263508Sdim 983263508Sdim bool AddLevel = Style.NamespaceIndentation == FormatStyle::NI_All || 984263508Sdim (Style.NamespaceIndentation == FormatStyle::NI_Inner && 985263508Sdim DeclarationScopeStack.size() > 1); 986263508Sdim 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. 989263508Sdim if (FormatTok->Tok.is(tok::semi)) 990249261Sdim nextToken(); 991249261Sdim addUnwrappedLine(); 992249261Sdim } 993249261Sdim // FIXME: Add error handling. 994249261Sdim} 995249261Sdim 996249261Sdimvoid UnwrappedLineParser::parseForOrWhileLoop() { 997263508Sdim assert((FormatTok->Tok.is(tok::kw_for) || FormatTok->Tok.is(tok::kw_while)) && 998249261Sdim "'for' or 'while' expected"); 999249261Sdim nextToken(); 1000263508Sdim if (FormatTok->Tok.is(tok::l_paren)) 1001249261Sdim parseParens(); 1002263508Sdim if (FormatTok->Tok.is(tok::l_brace)) { 1003263508Sdim if (Style.BreakBeforeBraces == FormatStyle::BS_Allman) 1004263508Sdim addUnwrappedLine(); 1005263508Sdim parseBlock(/*MustBeDeclaration=*/false); 1006249261Sdim addUnwrappedLine(); 1007249261Sdim } else { 1008249261Sdim addUnwrappedLine(); 1009249261Sdim ++Line->Level; 1010249261Sdim parseStructuralElement(); 1011249261Sdim --Line->Level; 1012249261Sdim } 1013249261Sdim} 1014249261Sdim 1015249261Sdimvoid UnwrappedLineParser::parseDoWhile() { 1016263508Sdim assert(FormatTok->Tok.is(tok::kw_do) && "'do' expected"); 1017249261Sdim nextToken(); 1018263508Sdim if (FormatTok->Tok.is(tok::l_brace)) { 1019263508Sdim if (Style.BreakBeforeBraces == FormatStyle::BS_Allman) 1020263508Sdim addUnwrappedLine(); 1021263508Sdim parseBlock(/*MustBeDeclaration=*/false); 1022249261Sdim } else { 1023249261Sdim addUnwrappedLine(); 1024249261Sdim ++Line->Level; 1025249261Sdim parseStructuralElement(); 1026249261Sdim --Line->Level; 1027249261Sdim } 1028249261Sdim 1029249261Sdim // FIXME: Add error handling. 1030263508Sdim 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; 1044263508Sdim if (CommentsBeforeNextToken.empty() && FormatTok->Tok.is(tok::l_brace)) { 1045263508Sdim if (Style.BreakBeforeBraces == FormatStyle::BS_Allman) 1046263508Sdim addUnwrappedLine(); 1047263508Sdim parseBlock(/*MustBeDeclaration=*/false); 1048263508Sdim if (FormatTok->Tok.is(tok::kw_break)) { 1049263508Sdim // "break;" after "}" on its own line only for BS_Allman 1050263508Sdim if (Style.BreakBeforeBraces == FormatStyle::BS_Allman) 1051263508Sdim addUnwrappedLine(); 1052263508Sdim parseStructuralElement(); 1053263508Sdim } 1054249261Sdim } 1055249261Sdim addUnwrappedLine(); 1056249261Sdim Line->Level = OldLineLevel; 1057249261Sdim} 1058249261Sdim 1059249261Sdimvoid UnwrappedLineParser::parseCaseLabel() { 1060263508Sdim assert(FormatTok->Tok.is(tok::kw_case) && "'case' expected"); 1061249261Sdim // FIXME: fix handling of complex expressions here. 1062249261Sdim do { 1063249261Sdim nextToken(); 1064263508Sdim } while (!eof() && !FormatTok->Tok.is(tok::colon)); 1065249261Sdim parseLabel(); 1066249261Sdim} 1067249261Sdim 1068249261Sdimvoid UnwrappedLineParser::parseSwitch() { 1069263508Sdim assert(FormatTok->Tok.is(tok::kw_switch) && "'switch' expected"); 1070249261Sdim nextToken(); 1071263508Sdim if (FormatTok->Tok.is(tok::l_paren)) 1072249261Sdim parseParens(); 1073263508Sdim if (FormatTok->Tok.is(tok::l_brace)) { 1074263508Sdim if (Style.BreakBeforeBraces == FormatStyle::BS_Allman) 1075263508Sdim addUnwrappedLine(); 1076263508Sdim parseBlock(/*MustBeDeclaration=*/false); 1077249261Sdim addUnwrappedLine(); 1078249261Sdim } else { 1079249261Sdim addUnwrappedLine(); 1080263508Sdim ++Line->Level; 1081249261Sdim parseStructuralElement(); 1082263508Sdim --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. 1089263508Sdim if (FormatTok->Tok.is(tok::colon)) 1090249261Sdim nextToken(); 1091249261Sdim addUnwrappedLine(); 1092249261Sdim} 1093249261Sdim 1094249261Sdimvoid UnwrappedLineParser::parseEnum() { 1095249261Sdim nextToken(); 1096263508Sdim // Eat up enum class ... 1097263508Sdim if (FormatTok->Tok.is(tok::kw_class) || 1098263508Sdim FormatTok->Tok.is(tok::kw_struct)) 1099263508Sdim nextToken(); 1100263508Sdim while (FormatTok->Tok.getIdentifierInfo() || 1101263508Sdim FormatTok->isOneOf(tok::colon, tok::coloncolon)) { 1102249261Sdim nextToken(); 1103249261Sdim // We can have macros or attributes in between 'enum' and the enum name. 1104263508Sdim if (FormatTok->Tok.is(tok::l_paren)) { 1105249261Sdim parseParens(); 1106249261Sdim } 1107263508Sdim if (FormatTok->Tok.is(tok::identifier)) 1108249261Sdim nextToken(); 1109249261Sdim } 1110263508Sdim if (FormatTok->Tok.is(tok::l_brace)) { 1111263508Sdim FormatTok->BlockKind = BK_Block; 1112263508Sdim bool HasError = !parseBracedList(/*ContinueOnSemicolons=*/true); 1113263508Sdim if (HasError) { 1114263508Sdim if (FormatTok->is(tok::semi)) 1115249261Sdim nextToken(); 1116263508Sdim addUnwrappedLine(); 1117263508Sdim } 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(); 1126263508Sdim if (FormatTok->Tok.is(tok::identifier) || 1127263508Sdim FormatTok->Tok.is(tok::kw___attribute) || 1128263508Sdim FormatTok->Tok.is(tok::kw___declspec) || 1129263508Sdim FormatTok->Tok.is(tok::kw_alignas)) { 1130249261Sdim nextToken(); 1131249261Sdim // We can have macros or attributes in between 'class' and the class name. 1132263508Sdim 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. 1137263508Sdim while (FormatTok->Tok.is(tok::identifier) || 1138263508Sdim FormatTok->Tok.is(tok::coloncolon) || 1139263508Sdim 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). 1152263508Sdim if (FormatTok->Tok.is(tok::colon) || FormatTok->Tok.is(tok::less)) { 1153263508Sdim while (!eof() && FormatTok->Tok.isNot(tok::l_brace)) { 1154263508Sdim if (FormatTok->Tok.is(tok::semi)) 1155249261Sdim return; 1156249261Sdim nextToken(); 1157249261Sdim } 1158249261Sdim } 1159249261Sdim } 1160263508Sdim if (FormatTok->Tok.is(tok::l_brace)) { 1161263508Sdim if (Style.BreakBeforeBraces == FormatStyle::BS_Linux || 1162263508Sdim Style.BreakBeforeBraces == FormatStyle::BS_Allman) 1163263508Sdim addUnwrappedLine(); 1164263508Sdim 1165263508Sdim parseBlock(/*MustBeDeclaration=*/true, /*Addlevel=*/true, 1166263508Sdim /*MunchSemi=*/false); 1167263508Sdim } 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() { 1174263508Sdim assert(FormatTok->Tok.is(tok::less) && "'<' expected."); 1175249261Sdim do 1176249261Sdim nextToken(); 1177263508Sdim while (!eof() && FormatTok->Tok.isNot(tok::greater)); 1178249261Sdim nextToken(); // Skip '>'. 1179249261Sdim} 1180249261Sdim 1181249261Sdimvoid UnwrappedLineParser::parseObjCUntilAtEnd() { 1182249261Sdim do { 1183263508Sdim if (FormatTok->Tok.isObjCAtKeyword(tok::objc_end)) { 1184249261Sdim nextToken(); 1185249261Sdim addUnwrappedLine(); 1186249261Sdim break; 1187249261Sdim } 1188263508Sdim if (FormatTok->is(tok::l_brace)) { 1189263508Sdim parseBlock(/*MustBeDeclaration=*/false); 1190263508Sdim // In ObjC interfaces, nothing should be following the "}". 1191263508Sdim addUnwrappedLine(); 1192263508Sdim } else { 1193263508Sdim parseStructuralElement(); 1194263508Sdim } 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. 1203263508Sdim if (FormatTok->Tok.is(tok::colon)) { 1204249261Sdim nextToken(); 1205249261Sdim nextToken(); // base class name 1206263508Sdim } else if (FormatTok->Tok.is(tok::l_paren)) 1207249261Sdim // Skip category, if present. 1208249261Sdim parseParens(); 1209249261Sdim 1210263508Sdim if (FormatTok->Tok.is(tok::less)) 1211249261Sdim parseObjCProtocolList(); 1212249261Sdim 1213249261Sdim // If instance variables are present, keep the '{' on the first line too. 1214263508Sdim if (FormatTok->Tok.is(tok::l_brace)) 1215263508Sdim 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 1228263508Sdim if (FormatTok->Tok.is(tok::less)) 1229249261Sdim parseObjCProtocolList(); 1230249261Sdim 1231249261Sdim // Check for protocol declaration. 1232263508Sdim if (FormatTok->Tok.is(tok::semi)) { 1233249261Sdim nextToken(); 1234249261Sdim return addUnwrappedLine(); 1235249261Sdim } 1236249261Sdim 1237249261Sdim addUnwrappedLine(); 1238249261Sdim parseObjCUntilAtEnd(); 1239249261Sdim} 1240249261Sdim 1241263508SdimLLVM_ATTRIBUTE_UNUSED static void printDebugInfo(const UnwrappedLine &Line, 1242263508Sdim StringRef Prefix = "") { 1243263508Sdim llvm::dbgs() << Prefix << "Line(" << Line.Level << ")" 1244263508Sdim << (Line.InPPDirective ? " MACRO" : "") << ": "; 1245263508Sdim for (std::list<UnwrappedLineNode>::const_iterator I = Line.Tokens.begin(), 1246263508Sdim E = Line.Tokens.end(); 1247263508Sdim I != E; ++I) { 1248263508Sdim llvm::dbgs() << I->Tok->Tok.getName() << "[" << I->Tok->Type << "] "; 1249263508Sdim } 1250263508Sdim for (std::list<UnwrappedLineNode>::const_iterator I = Line.Tokens.begin(), 1251263508Sdim E = Line.Tokens.end(); 1252263508Sdim I != E; ++I) { 1253263508Sdim const UnwrappedLineNode &Node = *I; 1254263508Sdim for (SmallVectorImpl<UnwrappedLine>::const_iterator 1255263508Sdim I = Node.Children.begin(), 1256263508Sdim E = Node.Children.end(); 1257263508Sdim I != E; ++I) { 1258263508Sdim printDebugInfo(*I, "\nChild: "); 1259263508Sdim } 1260263508Sdim } 1261263508Sdim llvm::dbgs() << "\n"; 1262263508Sdim} 1263263508Sdim 1264249261Sdimvoid UnwrappedLineParser::addUnwrappedLine() { 1265249261Sdim if (Line->Tokens.empty()) 1266249261Sdim return; 1267249261Sdim DEBUG({ 1268263508Sdim if (CurrentLines == &Lines) 1269263508Sdim printDebugInfo(*Line); 1270249261Sdim }); 1271249261Sdim CurrentLines->push_back(*Line); 1272249261Sdim Line->Tokens.clear(); 1273249261Sdim if (CurrentLines == &Lines && !PreprocessorDirectives.empty()) { 1274263508Sdim 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 1284263508Sdimbool UnwrappedLineParser::eof() const { return FormatTok->Tok.is(tok::eof); } 1285249261Sdim 1286249261Sdimvoid UnwrappedLineParser::flushComments(bool NewlineBeforeNext) { 1287249261Sdim bool JustComments = Line->Tokens.empty(); 1288263508Sdim for (SmallVectorImpl<FormatToken *>::const_iterator 1289249261Sdim I = CommentsBeforeNextToken.begin(), 1290249261Sdim E = CommentsBeforeNextToken.end(); 1291249261Sdim I != E; ++I) { 1292263508Sdim 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; 1306263508Sdim flushComments(FormatTok->NewlinesBefore > 0); 1307249261Sdim pushToken(FormatTok); 1308249261Sdim readToken(); 1309249261Sdim} 1310249261Sdim 1311249261Sdimvoid UnwrappedLineParser::readToken() { 1312249261Sdim bool CommentsInCurrentLine = true; 1313249261Sdim do { 1314249261Sdim FormatTok = Tokens->getNextToken(); 1315263508Sdim while (!Line->InPPDirective && FormatTok->Tok.is(tok::hash) && 1316263508Sdim (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. 1325263508Sdim flushComments(FormatTok->NewlinesBefore > 0); 1326249261Sdim parsePPDirective(); 1327249261Sdim } 1328263508Sdim 1329263508Sdim if (!PPStack.empty() && (PPStack.back() == PP_Unreachable) && 1330263508Sdim !Line->InPPDirective) { 1331263508Sdim continue; 1332263508Sdim } 1333263508Sdim 1334263508Sdim if (!FormatTok->Tok.is(tok::comment)) 1335249261Sdim return; 1336263508Sdim 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 1347263508Sdimvoid UnwrappedLineParser::pushToken(FormatToken *Tok) { 1348263508Sdim Line->Tokens.push_back(UnwrappedLineNode(Tok)); 1349249261Sdim if (MustBreakBeforeNextToken) { 1350263508Sdim Line->Tokens.back().Tok->MustBreakBefore = true; 1351249261Sdim MustBreakBeforeNextToken = false; 1352249261Sdim } 1353249261Sdim} 1354249261Sdim 1355249261Sdim} // end namespace format 1356249261Sdim} // end namespace clang 1357