brintos

brintos / llvm-project-archived public Read only

0
0
Text · 159.9 KiB · 19c83d3 Raw
5111 lines · cpp
1//===--- UnwrappedLineParser.cpp - Format C++ code ------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// This file contains the implementation of the UnwrappedLineParser,11/// which turns a stream of tokens into UnwrappedLines.12///13//===----------------------------------------------------------------------===//14 15#include "UnwrappedLineParser.h"16#include "FormatToken.h"17#include "FormatTokenSource.h"18#include "Macros.h"19#include "TokenAnnotator.h"20#include "clang/Basic/TokenKinds.h"21#include "llvm/ADT/STLExtras.h"22#include "llvm/ADT/StringRef.h"23#include "llvm/Support/Debug.h"24#include "llvm/Support/raw_os_ostream.h"25#include "llvm/Support/raw_ostream.h"26 27#include <utility>28 29#define DEBUG_TYPE "format-parser"30 31namespace clang {32namespace format {33 34namespace {35 36void printLine(llvm::raw_ostream &OS, const UnwrappedLine &Line,37               StringRef Prefix = "", bool PrintText = false) {38  OS << Prefix << "Line(" << Line.Level << ", FSC=" << Line.FirstStartColumn39     << ")" << (Line.InPPDirective ? " MACRO" : "") << ": ";40  bool NewLine = false;41  for (std::list<UnwrappedLineNode>::const_iterator I = Line.Tokens.begin(),42                                                    E = Line.Tokens.end();43       I != E; ++I) {44    if (NewLine) {45      OS << Prefix;46      NewLine = false;47    }48    OS << I->Tok->Tok.getName() << "["49       << "T=" << (unsigned)I->Tok->getType()50       << ", OC=" << I->Tok->OriginalColumn << ", \"" << I->Tok->TokenText51       << "\"] ";52    for (const auto *CI = I->Children.begin(), *CE = I->Children.end();53         CI != CE; ++CI) {54      OS << "\n";55      printLine(OS, *CI, (Prefix + "  ").str());56      NewLine = true;57    }58  }59  if (!NewLine)60    OS << "\n";61}62 63[[maybe_unused]] static void printDebugInfo(const UnwrappedLine &Line) {64  printLine(llvm::dbgs(), Line);65}66 67class ScopedDeclarationState {68public:69  ScopedDeclarationState(UnwrappedLine &Line, llvm::BitVector &Stack,70                         bool MustBeDeclaration)71      : Line(Line), Stack(Stack) {72    Line.MustBeDeclaration = MustBeDeclaration;73    Stack.push_back(MustBeDeclaration);74  }75  ~ScopedDeclarationState() {76    Stack.pop_back();77    if (!Stack.empty())78      Line.MustBeDeclaration = Stack.back();79    else80      Line.MustBeDeclaration = true;81  }82 83private:84  UnwrappedLine &Line;85  llvm::BitVector &Stack;86};87 88} // end anonymous namespace89 90std::ostream &operator<<(std::ostream &Stream, const UnwrappedLine &Line) {91  llvm::raw_os_ostream OS(Stream);92  printLine(OS, Line);93  return Stream;94}95 96class ScopedLineState {97public:98  ScopedLineState(UnwrappedLineParser &Parser,99                  bool SwitchToPreprocessorLines = false)100      : Parser(Parser), OriginalLines(Parser.CurrentLines) {101    if (SwitchToPreprocessorLines)102      Parser.CurrentLines = &Parser.PreprocessorDirectives;103    else if (!Parser.Line->Tokens.empty())104      Parser.CurrentLines = &Parser.Line->Tokens.back().Children;105    PreBlockLine = std::move(Parser.Line);106    Parser.Line = std::make_unique<UnwrappedLine>();107    Parser.Line->Level = PreBlockLine->Level;108    Parser.Line->PPLevel = PreBlockLine->PPLevel;109    Parser.Line->InPPDirective = PreBlockLine->InPPDirective;110    Parser.Line->InMacroBody = PreBlockLine->InMacroBody;111    Parser.Line->UnbracedBodyLevel = PreBlockLine->UnbracedBodyLevel;112  }113 114  ~ScopedLineState() {115    if (!Parser.Line->Tokens.empty())116      Parser.addUnwrappedLine();117    assert(Parser.Line->Tokens.empty());118    Parser.Line = std::move(PreBlockLine);119    if (Parser.CurrentLines == &Parser.PreprocessorDirectives)120      Parser.AtEndOfPPLine = true;121    Parser.CurrentLines = OriginalLines;122  }123 124private:125  UnwrappedLineParser &Parser;126 127  std::unique_ptr<UnwrappedLine> PreBlockLine;128  SmallVectorImpl<UnwrappedLine> *OriginalLines;129};130 131class CompoundStatementIndenter {132public:133  CompoundStatementIndenter(UnwrappedLineParser *Parser,134                            const FormatStyle &Style, unsigned &LineLevel)135      : CompoundStatementIndenter(Parser, LineLevel,136                                  Style.BraceWrapping.AfterControlStatement ==137                                      FormatStyle::BWACS_Always,138                                  Style.BraceWrapping.IndentBraces) {}139  CompoundStatementIndenter(UnwrappedLineParser *Parser, unsigned &LineLevel,140                            bool WrapBrace, bool IndentBrace)141      : LineLevel(LineLevel), OldLineLevel(LineLevel) {142    if (WrapBrace)143      Parser->addUnwrappedLine();144    if (IndentBrace)145      ++LineLevel;146  }147  ~CompoundStatementIndenter() { LineLevel = OldLineLevel; }148 149private:150  unsigned &LineLevel;151  unsigned OldLineLevel;152};153 154UnwrappedLineParser::UnwrappedLineParser(155    SourceManager &SourceMgr, const FormatStyle &Style,156    const AdditionalKeywords &Keywords, unsigned FirstStartColumn,157    ArrayRef<FormatToken *> Tokens, UnwrappedLineConsumer &Callback,158    llvm::SpecificBumpPtrAllocator<FormatToken> &Allocator,159    IdentifierTable &IdentTable)160    : Line(new UnwrappedLine), AtEndOfPPLine(false), CurrentLines(&Lines),161      Style(Style), IsCpp(Style.isCpp()),162      LangOpts(getFormattingLangOpts(Style)), Keywords(Keywords),163      CommentPragmasRegex(Style.CommentPragmas), Tokens(nullptr),164      Callback(Callback), AllTokens(Tokens), PPBranchLevel(-1),165      IncludeGuard(getIncludeGuardState(Style.IndentPPDirectives)),166      IncludeGuardToken(nullptr), FirstStartColumn(FirstStartColumn),167      Macros(Style.Macros, SourceMgr, Style, Allocator, IdentTable) {}168 169void UnwrappedLineParser::reset() {170  PPBranchLevel = -1;171  IncludeGuard = getIncludeGuardState(Style.IndentPPDirectives);172  IncludeGuardToken = nullptr;173  Line.reset(new UnwrappedLine);174  CommentsBeforeNextToken.clear();175  FormatTok = nullptr;176  AtEndOfPPLine = false;177  IsDecltypeAutoFunction = false;178  PreprocessorDirectives.clear();179  CurrentLines = &Lines;180  DeclarationScopeStack.clear();181  NestedTooDeep.clear();182  NestedLambdas.clear();183  PPStack.clear();184  Line->FirstStartColumn = FirstStartColumn;185 186  if (!Unexpanded.empty())187    for (FormatToken *Token : AllTokens)188      Token->MacroCtx.reset();189  CurrentExpandedLines.clear();190  ExpandedLines.clear();191  Unexpanded.clear();192  InExpansion = false;193  Reconstruct.reset();194}195 196void UnwrappedLineParser::parse() {197  IndexedTokenSource TokenSource(AllTokens);198  Line->FirstStartColumn = FirstStartColumn;199  do {200    LLVM_DEBUG(llvm::dbgs() << "----\n");201    reset();202    Tokens = &TokenSource;203    TokenSource.reset();204 205    readToken();206    parseFile();207 208    // If we found an include guard then all preprocessor directives (other than209    // the guard) are over-indented by one.210    if (IncludeGuard == IG_Found) {211      for (auto &Line : Lines)212        if (Line.InPPDirective && Line.Level > 0)213          --Line.Level;214    }215 216    // Create line with eof token.217    assert(eof());218    pushToken(FormatTok);219    addUnwrappedLine();220 221    // In a first run, format everything with the lines containing macro calls222    // replaced by the expansion.223    if (!ExpandedLines.empty()) {224      LLVM_DEBUG(llvm::dbgs() << "Expanded lines:\n");225      for (const auto &Line : Lines) {226        if (!Line.Tokens.empty()) {227          auto it = ExpandedLines.find(Line.Tokens.begin()->Tok);228          if (it != ExpandedLines.end()) {229            for (const auto &Expanded : it->second) {230              LLVM_DEBUG(printDebugInfo(Expanded));231              Callback.consumeUnwrappedLine(Expanded);232            }233            continue;234          }235        }236        LLVM_DEBUG(printDebugInfo(Line));237        Callback.consumeUnwrappedLine(Line);238      }239      Callback.finishRun();240    }241 242    LLVM_DEBUG(llvm::dbgs() << "Unwrapped lines:\n");243    for (const UnwrappedLine &Line : Lines) {244      LLVM_DEBUG(printDebugInfo(Line));245      Callback.consumeUnwrappedLine(Line);246    }247    Callback.finishRun();248    Lines.clear();249    while (!PPLevelBranchIndex.empty() &&250           PPLevelBranchIndex.back() + 1 >= PPLevelBranchCount.back()) {251      PPLevelBranchIndex.resize(PPLevelBranchIndex.size() - 1);252      PPLevelBranchCount.resize(PPLevelBranchCount.size() - 1);253    }254    if (!PPLevelBranchIndex.empty()) {255      ++PPLevelBranchIndex.back();256      assert(PPLevelBranchIndex.size() == PPLevelBranchCount.size());257      assert(PPLevelBranchIndex.back() <= PPLevelBranchCount.back());258    }259  } while (!PPLevelBranchIndex.empty());260}261 262void UnwrappedLineParser::parseFile() {263  // The top-level context in a file always has declarations, except for pre-264  // processor directives and JavaScript files.265  bool MustBeDeclaration = !Line->InPPDirective && !Style.isJavaScript();266  ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,267                                          MustBeDeclaration);268  if (Style.isTextProto() || (Style.isJson() && FormatTok->IsFirst))269    parseBracedList();270  else271    parseLevel();272  // Make sure to format the remaining tokens.273  //274  // LK_TextProto is special since its top-level is parsed as the body of a275  // braced list, which does not necessarily have natural line separators such276  // as a semicolon. Comments after the last entry that have been determined to277  // not belong to that line, as in:278  //   key: value279  //   // endfile comment280  // do not have a chance to be put on a line of their own until this point.281  // Here we add this newline before end-of-file comments.282  if (Style.isTextProto() && !CommentsBeforeNextToken.empty())283    addUnwrappedLine();284  flushComments(true);285  addUnwrappedLine();286}287 288void UnwrappedLineParser::parseCSharpGenericTypeConstraint() {289  do {290    switch (FormatTok->Tok.getKind()) {291    case tok::l_brace:292    case tok::semi:293      return;294    default:295      if (FormatTok->is(Keywords.kw_where)) {296        addUnwrappedLine();297        nextToken();298        parseCSharpGenericTypeConstraint();299        break;300      }301      nextToken();302      break;303    }304  } while (!eof());305}306 307void UnwrappedLineParser::parseCSharpAttribute() {308  int UnpairedSquareBrackets = 1;309  do {310    switch (FormatTok->Tok.getKind()) {311    case tok::r_square:312      nextToken();313      --UnpairedSquareBrackets;314      if (UnpairedSquareBrackets == 0) {315        addUnwrappedLine();316        return;317      }318      break;319    case tok::l_square:320      ++UnpairedSquareBrackets;321      nextToken();322      break;323    default:324      nextToken();325      break;326    }327  } while (!eof());328}329 330bool UnwrappedLineParser::precededByCommentOrPPDirective() const {331  if (!Lines.empty() && Lines.back().InPPDirective)332    return true;333 334  const FormatToken *Previous = Tokens->getPreviousToken();335  return Previous && Previous->is(tok::comment) &&336         (Previous->IsMultiline || Previous->NewlinesBefore > 0);337}338 339/// Parses a level, that is ???.340/// \param OpeningBrace Opening brace (\p nullptr if absent) of that level.341/// \param IfKind The \p if statement kind in the level.342/// \param IfLeftBrace The left brace of the \p if block in the level.343/// \returns true if a simple block of if/else/for/while, or false otherwise.344/// (A simple block has a single statement.)345bool UnwrappedLineParser::parseLevel(const FormatToken *OpeningBrace,346                                     IfStmtKind *IfKind,347                                     FormatToken **IfLeftBrace) {348  const bool InRequiresExpression =349      OpeningBrace && OpeningBrace->is(TT_RequiresExpressionLBrace);350  const bool IsPrecededByCommentOrPPDirective =351      !Style.RemoveBracesLLVM || precededByCommentOrPPDirective();352  FormatToken *IfLBrace = nullptr;353  bool HasDoWhile = false;354  bool HasLabel = false;355  unsigned StatementCount = 0;356  bool SwitchLabelEncountered = false;357 358  do {359    if (FormatTok->isAttribute()) {360      nextToken();361      if (FormatTok->is(tok::l_paren))362        parseParens();363      continue;364    }365    tok::TokenKind Kind = FormatTok->Tok.getKind();366    if (FormatTok->is(TT_MacroBlockBegin))367      Kind = tok::l_brace;368    else if (FormatTok->is(TT_MacroBlockEnd))369      Kind = tok::r_brace;370 371    auto ParseDefault = [this, OpeningBrace, IfKind, &IfLBrace, &HasDoWhile,372                         &HasLabel, &StatementCount] {373      parseStructuralElement(OpeningBrace, IfKind, &IfLBrace,374                             HasDoWhile ? nullptr : &HasDoWhile,375                             HasLabel ? nullptr : &HasLabel);376      ++StatementCount;377      assert(StatementCount > 0 && "StatementCount overflow!");378    };379 380    switch (Kind) {381    case tok::comment:382      nextToken();383      addUnwrappedLine();384      break;385    case tok::l_brace:386      if (InRequiresExpression) {387        FormatTok->setFinalizedType(TT_CompoundRequirementLBrace);388      } else if (FormatTok->Previous &&389                 FormatTok->Previous->ClosesRequiresClause) {390        // We need the 'default' case here to correctly parse a function391        // l_brace.392        ParseDefault();393        continue;394      }395      if (!InRequiresExpression && FormatTok->isNot(TT_MacroBlockBegin)) {396        if (tryToParseBracedList())397          continue;398        FormatTok->setFinalizedType(TT_BlockLBrace);399      }400      parseBlock();401      ++StatementCount;402      assert(StatementCount > 0 && "StatementCount overflow!");403      addUnwrappedLine();404      break;405    case tok::r_brace:406      if (OpeningBrace) {407        if (!Style.RemoveBracesLLVM || Line->InPPDirective ||408            OpeningBrace->isNoneOf(TT_ControlStatementLBrace, TT_ElseLBrace)) {409          return false;410        }411        if (FormatTok->isNot(tok::r_brace) || StatementCount != 1 || HasLabel ||412            HasDoWhile || IsPrecededByCommentOrPPDirective ||413            precededByCommentOrPPDirective()) {414          return false;415        }416        const FormatToken *Next = Tokens->peekNextToken();417        if (Next->is(tok::comment) && Next->NewlinesBefore == 0)418          return false;419        if (IfLeftBrace)420          *IfLeftBrace = IfLBrace;421        return true;422      }423      nextToken();424      addUnwrappedLine();425      break;426    case tok::kw_default: {427      unsigned StoredPosition = Tokens->getPosition();428      auto *Next = Tokens->getNextNonComment();429      FormatTok = Tokens->setPosition(StoredPosition);430      if (Next->isNoneOf(tok::colon, tok::arrow)) {431        // default not followed by `:` or `->` is not a case label; treat it432        // like an identifier.433        parseStructuralElement();434        break;435      }436      // Else, if it is 'default:', fall through to the case handling.437      [[fallthrough]];438    }439    case tok::kw_case:440      if (Style.Language == FormatStyle::LK_Proto || Style.isVerilog() ||441          (Style.isJavaScript() && Line->MustBeDeclaration)) {442        // Proto: there are no switch/case statements443        // Verilog: Case labels don't have this word. We handle case444        // labels including default in TokenAnnotator.445        // JavaScript: A 'case: string' style field declaration.446        ParseDefault();447        break;448      }449      if (!SwitchLabelEncountered &&450          (Style.IndentCaseLabels ||451           (OpeningBrace && OpeningBrace->is(TT_SwitchExpressionLBrace)) ||452           (Line->InPPDirective && Line->Level == 1))) {453        ++Line->Level;454      }455      SwitchLabelEncountered = true;456      parseStructuralElement();457      break;458    case tok::l_square:459      if (Style.isCSharp()) {460        nextToken();461        parseCSharpAttribute();462        break;463      }464      if (handleCppAttributes())465        break;466      [[fallthrough]];467    default:468      ParseDefault();469      break;470    }471  } while (!eof());472 473  return false;474}475 476void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {477  // We'll parse forward through the tokens until we hit478  // a closing brace or eof - note that getNextToken() will479  // parse macros, so this will magically work inside macro480  // definitions, too.481  unsigned StoredPosition = Tokens->getPosition();482  FormatToken *Tok = FormatTok;483  const FormatToken *PrevTok = Tok->Previous;484  // Keep a stack of positions of lbrace tokens. We will485  // update information about whether an lbrace starts a486  // braced init list or a different block during the loop.487  struct StackEntry {488    FormatToken *Tok;489    const FormatToken *PrevTok;490  };491  SmallVector<StackEntry, 8> LBraceStack;492  assert(Tok->is(tok::l_brace));493 494  do {495    auto *NextTok = Tokens->getNextNonComment();496 497    if (!Line->InMacroBody && !Style.isTableGen()) {498      // Skip PPDirective lines (except macro definitions) and comments.499      while (NextTok->is(tok::hash)) {500        NextTok = Tokens->getNextToken();501        if (NextTok->isOneOf(tok::pp_not_keyword, tok::pp_define))502          break;503        do {504          NextTok = Tokens->getNextToken();505        } while (!NextTok->HasUnescapedNewline && NextTok->isNot(tok::eof));506 507        while (NextTok->is(tok::comment))508          NextTok = Tokens->getNextToken();509      }510    }511 512    switch (Tok->Tok.getKind()) {513    case tok::l_brace:514      if (Style.isJavaScript() && PrevTok) {515        if (PrevTok->isOneOf(tok::colon, tok::less)) {516          // A ':' indicates this code is in a type, or a braced list517          // following a label in an object literal ({a: {b: 1}}).518          // A '<' could be an object used in a comparison, but that is nonsense519          // code (can never return true), so more likely it is a generic type520          // argument (`X<{a: string; b: number}>`).521          // The code below could be confused by semicolons between the522          // individual members in a type member list, which would normally523          // trigger BK_Block. In both cases, this must be parsed as an inline524          // braced init.525          Tok->setBlockKind(BK_BracedInit);526        } else if (PrevTok->is(tok::r_paren)) {527          // `) { }` can only occur in function or method declarations in JS.528          Tok->setBlockKind(BK_Block);529        }530      } else {531        Tok->setBlockKind(BK_Unknown);532      }533      LBraceStack.push_back({Tok, PrevTok});534      break;535    case tok::r_brace:536      if (LBraceStack.empty())537        break;538      if (auto *LBrace = LBraceStack.back().Tok; LBrace->is(BK_Unknown)) {539        bool ProbablyBracedList = false;540        if (Style.Language == FormatStyle::LK_Proto) {541          ProbablyBracedList = NextTok->isOneOf(tok::comma, tok::r_square);542        } else if (LBrace->isNot(TT_EnumLBrace)) {543          // Using OriginalColumn to distinguish between ObjC methods and544          // binary operators is a bit hacky.545          bool NextIsObjCMethod = NextTok->isOneOf(tok::plus, tok::minus) &&546                                  NextTok->OriginalColumn == 0;547 548          // Try to detect a braced list. Note that regardless how we mark inner549          // braces here, we will overwrite the BlockKind later if we parse a550          // braced list (where all blocks inside are by default braced lists),551          // or when we explicitly detect blocks (for example while parsing552          // lambdas).553 554          // If we already marked the opening brace as braced list, the closing555          // must also be part of it.556          ProbablyBracedList = LBrace->is(TT_BracedListLBrace);557 558          ProbablyBracedList = ProbablyBracedList ||559                               (Style.isJavaScript() &&560                                NextTok->isOneOf(Keywords.kw_of, Keywords.kw_in,561                                                 Keywords.kw_as));562          ProbablyBracedList =563              ProbablyBracedList ||564              (IsCpp && (PrevTok->Tok.isLiteral() ||565                         NextTok->isOneOf(tok::l_paren, tok::arrow)));566 567          // If there is a comma, semicolon or right paren after the closing568          // brace, we assume this is a braced initializer list.569          // FIXME: Some of these do not apply to JS, e.g. "} {" can never be a570          // braced list in JS.571          ProbablyBracedList =572              ProbablyBracedList ||573              NextTok->isOneOf(tok::comma, tok::period, tok::colon,574                               tok::r_paren, tok::r_square, tok::ellipsis);575 576          // Distinguish between braced list in a constructor initializer list577          // followed by constructor body, or just adjacent blocks.578          ProbablyBracedList =579              ProbablyBracedList ||580              (NextTok->is(tok::l_brace) && LBraceStack.back().PrevTok &&581               LBraceStack.back().PrevTok->isOneOf(tok::identifier,582                                                   tok::greater));583 584          ProbablyBracedList =585              ProbablyBracedList ||586              (NextTok->is(tok::identifier) &&587               PrevTok->isNoneOf(tok::semi, tok::r_brace, tok::l_brace));588 589          ProbablyBracedList = ProbablyBracedList ||590                               (NextTok->is(tok::semi) &&591                                (!ExpectClassBody || LBraceStack.size() != 1));592 593          ProbablyBracedList =594              ProbablyBracedList ||595              (NextTok->isBinaryOperator() && !NextIsObjCMethod);596 597          if (!Style.isCSharp() && NextTok->is(tok::l_square)) {598            // We can have an array subscript after a braced init599            // list, but C++11 attributes are expected after blocks.600            NextTok = Tokens->getNextToken();601            ProbablyBracedList = NextTok->isNot(tok::l_square);602          }603 604          // Cpp macro definition body that is a nonempty braced list or block:605          if (IsCpp && Line->InMacroBody && PrevTok != FormatTok &&606              !FormatTok->Previous && NextTok->is(tok::eof) &&607              // A statement can end with only `;` (simple statement), a block608              // closing brace (compound statement), or `:` (label statement).609              // If PrevTok is a block opening brace, Tok ends an empty block.610              PrevTok->isNoneOf(tok::semi, BK_Block, tok::colon)) {611            ProbablyBracedList = true;612          }613        }614        const auto BlockKind = ProbablyBracedList ? BK_BracedInit : BK_Block;615        Tok->setBlockKind(BlockKind);616        LBrace->setBlockKind(BlockKind);617      }618      LBraceStack.pop_back();619      break;620    case tok::identifier:621      if (Tok->isNot(TT_StatementMacro))622        break;623      [[fallthrough]];624    case tok::at:625    case tok::semi:626    case tok::kw_if:627    case tok::kw_while:628    case tok::kw_for:629    case tok::kw_switch:630    case tok::kw_try:631    case tok::kw___try:632      if (!LBraceStack.empty() && LBraceStack.back().Tok->is(BK_Unknown))633        LBraceStack.back().Tok->setBlockKind(BK_Block);634      break;635    default:636      break;637    }638 639    PrevTok = Tok;640    Tok = NextTok;641  } while (Tok->isNot(tok::eof) && !LBraceStack.empty());642 643  // Assume other blocks for all unclosed opening braces.644  for (const auto &Entry : LBraceStack)645    if (Entry.Tok->is(BK_Unknown))646      Entry.Tok->setBlockKind(BK_Block);647 648  FormatTok = Tokens->setPosition(StoredPosition);649}650 651// Sets the token type of the directly previous right brace.652void UnwrappedLineParser::setPreviousRBraceType(TokenType Type) {653  if (auto Prev = FormatTok->getPreviousNonComment();654      Prev && Prev->is(tok::r_brace)) {655    Prev->setFinalizedType(Type);656  }657}658 659template <class T>660static inline void hash_combine(std::size_t &seed, const T &v) {661  std::hash<T> hasher;662  seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);663}664 665size_t UnwrappedLineParser::computePPHash() const {666  size_t h = 0;667  for (const auto &i : PPStack) {668    hash_combine(h, size_t(i.Kind));669    hash_combine(h, i.Line);670  }671  return h;672}673 674// Checks whether \p ParsedLine might fit on a single line. If \p OpeningBrace675// is not null, subtracts its length (plus the preceding space) when computing676// the length of \p ParsedLine. We must clone the tokens of \p ParsedLine before677// running the token annotator on it so that we can restore them afterward.678bool UnwrappedLineParser::mightFitOnOneLine(679    UnwrappedLine &ParsedLine, const FormatToken *OpeningBrace) const {680  const auto ColumnLimit = Style.ColumnLimit;681  if (ColumnLimit == 0)682    return true;683 684  auto &Tokens = ParsedLine.Tokens;685  assert(!Tokens.empty());686 687  const auto *LastToken = Tokens.back().Tok;688  assert(LastToken);689 690  SmallVector<UnwrappedLineNode> SavedTokens(Tokens.size());691 692  int Index = 0;693  for (const auto &Token : Tokens) {694    assert(Token.Tok);695    auto &SavedToken = SavedTokens[Index++];696    SavedToken.Tok = new FormatToken;697    SavedToken.Tok->copyFrom(*Token.Tok);698    SavedToken.Children = std::move(Token.Children);699  }700 701  AnnotatedLine Line(ParsedLine);702  assert(Line.Last == LastToken);703 704  TokenAnnotator Annotator(Style, Keywords);705  Annotator.annotate(Line);706  Annotator.calculateFormattingInformation(Line);707 708  auto Length = LastToken->TotalLength;709  if (OpeningBrace) {710    assert(OpeningBrace != Tokens.front().Tok);711    if (auto Prev = OpeningBrace->Previous;712        Prev && Prev->TotalLength + ColumnLimit == OpeningBrace->TotalLength) {713      Length -= ColumnLimit;714    }715    Length -= OpeningBrace->TokenText.size() + 1;716  }717 718  if (const auto *FirstToken = Line.First; FirstToken->is(tok::r_brace)) {719    assert(!OpeningBrace || OpeningBrace->is(TT_ControlStatementLBrace));720    Length -= FirstToken->TokenText.size() + 1;721  }722 723  Index = 0;724  for (auto &Token : Tokens) {725    const auto &SavedToken = SavedTokens[Index++];726    Token.Tok->copyFrom(*SavedToken.Tok);727    Token.Children = std::move(SavedToken.Children);728    delete SavedToken.Tok;729  }730 731  // If these change PPLevel needs to be used for get correct indentation.732  assert(!Line.InMacroBody);733  assert(!Line.InPPDirective);734  return Line.Level * Style.IndentWidth + Length <= ColumnLimit;735}736 737FormatToken *UnwrappedLineParser::parseBlock(bool MustBeDeclaration,738                                             unsigned AddLevels, bool MunchSemi,739                                             bool KeepBraces,740                                             IfStmtKind *IfKind,741                                             bool UnindentWhitesmithsBraces) {742  auto HandleVerilogBlockLabel = [this]() {743    // ":" name744    if (Style.isVerilog() && FormatTok->is(tok::colon)) {745      nextToken();746      if (Keywords.isVerilogIdentifier(*FormatTok))747        nextToken();748    }749  };750 751  // Whether this is a Verilog-specific block that has a special header like a752  // module.753  const bool VerilogHierarchy =754      Style.isVerilog() && Keywords.isVerilogHierarchy(*FormatTok);755  assert((FormatTok->isOneOf(tok::l_brace, TT_MacroBlockBegin) ||756          (Style.isVerilog() &&757           (Keywords.isVerilogBegin(*FormatTok) || VerilogHierarchy))) &&758         "'{' or macro block token expected");759  FormatToken *Tok = FormatTok;760  const bool FollowedByComment = Tokens->peekNextToken()->is(tok::comment);761  auto Index = CurrentLines->size();762  const bool MacroBlock = FormatTok->is(TT_MacroBlockBegin);763  FormatTok->setBlockKind(BK_Block);764 765  // For Whitesmiths mode, jump to the next level prior to skipping over the766  // braces.767  if (!VerilogHierarchy && AddLevels > 0 &&768      Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths) {769    ++Line->Level;770  }771 772  size_t PPStartHash = computePPHash();773 774  const unsigned InitialLevel = Line->Level;775  if (VerilogHierarchy) {776    AddLevels += parseVerilogHierarchyHeader();777  } else {778    nextToken(/*LevelDifference=*/AddLevels);779    HandleVerilogBlockLabel();780  }781 782  // Bail out if there are too many levels. Otherwise, the stack might overflow.783  if (Line->Level > 300)784    return nullptr;785 786  if (MacroBlock && FormatTok->is(tok::l_paren))787    parseParens();788 789  size_t NbPreprocessorDirectives =790      !parsingPPDirective() ? PreprocessorDirectives.size() : 0;791  addUnwrappedLine();792  size_t OpeningLineIndex =793      CurrentLines->empty()794          ? (UnwrappedLine::kInvalidIndex)795          : (CurrentLines->size() - 1 - NbPreprocessorDirectives);796 797  // Whitesmiths is weird here. The brace needs to be indented for the namespace798  // block, but the block itself may not be indented depending on the style799  // settings. This allows the format to back up one level in those cases.800  if (UnindentWhitesmithsBraces)801    --Line->Level;802 803  ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,804                                          MustBeDeclaration);805  if (AddLevels > 0u && Style.BreakBeforeBraces != FormatStyle::BS_Whitesmiths)806    Line->Level += AddLevels;807 808  FormatToken *IfLBrace = nullptr;809  const bool SimpleBlock = parseLevel(Tok, IfKind, &IfLBrace);810 811  if (eof())812    return IfLBrace;813 814  if (MacroBlock ? FormatTok->isNot(TT_MacroBlockEnd)815                 : FormatTok->isNot(tok::r_brace)) {816    Line->Level = InitialLevel;817    FormatTok->setBlockKind(BK_Block);818    return IfLBrace;819  }820 821  if (FormatTok->is(tok::r_brace)) {822    FormatTok->setBlockKind(BK_Block);823    if (Tok->is(TT_NamespaceLBrace))824      FormatTok->setFinalizedType(TT_NamespaceRBrace);825  }826 827  const bool IsFunctionRBrace =828      FormatTok->is(tok::r_brace) && Tok->is(TT_FunctionLBrace);829 830  auto RemoveBraces = [=]() mutable {831    if (!SimpleBlock)832      return false;833    assert(Tok->isOneOf(TT_ControlStatementLBrace, TT_ElseLBrace));834    assert(FormatTok->is(tok::r_brace));835    const bool WrappedOpeningBrace = !Tok->Previous;836    if (WrappedOpeningBrace && FollowedByComment)837      return false;838    const bool HasRequiredIfBraces = IfLBrace && !IfLBrace->Optional;839    if (KeepBraces && !HasRequiredIfBraces)840      return false;841    if (Tok->isNot(TT_ElseLBrace) || !HasRequiredIfBraces) {842      const FormatToken *Previous = Tokens->getPreviousToken();843      assert(Previous);844      if (Previous->is(tok::r_brace) && !Previous->Optional)845        return false;846    }847    assert(!CurrentLines->empty());848    auto &LastLine = CurrentLines->back();849    if (LastLine.Level == InitialLevel + 1 && !mightFitOnOneLine(LastLine))850      return false;851    if (Tok->is(TT_ElseLBrace))852      return true;853    if (WrappedOpeningBrace) {854      assert(Index > 0);855      --Index; // The line above the wrapped l_brace.856      Tok = nullptr;857    }858    return mightFitOnOneLine((*CurrentLines)[Index], Tok);859  };860  if (RemoveBraces()) {861    Tok->MatchingParen = FormatTok;862    FormatTok->MatchingParen = Tok;863  }864 865  size_t PPEndHash = computePPHash();866 867  // Munch the closing brace.868  nextToken(/*LevelDifference=*/-AddLevels);869 870  // When this is a function block and there is an unnecessary semicolon871  // afterwards then mark it as optional (so the RemoveSemi pass can get rid of872  // it later).873  if (Style.RemoveSemicolon && IsFunctionRBrace) {874    while (FormatTok->is(tok::semi)) {875      FormatTok->Optional = true;876      nextToken();877    }878  }879 880  HandleVerilogBlockLabel();881 882  if (MacroBlock && FormatTok->is(tok::l_paren))883    parseParens();884 885  Line->Level = InitialLevel;886 887  if (FormatTok->is(tok::kw_noexcept)) {888    // A noexcept in a requires expression.889    nextToken();890  }891 892  if (FormatTok->is(tok::arrow)) {893    // Following the } or noexcept we can find a trailing return type arrow894    // as part of an implicit conversion constraint.895    nextToken();896    parseStructuralElement();897  }898 899  if (MunchSemi && FormatTok->is(tok::semi))900    nextToken();901 902  if (PPStartHash == PPEndHash) {903    Line->MatchingOpeningBlockLineIndex = OpeningLineIndex;904    if (OpeningLineIndex != UnwrappedLine::kInvalidIndex) {905      // Update the opening line to add the forward reference as well906      (*CurrentLines)[OpeningLineIndex].MatchingClosingBlockLineIndex =907          CurrentLines->size() - 1;908    }909  }910 911  return IfLBrace;912}913 914static bool isGoogScope(const UnwrappedLine &Line) {915  // FIXME: Closure-library specific stuff should not be hard-coded but be916  // configurable.917  if (Line.Tokens.size() < 4)918    return false;919  auto I = Line.Tokens.begin();920  if (I->Tok->TokenText != "goog")921    return false;922  ++I;923  if (I->Tok->isNot(tok::period))924    return false;925  ++I;926  if (I->Tok->TokenText != "scope")927    return false;928  ++I;929  return I->Tok->is(tok::l_paren);930}931 932static bool isIIFE(const UnwrappedLine &Line,933                   const AdditionalKeywords &Keywords) {934  // Look for the start of an immediately invoked anonymous function.935  // https://en.wikipedia.org/wiki/Immediately-invoked_function_expression936  // This is commonly done in JavaScript to create a new, anonymous scope.937  // Example: (function() { ... })()938  if (Line.Tokens.size() < 3)939    return false;940  auto I = Line.Tokens.begin();941  if (I->Tok->isNot(tok::l_paren))942    return false;943  ++I;944  if (I->Tok->isNot(Keywords.kw_function))945    return false;946  ++I;947  return I->Tok->is(tok::l_paren);948}949 950static bool ShouldBreakBeforeBrace(const FormatStyle &Style,951                                   const FormatToken &InitialToken,952                                   const bool IsJavaRecord) {953  if (IsJavaRecord)954    return Style.BraceWrapping.AfterClass;955 956  tok::TokenKind Kind = InitialToken.Tok.getKind();957  if (InitialToken.is(TT_NamespaceMacro))958    Kind = tok::kw_namespace;959 960  switch (Kind) {961  case tok::kw_namespace:962    return Style.BraceWrapping.AfterNamespace;963  case tok::kw_class:964    return Style.BraceWrapping.AfterClass;965  case tok::kw_union:966    return Style.BraceWrapping.AfterUnion;967  case tok::kw_struct:968    return Style.BraceWrapping.AfterStruct;969  case tok::kw_enum:970    return Style.BraceWrapping.AfterEnum;971  default:972    return false;973  }974}975 976void UnwrappedLineParser::parseChildBlock() {977  assert(FormatTok->is(tok::l_brace));978  FormatTok->setBlockKind(BK_Block);979  const FormatToken *OpeningBrace = FormatTok;980  nextToken();981  {982    bool SkipIndent = (Style.isJavaScript() &&983                       (isGoogScope(*Line) || isIIFE(*Line, Keywords)));984    ScopedLineState LineState(*this);985    ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,986                                            /*MustBeDeclaration=*/false);987    Line->Level += SkipIndent ? 0 : 1;988    parseLevel(OpeningBrace);989    flushComments(isOnNewLine(*FormatTok));990    Line->Level -= SkipIndent ? 0 : 1;991  }992  nextToken();993}994 995void UnwrappedLineParser::parsePPDirective() {996  assert(FormatTok->is(tok::hash) && "'#' expected");997  ScopedMacroState MacroState(*Line, Tokens, FormatTok);998 999  nextToken();1000 1001  if (!FormatTok->Tok.getIdentifierInfo()) {1002    parsePPUnknown();1003    return;1004  }1005 1006  switch (FormatTok->Tok.getIdentifierInfo()->getPPKeywordID()) {1007  case tok::pp_define:1008    parsePPDefine();1009    return;1010  case tok::pp_if:1011    parsePPIf(/*IfDef=*/false);1012    break;1013  case tok::pp_ifdef:1014  case tok::pp_ifndef:1015    parsePPIf(/*IfDef=*/true);1016    break;1017  case tok::pp_else:1018  case tok::pp_elifdef:1019  case tok::pp_elifndef:1020  case tok::pp_elif:1021    parsePPElse();1022    break;1023  case tok::pp_endif:1024    parsePPEndIf();1025    break;1026  case tok::pp_pragma:1027    parsePPPragma();1028    break;1029  case tok::pp_error:1030  case tok::pp_warning:1031    nextToken();1032    if (!eof() && Style.isCpp())1033      FormatTok->setFinalizedType(TT_AfterPPDirective);1034    [[fallthrough]];1035  default:1036    parsePPUnknown();1037    break;1038  }1039}1040 1041void UnwrappedLineParser::conditionalCompilationCondition(bool Unreachable) {1042  size_t Line = CurrentLines->size();1043  if (CurrentLines == &PreprocessorDirectives)1044    Line += Lines.size();1045 1046  if (Unreachable ||1047      (!PPStack.empty() && PPStack.back().Kind == PP_Unreachable)) {1048    PPStack.push_back({PP_Unreachable, Line});1049  } else {1050    PPStack.push_back({PP_Conditional, Line});1051  }1052}1053 1054void UnwrappedLineParser::conditionalCompilationStart(bool Unreachable) {1055  ++PPBranchLevel;1056  assert(PPBranchLevel >= 0 && PPBranchLevel <= (int)PPLevelBranchIndex.size());1057  if (PPBranchLevel == (int)PPLevelBranchIndex.size()) {1058    PPLevelBranchIndex.push_back(0);1059    PPLevelBranchCount.push_back(0);1060  }1061  PPChainBranchIndex.push(Unreachable ? -1 : 0);1062  bool Skip = PPLevelBranchIndex[PPBranchLevel] > 0;1063  conditionalCompilationCondition(Unreachable || Skip);1064}1065 1066void UnwrappedLineParser::conditionalCompilationAlternative() {1067  if (!PPStack.empty())1068    PPStack.pop_back();1069  assert(PPBranchLevel < (int)PPLevelBranchIndex.size());1070  if (!PPChainBranchIndex.empty())1071    ++PPChainBranchIndex.top();1072  conditionalCompilationCondition(1073      PPBranchLevel >= 0 && !PPChainBranchIndex.empty() &&1074      PPLevelBranchIndex[PPBranchLevel] != PPChainBranchIndex.top());1075}1076 1077void UnwrappedLineParser::conditionalCompilationEnd() {1078  assert(PPBranchLevel < (int)PPLevelBranchIndex.size());1079  if (PPBranchLevel >= 0 && !PPChainBranchIndex.empty()) {1080    if (PPChainBranchIndex.top() + 1 > PPLevelBranchCount[PPBranchLevel])1081      PPLevelBranchCount[PPBranchLevel] = PPChainBranchIndex.top() + 1;1082  }1083  // Guard against #endif's without #if.1084  if (PPBranchLevel > -1)1085    --PPBranchLevel;1086  if (!PPChainBranchIndex.empty())1087    PPChainBranchIndex.pop();1088  if (!PPStack.empty())1089    PPStack.pop_back();1090}1091 1092void UnwrappedLineParser::parsePPIf(bool IfDef) {1093  bool IfNDef = FormatTok->is(tok::pp_ifndef);1094  nextToken();1095  bool Unreachable = false;1096  if (!IfDef && (FormatTok->is(tok::kw_false) || FormatTok->TokenText == "0"))1097    Unreachable = true;1098  if (IfDef && !IfNDef && FormatTok->TokenText == "SWIG")1099    Unreachable = true;1100  conditionalCompilationStart(Unreachable);1101  FormatToken *IfCondition = FormatTok;1102  // If there's a #ifndef on the first line, and the only lines before it are1103  // comments, it could be an include guard.1104  bool MaybeIncludeGuard = IfNDef;1105  if (IncludeGuard == IG_Inited && MaybeIncludeGuard) {1106    for (auto &Line : Lines) {1107      if (Line.Tokens.front().Tok->isNot(tok::comment)) {1108        MaybeIncludeGuard = false;1109        IncludeGuard = IG_Rejected;1110        break;1111      }1112    }1113  }1114  --PPBranchLevel;1115  parsePPUnknown();1116  ++PPBranchLevel;1117  if (IncludeGuard == IG_Inited && MaybeIncludeGuard) {1118    IncludeGuard = IG_IfNdefed;1119    IncludeGuardToken = IfCondition;1120  }1121}1122 1123void UnwrappedLineParser::parsePPElse() {1124  // If a potential include guard has an #else, it's not an include guard.1125  if (IncludeGuard == IG_Defined && PPBranchLevel == 0)1126    IncludeGuard = IG_Rejected;1127  // Don't crash when there is an #else without an #if.1128  assert(PPBranchLevel >= -1);1129  if (PPBranchLevel == -1)1130    conditionalCompilationStart(/*Unreachable=*/true);1131  conditionalCompilationAlternative();1132  --PPBranchLevel;1133  parsePPUnknown();1134  ++PPBranchLevel;1135}1136 1137void UnwrappedLineParser::parsePPEndIf() {1138  conditionalCompilationEnd();1139  parsePPUnknown();1140  // If the #endif of a potential include guard is the last thing in the file,1141  // then we found an include guard.1142  if (IncludeGuard == IG_Defined && PPBranchLevel == -1 && Tokens->isEOF() &&1143      getIncludeGuardState(Style.IndentPPDirectives) == IG_Inited) {1144    IncludeGuard = IG_Found;1145  }1146}1147 1148void UnwrappedLineParser::parsePPDefine() {1149  nextToken();1150 1151  if (!FormatTok->Tok.getIdentifierInfo()) {1152    IncludeGuard = IG_Rejected;1153    IncludeGuardToken = nullptr;1154    parsePPUnknown();1155    return;1156  }1157 1158  bool MaybeIncludeGuard = false;1159  if (IncludeGuard == IG_IfNdefed &&1160      IncludeGuardToken->TokenText == FormatTok->TokenText) {1161    IncludeGuard = IG_Defined;1162    IncludeGuardToken = nullptr;1163    for (auto &Line : Lines) {1164      if (Line.Tokens.front().Tok->isNoneOf(tok::comment, tok::hash)) {1165        IncludeGuard = IG_Rejected;1166        break;1167      }1168    }1169    MaybeIncludeGuard = IncludeGuard == IG_Defined;1170  }1171 1172  // In the context of a define, even keywords should be treated as normal1173  // identifiers. Setting the kind to identifier is not enough, because we need1174  // to treat additional keywords like __except as well, which are already1175  // identifiers. Setting the identifier info to null interferes with include1176  // guard processing above, and changes preprocessing nesting.1177  FormatTok->Tok.setKind(tok::identifier);1178  FormatTok->Tok.setIdentifierInfo(Keywords.kw_internal_ident_after_define);1179  nextToken();1180 1181  // IncludeGuard can't have a non-empty macro definition.1182  if (MaybeIncludeGuard && !eof())1183    IncludeGuard = IG_Rejected;1184 1185  if (FormatTok->is(tok::l_paren) && !FormatTok->hasWhitespaceBefore())1186    parseParens();1187  if (Style.IndentPPDirectives != FormatStyle::PPDIS_None)1188    Line->Level += PPBranchLevel + 1;1189  addUnwrappedLine();1190  ++Line->Level;1191 1192  Line->PPLevel = PPBranchLevel + (IncludeGuard == IG_Defined ? 0 : 1);1193  assert((int)Line->PPLevel >= 0);1194 1195  if (eof())1196    return;1197 1198  Line->InMacroBody = true;1199 1200  if (!Style.SkipMacroDefinitionBody) {1201    // Errors during a preprocessor directive can only affect the layout of the1202    // preprocessor directive, and thus we ignore them. An alternative approach1203    // would be to use the same approach we use on the file level (no1204    // re-indentation if there was a structural error) within the macro1205    // definition.1206    parseFile();1207    return;1208  }1209 1210  for (auto *Comment : CommentsBeforeNextToken)1211    Comment->Finalized = true;1212 1213  do {1214    FormatTok->Finalized = true;1215    FormatTok = Tokens->getNextToken();1216  } while (!eof());1217 1218  addUnwrappedLine();1219}1220 1221void UnwrappedLineParser::parsePPPragma() {1222  Line->InPragmaDirective = true;1223  parsePPUnknown();1224}1225 1226void UnwrappedLineParser::parsePPUnknown() {1227  while (!eof())1228    nextToken();1229  if (Style.IndentPPDirectives != FormatStyle::PPDIS_None)1230    Line->Level += PPBranchLevel + 1;1231  addUnwrappedLine();1232}1233 1234// Here we exclude certain tokens that are not usually the first token in an1235// unwrapped line. This is used in attempt to distinguish macro calls without1236// trailing semicolons from other constructs split to several lines.1237static bool tokenCanStartNewLine(const FormatToken &Tok) {1238  // Semicolon can be a null-statement, l_square can be a start of a macro or1239  // a C++11 attribute, but this doesn't seem to be common.1240  return Tok.isNoneOf(tok::semi, tok::l_brace,1241                      // Tokens that can only be used as binary operators and a1242                      // part of overloaded operator names.1243                      tok::period, tok::periodstar, tok::arrow, tok::arrowstar,1244                      tok::less, tok::greater, tok::slash, tok::percent,1245                      tok::lessless, tok::greatergreater, tok::equal,1246                      tok::plusequal, tok::minusequal, tok::starequal,1247                      tok::slashequal, tok::percentequal, tok::ampequal,1248                      tok::pipeequal, tok::caretequal, tok::greatergreaterequal,1249                      tok::lesslessequal,1250                      // Colon is used in labels, base class lists, initializer1251                      // lists, range-based for loops, ternary operator, but1252                      // should never be the first token in an unwrapped line.1253                      tok::colon,1254                      // 'noexcept' is a trailing annotation.1255                      tok::kw_noexcept);1256}1257 1258static bool mustBeJSIdent(const AdditionalKeywords &Keywords,1259                          const FormatToken *FormatTok) {1260  // FIXME: This returns true for C/C++ keywords like 'struct'.1261  return FormatTok->is(tok::identifier) &&1262         (!FormatTok->Tok.getIdentifierInfo() ||1263          FormatTok->isNoneOf(1264              Keywords.kw_in, Keywords.kw_of, Keywords.kw_as, Keywords.kw_async,1265              Keywords.kw_await, Keywords.kw_yield, Keywords.kw_finally,1266              Keywords.kw_function, Keywords.kw_import, Keywords.kw_is,1267              Keywords.kw_let, Keywords.kw_var, tok::kw_const,1268              Keywords.kw_abstract, Keywords.kw_extends, Keywords.kw_implements,1269              Keywords.kw_instanceof, Keywords.kw_interface,1270              Keywords.kw_override, Keywords.kw_throws, Keywords.kw_from));1271}1272 1273static bool mustBeJSIdentOrValue(const AdditionalKeywords &Keywords,1274                                 const FormatToken *FormatTok) {1275  return FormatTok->Tok.isLiteral() ||1276         FormatTok->isOneOf(tok::kw_true, tok::kw_false) ||1277         mustBeJSIdent(Keywords, FormatTok);1278}1279 1280// isJSDeclOrStmt returns true if |FormatTok| starts a declaration or statement1281// when encountered after a value (see mustBeJSIdentOrValue).1282static bool isJSDeclOrStmt(const AdditionalKeywords &Keywords,1283                           const FormatToken *FormatTok) {1284  return FormatTok->isOneOf(1285      tok::kw_return, Keywords.kw_yield,1286      // conditionals1287      tok::kw_if, tok::kw_else,1288      // loops1289      tok::kw_for, tok::kw_while, tok::kw_do, tok::kw_continue, tok::kw_break,1290      // switch/case1291      tok::kw_switch, tok::kw_case,1292      // exceptions1293      tok::kw_throw, tok::kw_try, tok::kw_catch, Keywords.kw_finally,1294      // declaration1295      tok::kw_const, tok::kw_class, Keywords.kw_var, Keywords.kw_let,1296      Keywords.kw_async, Keywords.kw_function,1297      // import/export1298      Keywords.kw_import, tok::kw_export);1299}1300 1301// Checks whether a token is a type in K&R C (aka C78).1302static bool isC78Type(const FormatToken &Tok) {1303  return Tok.isOneOf(tok::kw_char, tok::kw_short, tok::kw_int, tok::kw_long,1304                     tok::kw_unsigned, tok::kw_float, tok::kw_double,1305                     tok::identifier);1306}1307 1308// This function checks whether a token starts the first parameter declaration1309// in a K&R C (aka C78) function definition, e.g.:1310//   int f(a, b)1311//   short a, b;1312//   {1313//      return a + b;1314//   }1315static bool isC78ParameterDecl(const FormatToken *Tok, const FormatToken *Next,1316                               const FormatToken *FuncName) {1317  assert(Tok);1318  assert(Next);1319  assert(FuncName);1320 1321  if (FuncName->isNot(tok::identifier))1322    return false;1323 1324  const FormatToken *Prev = FuncName->Previous;1325  if (!Prev || (Prev->isNot(tok::star) && !isC78Type(*Prev)))1326    return false;1327 1328  if (!isC78Type(*Tok) &&1329      Tok->isNoneOf(tok::kw_register, tok::kw_struct, tok::kw_union)) {1330    return false;1331  }1332 1333  if (Next->isNot(tok::star) && !Next->Tok.getIdentifierInfo())1334    return false;1335 1336  Tok = Tok->Previous;1337  if (!Tok || Tok->isNot(tok::r_paren))1338    return false;1339 1340  Tok = Tok->Previous;1341  if (!Tok || Tok->isNot(tok::identifier))1342    return false;1343 1344  return Tok->Previous && Tok->Previous->isOneOf(tok::l_paren, tok::comma);1345}1346 1347bool UnwrappedLineParser::parseModuleImport() {1348  assert(FormatTok->is(Keywords.kw_import) && "'import' expected");1349 1350  if (auto Token = Tokens->peekNextToken(/*SkipComment=*/true);1351      !Token->Tok.getIdentifierInfo() &&1352      Token->isNoneOf(tok::colon, tok::less, tok::string_literal)) {1353    return false;1354  }1355 1356  nextToken();1357  while (!eof()) {1358    if (FormatTok->is(tok::colon)) {1359      FormatTok->setFinalizedType(TT_ModulePartitionColon);1360    }1361    // Handle import <foo/bar.h> as we would an include statement.1362    else if (FormatTok->is(tok::less)) {1363      nextToken();1364      while (FormatTok->isNoneOf(tok::semi, tok::greater) && !eof()) {1365        // Mark tokens up to the trailing line comments as implicit string1366        // literals.1367        if (FormatTok->isNot(tok::comment) &&1368            !FormatTok->TokenText.starts_with("//")) {1369          FormatTok->setFinalizedType(TT_ImplicitStringLiteral);1370        }1371        nextToken();1372      }1373    }1374    if (FormatTok->is(tok::semi)) {1375      nextToken();1376      break;1377    }1378    nextToken();1379  }1380 1381  addUnwrappedLine();1382  return true;1383}1384 1385// readTokenWithJavaScriptASI reads the next token and terminates the current1386// line if JavaScript Automatic Semicolon Insertion must1387// happen between the current token and the next token.1388//1389// This method is conservative - it cannot cover all edge cases of JavaScript,1390// but only aims to correctly handle certain well known cases. It *must not*1391// return true in speculative cases.1392void UnwrappedLineParser::readTokenWithJavaScriptASI() {1393  FormatToken *Previous = FormatTok;1394  readToken();1395  FormatToken *Next = FormatTok;1396 1397  bool IsOnSameLine =1398      CommentsBeforeNextToken.empty()1399          ? Next->NewlinesBefore == 01400          : CommentsBeforeNextToken.front()->NewlinesBefore == 0;1401  if (IsOnSameLine)1402    return;1403 1404  bool PreviousMustBeValue = mustBeJSIdentOrValue(Keywords, Previous);1405  bool PreviousStartsTemplateExpr =1406      Previous->is(TT_TemplateString) && Previous->TokenText.ends_with("${");1407  if (PreviousMustBeValue || Previous->is(tok::r_paren)) {1408    // If the line contains an '@' sign, the previous token might be an1409    // annotation, which can precede another identifier/value.1410    bool HasAt = llvm::any_of(Line->Tokens, [](UnwrappedLineNode &LineNode) {1411      return LineNode.Tok->is(tok::at);1412    });1413    if (HasAt)1414      return;1415  }1416  if (Next->is(tok::exclaim) && PreviousMustBeValue)1417    return addUnwrappedLine();1418  bool NextMustBeValue = mustBeJSIdentOrValue(Keywords, Next);1419  bool NextEndsTemplateExpr =1420      Next->is(TT_TemplateString) && Next->TokenText.starts_with("}");1421  if (NextMustBeValue && !NextEndsTemplateExpr && !PreviousStartsTemplateExpr &&1422      (PreviousMustBeValue ||1423       Previous->isOneOf(tok::r_square, tok::r_paren, tok::plusplus,1424                         tok::minusminus))) {1425    return addUnwrappedLine();1426  }1427  if ((PreviousMustBeValue || Previous->is(tok::r_paren)) &&1428      isJSDeclOrStmt(Keywords, Next)) {1429    return addUnwrappedLine();1430  }1431}1432 1433void UnwrappedLineParser::parseStructuralElement(1434    const FormatToken *OpeningBrace, IfStmtKind *IfKind,1435    FormatToken **IfLeftBrace, bool *HasDoWhile, bool *HasLabel) {1436  if (Style.isTableGen() && FormatTok->is(tok::pp_include)) {1437    nextToken();1438    if (FormatTok->is(tok::string_literal))1439      nextToken();1440    addUnwrappedLine();1441    return;1442  }1443 1444  if (IsCpp) {1445    while (FormatTok->is(tok::l_square) && handleCppAttributes()) {1446    }1447  } else if (Style.isVerilog()) {1448    if (Keywords.isVerilogStructuredProcedure(*FormatTok)) {1449      parseForOrWhileLoop(/*HasParens=*/false);1450      return;1451    }1452    if (FormatTok->isOneOf(Keywords.kw_foreach, Keywords.kw_repeat)) {1453      parseForOrWhileLoop();1454      return;1455    }1456    if (FormatTok->isOneOf(tok::kw_restrict, Keywords.kw_assert,1457                           Keywords.kw_assume, Keywords.kw_cover)) {1458      parseIfThenElse(IfKind, /*KeepBraces=*/false, /*IsVerilogAssert=*/true);1459      return;1460    }1461 1462    // Skip things that can exist before keywords like 'if' and 'case'.1463    while (true) {1464      if (FormatTok->isOneOf(Keywords.kw_priority, Keywords.kw_unique,1465                             Keywords.kw_unique0)) {1466        nextToken();1467      } else if (FormatTok->is(tok::l_paren) &&1468                 Tokens->peekNextToken()->is(tok::star)) {1469        parseParens();1470      } else {1471        break;1472      }1473    }1474  }1475 1476  // Tokens that only make sense at the beginning of a line.1477  if (FormatTok->isAccessSpecifierKeyword()) {1478    if (Style.isJava() || Style.isJavaScript() || Style.isCSharp())1479      nextToken();1480    else1481      parseAccessSpecifier();1482    return;1483  }1484  switch (FormatTok->Tok.getKind()) {1485  case tok::kw_asm:1486    nextToken();1487    if (FormatTok->is(tok::l_brace)) {1488      FormatTok->setFinalizedType(TT_InlineASMBrace);1489      nextToken();1490      while (FormatTok && !eof()) {1491        if (FormatTok->is(tok::r_brace)) {1492          FormatTok->setFinalizedType(TT_InlineASMBrace);1493          nextToken();1494          addUnwrappedLine();1495          break;1496        }1497        FormatTok->Finalized = true;1498        nextToken();1499      }1500    }1501    break;1502  case tok::kw_namespace:1503    parseNamespace();1504    return;1505  case tok::kw_if: {1506    if (Style.isJavaScript() && Line->MustBeDeclaration) {1507      // field/method declaration.1508      break;1509    }1510    FormatToken *Tok = parseIfThenElse(IfKind);1511    if (IfLeftBrace)1512      *IfLeftBrace = Tok;1513    return;1514  }1515  case tok::kw_for:1516  case tok::kw_while:1517    if (Style.isJavaScript() && Line->MustBeDeclaration) {1518      // field/method declaration.1519      break;1520    }1521    parseForOrWhileLoop();1522    return;1523  case tok::kw_do:1524    if (Style.isJavaScript() && Line->MustBeDeclaration) {1525      // field/method declaration.1526      break;1527    }1528    parseDoWhile();1529    if (HasDoWhile)1530      *HasDoWhile = true;1531    return;1532  case tok::kw_switch:1533    if (Style.isJavaScript() && Line->MustBeDeclaration) {1534      // 'switch: string' field declaration.1535      break;1536    }1537    parseSwitch(/*IsExpr=*/false);1538    return;1539  case tok::kw_default: {1540    // In Verilog default along with other labels are handled in the next loop.1541    if (Style.isVerilog())1542      break;1543    if (Style.isJavaScript() && Line->MustBeDeclaration) {1544      // 'default: string' field declaration.1545      break;1546    }1547    auto *Default = FormatTok;1548    nextToken();1549    if (FormatTok->is(tok::colon)) {1550      FormatTok->setFinalizedType(TT_CaseLabelColon);1551      parseLabel();1552      return;1553    }1554    if (FormatTok->is(tok::arrow)) {1555      FormatTok->setFinalizedType(TT_CaseLabelArrow);1556      Default->setFinalizedType(TT_SwitchExpressionLabel);1557      parseLabel();1558      return;1559    }1560    // e.g. "default void f() {}" in a Java interface.1561    break;1562  }1563  case tok::kw_case:1564    // Proto: there are no switch/case statements.1565    if (Style.Language == FormatStyle::LK_Proto) {1566      nextToken();1567      return;1568    }1569    if (Style.isVerilog()) {1570      parseBlock();1571      addUnwrappedLine();1572      return;1573    }1574    if (Style.isJavaScript() && Line->MustBeDeclaration) {1575      // 'case: string' field declaration.1576      nextToken();1577      break;1578    }1579    parseCaseLabel();1580    return;1581  case tok::kw_goto:1582    nextToken();1583    if (FormatTok->is(tok::kw_case))1584      nextToken();1585    break;1586  case tok::kw_try:1587  case tok::kw___try:1588    if (Style.isJavaScript() && Line->MustBeDeclaration) {1589      // field/method declaration.1590      break;1591    }1592    parseTryCatch();1593    return;1594  case tok::kw_extern:1595    if (Style.isVerilog()) {1596      // In Verilog an extern module declaration looks like a start of module.1597      // But there is no body and endmodule. So we handle it separately.1598      parseVerilogExtern();1599      return;1600    }1601    nextToken();1602    if (FormatTok->is(tok::string_literal)) {1603      nextToken();1604      if (FormatTok->is(tok::l_brace)) {1605        if (Style.BraceWrapping.AfterExternBlock)1606          addUnwrappedLine();1607        // Either we indent or for backwards compatibility we follow the1608        // AfterExternBlock style.1609        unsigned AddLevels =1610            (Style.IndentExternBlock == FormatStyle::IEBS_Indent) ||1611                    (Style.BraceWrapping.AfterExternBlock &&1612                     Style.IndentExternBlock ==1613                         FormatStyle::IEBS_AfterExternBlock)1614                ? 1u1615                : 0u;1616        parseBlock(/*MustBeDeclaration=*/true, AddLevels);1617        addUnwrappedLine();1618        return;1619      }1620    }1621    break;1622  case tok::kw_export:1623    if (Style.isJavaScript()) {1624      parseJavaScriptEs6ImportExport();1625      return;1626    }1627    if (Style.isVerilog()) {1628      parseVerilogExtern();1629      return;1630    }1631    if (IsCpp) {1632      nextToken();1633      if (FormatTok->is(tok::kw_namespace)) {1634        parseNamespace();1635        return;1636      }1637      if (FormatTok->is(tok::l_brace)) {1638        parseCppExportBlock();1639        return;1640      }1641      if (FormatTok->is(Keywords.kw_import) && parseModuleImport())1642        return;1643    }1644    break;1645  case tok::kw_inline:1646    nextToken();1647    if (FormatTok->is(tok::kw_namespace)) {1648      parseNamespace();1649      return;1650    }1651    break;1652  case tok::identifier:1653    if (FormatTok->is(TT_ForEachMacro)) {1654      parseForOrWhileLoop();1655      return;1656    }1657    if (FormatTok->is(TT_MacroBlockBegin)) {1658      parseBlock(/*MustBeDeclaration=*/false, /*AddLevels=*/1u,1659                 /*MunchSemi=*/false);1660      return;1661    }1662    if (FormatTok->is(Keywords.kw_import)) {1663      if (Style.isJavaScript()) {1664        parseJavaScriptEs6ImportExport();1665        return;1666      }1667      if (Style.Language == FormatStyle::LK_Proto) {1668        nextToken();1669        if (FormatTok->is(tok::kw_public))1670          nextToken();1671        if (FormatTok->isNot(tok::string_literal))1672          return;1673        nextToken();1674        if (FormatTok->is(tok::semi))1675          nextToken();1676        addUnwrappedLine();1677        return;1678      }1679      if (Style.isVerilog()) {1680        parseVerilogExtern();1681        return;1682      }1683      if (IsCpp && parseModuleImport())1684        return;1685    }1686    if (IsCpp && FormatTok->isOneOf(Keywords.kw_signals, Keywords.kw_qsignals,1687                                    Keywords.kw_slots, Keywords.kw_qslots)) {1688      nextToken();1689      if (FormatTok->is(tok::colon)) {1690        nextToken();1691        addUnwrappedLine();1692        return;1693      }1694    }1695    if (IsCpp && FormatTok->is(TT_StatementMacro)) {1696      parseStatementMacro();1697      return;1698    }1699    if (IsCpp && FormatTok->is(TT_NamespaceMacro)) {1700      parseNamespace();1701      return;1702    }1703    // In Verilog labels can be any expression, so we don't do them here.1704    // JS doesn't have macros, and within classes colons indicate fields, not1705    // labels.1706    // TableGen doesn't have labels.1707    if (!Style.isJavaScript() && !Style.isVerilog() && !Style.isTableGen() &&1708        Tokens->peekNextToken()->is(tok::colon) && !Line->MustBeDeclaration) {1709      nextToken();1710      if (!Line->InMacroBody || CurrentLines->size() > 1)1711        Line->Tokens.begin()->Tok->MustBreakBefore = true;1712      FormatTok->setFinalizedType(TT_GotoLabelColon);1713      parseLabel(!Style.IndentGotoLabels);1714      if (HasLabel)1715        *HasLabel = true;1716      return;1717    }1718    if (Style.isJava() && FormatTok->is(Keywords.kw_record)) {1719      parseRecord(/*ParseAsExpr=*/false, /*IsJavaRecord=*/true);1720      addUnwrappedLine();1721      return;1722    }1723    // In all other cases, parse the declaration.1724    break;1725  default:1726    break;1727  }1728 1729  bool SeenEqual = false;1730  for (const bool InRequiresExpression =1731           OpeningBrace && OpeningBrace->isOneOf(TT_RequiresExpressionLBrace,1732                                                 TT_CompoundRequirementLBrace);1733       !eof();) {1734    const FormatToken *Previous = FormatTok->Previous;1735    switch (FormatTok->Tok.getKind()) {1736    case tok::at:1737      nextToken();1738      if (FormatTok->is(tok::l_brace)) {1739        nextToken();1740        parseBracedList();1741        break;1742      }1743      if (Style.isJava() && FormatTok->is(Keywords.kw_interface)) {1744        nextToken();1745        break;1746      }1747      switch (bool IsAutoRelease = false; FormatTok->Tok.getObjCKeywordID()) {1748      case tok::objc_public:1749      case tok::objc_protected:1750      case tok::objc_package:1751      case tok::objc_private:1752        return parseAccessSpecifier();1753      case tok::objc_interface:1754      case tok::objc_implementation:1755        return parseObjCInterfaceOrImplementation();1756      case tok::objc_protocol:1757        if (parseObjCProtocol())1758          return;1759        break;1760      case tok::objc_end:1761        return; // Handled by the caller.1762      case tok::objc_optional:1763      case tok::objc_required:1764        nextToken();1765        addUnwrappedLine();1766        return;1767      case tok::objc_autoreleasepool:1768        IsAutoRelease = true;1769        [[fallthrough]];1770      case tok::objc_synchronized:1771        nextToken();1772        if (!IsAutoRelease && FormatTok->is(tok::l_paren)) {1773          // Skip synchronization object1774          parseParens();1775        }1776        if (FormatTok->is(tok::l_brace)) {1777          if (Style.BraceWrapping.AfterControlStatement ==1778              FormatStyle::BWACS_Always) {1779            addUnwrappedLine();1780          }1781          parseBlock();1782        }1783        addUnwrappedLine();1784        return;1785      case tok::objc_try:1786        // This branch isn't strictly necessary (the kw_try case below would1787        // do this too after the tok::at is parsed above).  But be explicit.1788        parseTryCatch();1789        return;1790      default:1791        break;1792      }1793      break;1794    case tok::kw_requires: {1795      if (IsCpp) {1796        bool ParsedClause = parseRequires(SeenEqual);1797        if (ParsedClause)1798          return;1799      } else {1800        nextToken();1801      }1802      break;1803    }1804    case tok::kw_enum:1805      // Ignore if this is part of "template <enum ..." or "... -> enum" or1806      // "template <..., enum ...>".1807      if (Previous && Previous->isOneOf(tok::less, tok::arrow, tok::comma)) {1808        nextToken();1809        break;1810      }1811 1812      // parseEnum falls through and does not yet add an unwrapped line as an1813      // enum definition can start a structural element.1814      if (!parseEnum())1815        break;1816      // This only applies to C++ and Verilog.1817      if (!IsCpp && !Style.isVerilog()) {1818        addUnwrappedLine();1819        return;1820      }1821      break;1822    case tok::kw_typedef:1823      nextToken();1824      if (FormatTok->isOneOf(Keywords.kw_NS_ENUM, Keywords.kw_NS_OPTIONS,1825                             Keywords.kw_CF_ENUM, Keywords.kw_CF_OPTIONS,1826                             Keywords.kw_CF_CLOSED_ENUM,1827                             Keywords.kw_NS_CLOSED_ENUM)) {1828        parseEnum();1829      }1830      break;1831    case tok::kw_class:1832      if (Style.isVerilog()) {1833        parseBlock();1834        addUnwrappedLine();1835        return;1836      }1837      if (Style.isTableGen()) {1838        // Do nothing special. In this case the l_brace becomes FunctionLBrace.1839        // This is same as def and so on.1840        nextToken();1841        break;1842      }1843      [[fallthrough]];1844    case tok::kw_struct:1845    case tok::kw_union:1846      if (parseStructLike())1847        return;1848      break;1849    case tok::kw_decltype:1850      nextToken();1851      if (FormatTok->is(tok::l_paren)) {1852        parseParens();1853        if (FormatTok->Previous &&1854            FormatTok->Previous->endsSequence(tok::r_paren, tok::kw_auto,1855                                              tok::l_paren)) {1856          Line->SeenDecltypeAuto = true;1857        }1858      }1859      break;1860    case tok::period:1861      nextToken();1862      // In Java, classes have an implicit static member "class".1863      if (Style.isJava() && FormatTok && FormatTok->is(tok::kw_class))1864        nextToken();1865      if (Style.isJavaScript() && FormatTok &&1866          FormatTok->Tok.getIdentifierInfo()) {1867        // JavaScript only has pseudo keywords, all keywords are allowed to1868        // appear in "IdentifierName" positions. See http://es5.github.io/#x7.61869        nextToken();1870      }1871      break;1872    case tok::semi:1873      nextToken();1874      addUnwrappedLine();1875      return;1876    case tok::r_brace:1877      addUnwrappedLine();1878      return;1879    case tok::l_paren: {1880      parseParens();1881      // Break the unwrapped line if a K&R C function definition has a parameter1882      // declaration.1883      if (OpeningBrace || !IsCpp || !Previous || eof())1884        break;1885      if (isC78ParameterDecl(FormatTok,1886                             Tokens->peekNextToken(/*SkipComment=*/true),1887                             Previous)) {1888        addUnwrappedLine();1889        return;1890      }1891      break;1892    }1893    case tok::kw_operator:1894      nextToken();1895      if (FormatTok->isBinaryOperator())1896        nextToken();1897      break;1898    case tok::caret: {1899      const auto *Prev = FormatTok->getPreviousNonComment();1900      nextToken();1901      if (Prev && Prev->is(tok::identifier))1902        break;1903      // Block return type.1904      if (FormatTok->Tok.isAnyIdentifier() || FormatTok->isTypeName(LangOpts)) {1905        nextToken();1906        // Return types: pointers are ok too.1907        while (FormatTok->is(tok::star))1908          nextToken();1909      }1910      // Block argument list.1911      if (FormatTok->is(tok::l_paren))1912        parseParens();1913      // Block body.1914      if (FormatTok->is(tok::l_brace))1915        parseChildBlock();1916      break;1917    }1918    case tok::l_brace:1919      if (InRequiresExpression)1920        FormatTok->setFinalizedType(TT_BracedListLBrace);1921      if (!tryToParsePropertyAccessor() && !tryToParseBracedList()) {1922        IsDecltypeAutoFunction = Line->SeenDecltypeAuto;1923        // A block outside of parentheses must be the last part of a1924        // structural element.1925        // FIXME: Figure out cases where this is not true, and add projections1926        // for them (the one we know is missing are lambdas).1927        if (Style.isJava() &&1928            Line->Tokens.front().Tok->is(Keywords.kw_synchronized)) {1929          // If necessary, we could set the type to something different than1930          // TT_FunctionLBrace.1931          if (Style.BraceWrapping.AfterControlStatement ==1932              FormatStyle::BWACS_Always) {1933            addUnwrappedLine();1934          }1935        } else if (Style.BraceWrapping.AfterFunction) {1936          addUnwrappedLine();1937        }1938        if (!Previous || Previous->isNot(TT_TypeDeclarationParen))1939          FormatTok->setFinalizedType(TT_FunctionLBrace);1940        parseBlock();1941        IsDecltypeAutoFunction = false;1942        addUnwrappedLine();1943        return;1944      }1945      // Otherwise this was a braced init list, and the structural1946      // element continues.1947      break;1948    case tok::kw_try:1949      if (Style.isJavaScript() && Line->MustBeDeclaration) {1950        // field/method declaration.1951        nextToken();1952        break;1953      }1954      // We arrive here when parsing function-try blocks.1955      if (Style.BraceWrapping.AfterFunction)1956        addUnwrappedLine();1957      parseTryCatch();1958      return;1959    case tok::identifier: {1960      if (Style.isCSharp() && FormatTok->is(Keywords.kw_where) &&1961          Line->MustBeDeclaration) {1962        addUnwrappedLine();1963        parseCSharpGenericTypeConstraint();1964        break;1965      }1966      if (FormatTok->is(TT_MacroBlockEnd)) {1967        addUnwrappedLine();1968        return;1969      }1970 1971      // Function declarations (as opposed to function expressions) are parsed1972      // on their own unwrapped line by continuing this loop. Function1973      // expressions (functions that are not on their own line) must not create1974      // a new unwrapped line, so they are special cased below.1975      size_t TokenCount = Line->Tokens.size();1976      if (Style.isJavaScript() && FormatTok->is(Keywords.kw_function) &&1977          (TokenCount > 1 ||1978           (TokenCount == 1 &&1979            Line->Tokens.front().Tok->isNot(Keywords.kw_async)))) {1980        tryToParseJSFunction();1981        break;1982      }1983      if ((Style.isJavaScript() || Style.isJava()) &&1984          FormatTok->is(Keywords.kw_interface)) {1985        if (Style.isJavaScript()) {1986          // In JavaScript/TypeScript, "interface" can be used as a standalone1987          // identifier, e.g. in `var interface = 1;`. If "interface" is1988          // followed by another identifier, it is very like to be an actual1989          // interface declaration.1990          unsigned StoredPosition = Tokens->getPosition();1991          FormatToken *Next = Tokens->getNextToken();1992          FormatTok = Tokens->setPosition(StoredPosition);1993          if (!mustBeJSIdent(Keywords, Next)) {1994            nextToken();1995            break;1996          }1997        }1998        parseRecord();1999        addUnwrappedLine();2000        return;2001      }2002 2003      if (Style.isVerilog()) {2004        if (FormatTok->is(Keywords.kw_table)) {2005          parseVerilogTable();2006          return;2007        }2008        if (Keywords.isVerilogBegin(*FormatTok) ||2009            Keywords.isVerilogHierarchy(*FormatTok)) {2010          parseBlock();2011          addUnwrappedLine();2012          return;2013        }2014      }2015 2016      if (!IsCpp && FormatTok->is(Keywords.kw_interface)) {2017        if (parseStructLike())2018          return;2019        break;2020      }2021 2022      if (IsCpp && FormatTok->is(TT_StatementMacro)) {2023        parseStatementMacro();2024        return;2025      }2026 2027      // See if the following token should start a new unwrapped line.2028      StringRef Text = FormatTok->TokenText;2029 2030      FormatToken *PreviousToken = FormatTok;2031      nextToken();2032 2033      // JS doesn't have macros, and within classes colons indicate fields, not2034      // labels.2035      if (Style.isJavaScript())2036        break;2037 2038      auto OneTokenSoFar = [&]() {2039        auto I = Line->Tokens.begin(), E = Line->Tokens.end();2040        while (I != E && I->Tok->is(tok::comment))2041          ++I;2042        if (Style.isVerilog())2043          while (I != E && I->Tok->is(tok::hash))2044            ++I;2045        return I != E && (++I == E);2046      };2047      if (OneTokenSoFar()) {2048        // Recognize function-like macro usages without trailing semicolon as2049        // well as free-standing macros like Q_OBJECT.2050        bool FunctionLike = FormatTok->is(tok::l_paren);2051        if (FunctionLike)2052          parseParens();2053 2054        bool FollowedByNewline =2055            CommentsBeforeNextToken.empty()2056                ? FormatTok->NewlinesBefore > 02057                : CommentsBeforeNextToken.front()->NewlinesBefore > 0;2058 2059        if (FollowedByNewline &&2060            (Text.size() >= 5 ||2061             (FunctionLike && FormatTok->isNot(tok::l_paren))) &&2062            tokenCanStartNewLine(*FormatTok) && Text == Text.upper()) {2063          if (PreviousToken->isNot(TT_UntouchableMacroFunc))2064            PreviousToken->setFinalizedType(TT_FunctionLikeOrFreestandingMacro);2065          addUnwrappedLine();2066          return;2067        }2068      }2069      break;2070    }2071    case tok::equal:2072      if ((Style.isJavaScript() || Style.isCSharp()) &&2073          FormatTok->is(TT_FatArrow)) {2074        tryToParseChildBlock();2075        break;2076      }2077 2078      SeenEqual = true;2079      nextToken();2080      if (FormatTok->is(tok::l_brace)) {2081        // Block kind should probably be set to BK_BracedInit for any language.2082        // C# needs this change to ensure that array initialisers and object2083        // initialisers are indented the same way.2084        if (Style.isCSharp())2085          FormatTok->setBlockKind(BK_BracedInit);2086        // TableGen's defset statement has syntax of the form,2087        // `defset <type> <name> = { <statement>... }`2088        if (Style.isTableGen() &&2089            Line->Tokens.begin()->Tok->is(Keywords.kw_defset)) {2090          FormatTok->setFinalizedType(TT_FunctionLBrace);2091          parseBlock(/*MustBeDeclaration=*/false, /*AddLevels=*/1u,2092                     /*MunchSemi=*/false);2093          addUnwrappedLine();2094          break;2095        }2096        nextToken();2097        parseBracedList();2098      } else if (Style.Language == FormatStyle::LK_Proto &&2099                 FormatTok->is(tok::less)) {2100        nextToken();2101        parseBracedList(/*IsAngleBracket=*/true);2102      }2103      break;2104    case tok::l_square:2105      parseSquare();2106      break;2107    case tok::kw_new:2108      if (Style.isCSharp() &&2109          (Tokens->peekNextToken()->isAccessSpecifierKeyword() ||2110           (Previous && Previous->isAccessSpecifierKeyword()))) {2111        nextToken();2112      } else {2113        parseNew();2114      }2115      break;2116    case tok::kw_switch:2117      if (Style.isJava())2118        parseSwitch(/*IsExpr=*/true);2119      else2120        nextToken();2121      break;2122    case tok::kw_case:2123      // Proto: there are no switch/case statements.2124      if (Style.Language == FormatStyle::LK_Proto) {2125        nextToken();2126        return;2127      }2128      // In Verilog switch is called case.2129      if (Style.isVerilog()) {2130        parseBlock();2131        addUnwrappedLine();2132        return;2133      }2134      if (Style.isJavaScript() && Line->MustBeDeclaration) {2135        // 'case: string' field declaration.2136        nextToken();2137        break;2138      }2139      parseCaseLabel();2140      break;2141    case tok::kw_default:2142      nextToken();2143      if (Style.isVerilog()) {2144        if (FormatTok->is(tok::colon)) {2145          // The label will be handled in the next iteration.2146          break;2147        }2148        if (FormatTok->is(Keywords.kw_clocking)) {2149          // A default clocking block.2150          parseBlock();2151          addUnwrappedLine();2152          return;2153        }2154        parseVerilogCaseLabel();2155        return;2156      }2157      break;2158    case tok::colon:2159      nextToken();2160      if (Style.isVerilog()) {2161        parseVerilogCaseLabel();2162        return;2163      }2164      break;2165    case tok::greater:2166      nextToken();2167      if (FormatTok->is(tok::l_brace))2168        FormatTok->Previous->setFinalizedType(TT_TemplateCloser);2169      break;2170    default:2171      nextToken();2172      break;2173    }2174  }2175}2176 2177bool UnwrappedLineParser::tryToParsePropertyAccessor() {2178  assert(FormatTok->is(tok::l_brace));2179  if (!Style.isCSharp())2180    return false;2181  // See if it's a property accessor.2182  if (!FormatTok->Previous || FormatTok->Previous->isNot(tok::identifier))2183    return false;2184 2185  // See if we are inside a property accessor.2186  //2187  // Record the current tokenPosition so that we can advance and2188  // reset the current token. `Next` is not set yet so we need2189  // another way to advance along the token stream.2190  unsigned int StoredPosition = Tokens->getPosition();2191  FormatToken *Tok = Tokens->getNextToken();2192 2193  // A trivial property accessor is of the form:2194  // { [ACCESS_SPECIFIER] [get]; [ACCESS_SPECIFIER] [set|init] }2195  // Track these as they do not require line breaks to be introduced.2196  bool HasSpecialAccessor = false;2197  bool IsTrivialPropertyAccessor = true;2198  bool HasAttribute = false;2199  while (!eof()) {2200    if (const bool IsAccessorKeyword =2201            Tok->isOneOf(Keywords.kw_get, Keywords.kw_init, Keywords.kw_set);2202        IsAccessorKeyword || Tok->isAccessSpecifierKeyword() ||2203        Tok->isOneOf(tok::l_square, tok::semi, Keywords.kw_internal)) {2204      if (IsAccessorKeyword)2205        HasSpecialAccessor = true;2206      else if (Tok->is(tok::l_square))2207        HasAttribute = true;2208      Tok = Tokens->getNextToken();2209      continue;2210    }2211    if (Tok->isNot(tok::r_brace))2212      IsTrivialPropertyAccessor = false;2213    break;2214  }2215 2216  if (!HasSpecialAccessor || HasAttribute) {2217    Tokens->setPosition(StoredPosition);2218    return false;2219  }2220 2221  // Try to parse the property accessor:2222  // https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties2223  Tokens->setPosition(StoredPosition);2224  if (!IsTrivialPropertyAccessor && Style.BraceWrapping.AfterFunction)2225    addUnwrappedLine();2226  nextToken();2227  do {2228    switch (FormatTok->Tok.getKind()) {2229    case tok::r_brace:2230      nextToken();2231      if (FormatTok->is(tok::equal)) {2232        while (!eof() && FormatTok->isNot(tok::semi))2233          nextToken();2234        nextToken();2235      }2236      addUnwrappedLine();2237      return true;2238    case tok::l_brace:2239      ++Line->Level;2240      parseBlock(/*MustBeDeclaration=*/true);2241      addUnwrappedLine();2242      --Line->Level;2243      break;2244    case tok::equal:2245      if (FormatTok->is(TT_FatArrow)) {2246        ++Line->Level;2247        do {2248          nextToken();2249        } while (!eof() && FormatTok->isNot(tok::semi));2250        nextToken();2251        addUnwrappedLine();2252        --Line->Level;2253        break;2254      }2255      nextToken();2256      break;2257    default:2258      if (FormatTok->isOneOf(Keywords.kw_get, Keywords.kw_init,2259                             Keywords.kw_set) &&2260          !IsTrivialPropertyAccessor) {2261        // Non-trivial get/set needs to be on its own line.2262        addUnwrappedLine();2263      }2264      nextToken();2265    }2266  } while (!eof());2267 2268  // Unreachable for well-formed code (paired '{' and '}').2269  return true;2270}2271 2272bool UnwrappedLineParser::tryToParseLambda() {2273  assert(FormatTok->is(tok::l_square));2274  if (!IsCpp) {2275    nextToken();2276    return false;2277  }2278  FormatToken &LSquare = *FormatTok;2279  if (!tryToParseLambdaIntroducer())2280    return false;2281 2282  FormatToken *Arrow = nullptr;2283  bool InTemplateParameterList = false;2284 2285  while (FormatTok->isNot(tok::l_brace)) {2286    if (FormatTok->isTypeName(LangOpts) || FormatTok->isAttribute()) {2287      nextToken();2288      continue;2289    }2290    switch (FormatTok->Tok.getKind()) {2291    case tok::l_brace:2292      break;2293    case tok::l_paren:2294      parseParens(/*AmpAmpTokenType=*/TT_PointerOrReference);2295      break;2296    case tok::l_square:2297      parseSquare();2298      break;2299    case tok::less:2300      assert(FormatTok->Previous);2301      if (FormatTok->Previous->is(tok::r_square))2302        InTemplateParameterList = true;2303      nextToken();2304      break;2305    case tok::kw_auto:2306    case tok::kw_class:2307    case tok::kw_struct:2308    case tok::kw_union:2309    case tok::kw_template:2310    case tok::kw_typename:2311    case tok::amp:2312    case tok::star:2313    case tok::kw_const:2314    case tok::kw_constexpr:2315    case tok::kw_consteval:2316    case tok::comma:2317    case tok::greater:2318    case tok::identifier:2319    case tok::numeric_constant:2320    case tok::coloncolon:2321    case tok::kw_mutable:2322    case tok::kw_noexcept:2323    case tok::kw_static:2324      nextToken();2325      break;2326    // Specialization of a template with an integer parameter can contain2327    // arithmetic, logical, comparison and ternary operators.2328    //2329    // FIXME: This also accepts sequences of operators that are not in the scope2330    // of a template argument list.2331    //2332    // In a C++ lambda a template type can only occur after an arrow. We use2333    // this as an heuristic to distinguish between Objective-C expressions2334    // followed by an `a->b` expression, such as:2335    // ([obj func:arg] + a->b)2336    // Otherwise the code below would parse as a lambda.2337    case tok::plus:2338    case tok::minus:2339    case tok::exclaim:2340    case tok::tilde:2341    case tok::slash:2342    case tok::percent:2343    case tok::lessless:2344    case tok::pipe:2345    case tok::pipepipe:2346    case tok::ampamp:2347    case tok::caret:2348    case tok::equalequal:2349    case tok::exclaimequal:2350    case tok::greaterequal:2351    case tok::lessequal:2352    case tok::question:2353    case tok::colon:2354    case tok::ellipsis:2355    case tok::kw_true:2356    case tok::kw_false:2357      if (Arrow || InTemplateParameterList) {2358        nextToken();2359        break;2360      }2361      return true;2362    case tok::arrow:2363      Arrow = FormatTok;2364      nextToken();2365      break;2366    case tok::kw_requires:2367      parseRequiresClause();2368      break;2369    case tok::equal:2370      if (!InTemplateParameterList)2371        return true;2372      nextToken();2373      break;2374    default:2375      return true;2376    }2377  }2378 2379  FormatTok->setFinalizedType(TT_LambdaLBrace);2380  LSquare.setFinalizedType(TT_LambdaLSquare);2381 2382  if (Arrow)2383    Arrow->setFinalizedType(TT_LambdaArrow);2384 2385  NestedLambdas.push_back(Line->SeenDecltypeAuto);2386  parseChildBlock();2387  assert(!NestedLambdas.empty());2388  NestedLambdas.pop_back();2389 2390  return true;2391}2392 2393bool UnwrappedLineParser::tryToParseLambdaIntroducer() {2394  const FormatToken *Previous = FormatTok->Previous;2395  const FormatToken *LeftSquare = FormatTok;2396  nextToken();2397  if (Previous) {2398    if (Previous->closesScope()) {2399      // Not a potential C-style cast.2400      if (Previous->isNot(tok::r_paren))2401        return false;2402      const auto *BeforeRParen = Previous->getPreviousNonComment();2403      // Lambdas can be cast to function types only, e.g. `std::function<int()>`2404      // and `int (*)()`.2405      if (!BeforeRParen || BeforeRParen->isNoneOf(tok::greater, tok::r_paren))2406        return false;2407    } else if (Previous->is(tok::star)) {2408      Previous = Previous->getPreviousNonComment();2409    }2410    if (Previous && Previous->Tok.getIdentifierInfo() &&2411        Previous->isNoneOf(tok::kw_return, tok::kw_co_await, tok::kw_co_yield,2412                           tok::kw_co_return)) {2413      return false;2414    }2415  }2416  if (LeftSquare->isCppStructuredBinding(IsCpp))2417    return false;2418  if (FormatTok->is(tok::l_square) || tok::isLiteral(FormatTok->Tok.getKind()))2419    return false;2420  if (FormatTok->is(tok::r_square)) {2421    const FormatToken *Next = Tokens->peekNextToken(/*SkipComment=*/true);2422    if (Next->is(tok::greater))2423      return false;2424  }2425  parseSquare(/*LambdaIntroducer=*/true);2426  return true;2427}2428 2429void UnwrappedLineParser::tryToParseJSFunction() {2430  assert(FormatTok->is(Keywords.kw_function));2431  if (FormatTok->is(Keywords.kw_async))2432    nextToken();2433  // Consume "function".2434  nextToken();2435 2436  // Consume * (generator function). Treat it like C++'s overloaded operators.2437  if (FormatTok->is(tok::star)) {2438    FormatTok->setFinalizedType(TT_OverloadedOperator);2439    nextToken();2440  }2441 2442  // Consume function name.2443  if (FormatTok->is(tok::identifier))2444    nextToken();2445 2446  if (FormatTok->isNot(tok::l_paren))2447    return;2448 2449  // Parse formal parameter list.2450  parseParens();2451 2452  if (FormatTok->is(tok::colon)) {2453    // Parse a type definition.2454    nextToken();2455 2456    // Eat the type declaration. For braced inline object types, balance braces,2457    // otherwise just parse until finding an l_brace for the function body.2458    if (FormatTok->is(tok::l_brace))2459      tryToParseBracedList();2460    else2461      while (FormatTok->isNoneOf(tok::l_brace, tok::semi) && !eof())2462        nextToken();2463  }2464 2465  if (FormatTok->is(tok::semi))2466    return;2467 2468  parseChildBlock();2469}2470 2471bool UnwrappedLineParser::tryToParseBracedList() {2472  if (FormatTok->is(BK_Unknown))2473    calculateBraceTypes();2474  assert(FormatTok->isNot(BK_Unknown));2475  if (FormatTok->is(BK_Block))2476    return false;2477  nextToken();2478  parseBracedList();2479  return true;2480}2481 2482bool UnwrappedLineParser::tryToParseChildBlock() {2483  assert(Style.isJavaScript() || Style.isCSharp());2484  assert(FormatTok->is(TT_FatArrow));2485  // Fat arrows (=>) have tok::TokenKind tok::equal but TokenType TT_FatArrow.2486  // They always start an expression or a child block if followed by a curly2487  // brace.2488  nextToken();2489  if (FormatTok->isNot(tok::l_brace))2490    return false;2491  parseChildBlock();2492  return true;2493}2494 2495bool UnwrappedLineParser::parseBracedList(bool IsAngleBracket, bool IsEnum) {2496  assert(!IsAngleBracket || !IsEnum);2497  bool HasError = false;2498 2499  // FIXME: Once we have an expression parser in the UnwrappedLineParser,2500  // replace this by using parseAssignmentExpression() inside.2501  do {2502    if (Style.isCSharp() && FormatTok->is(TT_FatArrow) &&2503        tryToParseChildBlock()) {2504      continue;2505    }2506    if (Style.isJavaScript()) {2507      if (FormatTok->is(Keywords.kw_function)) {2508        tryToParseJSFunction();2509        continue;2510      }2511      if (FormatTok->is(tok::l_brace)) {2512        // Could be a method inside of a braced list `{a() { return 1; }}`.2513        if (tryToParseBracedList())2514          continue;2515        parseChildBlock();2516      }2517    }2518    if (FormatTok->is(IsAngleBracket ? tok::greater : tok::r_brace)) {2519      if (IsEnum) {2520        FormatTok->setBlockKind(BK_Block);2521        if (!Style.AllowShortEnumsOnASingleLine)2522          addUnwrappedLine();2523      }2524      nextToken();2525      return !HasError;2526    }2527    switch (FormatTok->Tok.getKind()) {2528    case tok::l_square:2529      if (Style.isCSharp())2530        parseSquare();2531      else2532        tryToParseLambda();2533      break;2534    case tok::l_paren:2535      parseParens();2536      // JavaScript can just have free standing methods and getters/setters in2537      // object literals. Detect them by a "{" following ")".2538      if (Style.isJavaScript()) {2539        if (FormatTok->is(tok::l_brace))2540          parseChildBlock();2541        break;2542      }2543      break;2544    case tok::l_brace:2545      // Assume there are no blocks inside a braced init list apart2546      // from the ones we explicitly parse out (like lambdas).2547      FormatTok->setBlockKind(BK_BracedInit);2548      if (!IsAngleBracket) {2549        auto *Prev = FormatTok->Previous;2550        if (Prev && Prev->is(tok::greater))2551          Prev->setFinalizedType(TT_TemplateCloser);2552      }2553      nextToken();2554      parseBracedList();2555      break;2556    case tok::less:2557      nextToken();2558      if (IsAngleBracket)2559        parseBracedList(/*IsAngleBracket=*/true);2560      break;2561    case tok::semi:2562      // JavaScript (or more precisely TypeScript) can have semicolons in braced2563      // lists (in so-called TypeMemberLists). Thus, the semicolon cannot be2564      // used for error recovery if we have otherwise determined that this is2565      // a braced list.2566      if (Style.isJavaScript()) {2567        nextToken();2568        break;2569      }2570      HasError = true;2571      if (!IsEnum)2572        return false;2573      nextToken();2574      break;2575    case tok::comma:2576      nextToken();2577      if (IsEnum && !Style.AllowShortEnumsOnASingleLine)2578        addUnwrappedLine();2579      break;2580    case tok::kw_requires:2581      parseRequiresExpression();2582      break;2583    default:2584      nextToken();2585      break;2586    }2587  } while (!eof());2588  return false;2589}2590 2591/// Parses a pair of parentheses (and everything between them).2592/// \param AmpAmpTokenType If different than TT_Unknown sets this type for all2593/// double ampersands. This applies for all nested scopes as well.2594///2595/// Returns whether there is a `=` token between the parentheses.2596bool UnwrappedLineParser::parseParens(TokenType AmpAmpTokenType,2597                                      bool InMacroCall) {2598  assert(FormatTok->is(tok::l_paren) && "'(' expected.");2599  auto *LParen = FormatTok;2600  auto *Prev = FormatTok->Previous;2601  bool SeenComma = false;2602  bool SeenEqual = false;2603  bool MightBeFoldExpr = false;2604  nextToken();2605  const bool MightBeStmtExpr = FormatTok->is(tok::l_brace);2606  if (!InMacroCall && Prev && Prev->is(TT_FunctionLikeMacro))2607    InMacroCall = true;2608  do {2609    switch (FormatTok->Tok.getKind()) {2610    case tok::l_paren:2611      if (parseParens(AmpAmpTokenType, InMacroCall))2612        SeenEqual = true;2613      if (Style.isJava() && FormatTok->is(tok::l_brace))2614        parseChildBlock();2615      break;2616    case tok::r_paren: {2617      auto *RParen = FormatTok;2618      nextToken();2619      if (Prev) {2620        auto OptionalParens = [&] {2621          if (MightBeStmtExpr || MightBeFoldExpr || SeenComma || InMacroCall ||2622              Line->InMacroBody ||2623              Style.RemoveParentheses == FormatStyle::RPS_Leave ||2624              RParen->getPreviousNonComment() == LParen) {2625            return false;2626          }2627          const bool DoubleParens =2628              Prev->is(tok::l_paren) && FormatTok->is(tok::r_paren);2629          if (DoubleParens) {2630            const auto *PrevPrev = Prev->getPreviousNonComment();2631            const bool Excluded =2632                PrevPrev &&2633                (PrevPrev->isOneOf(tok::kw___attribute, tok::kw_decltype) ||2634                 (SeenEqual &&2635                  (PrevPrev->isOneOf(tok::kw_if, tok::kw_while) ||2636                   PrevPrev->endsSequence(tok::kw_constexpr, tok::kw_if))));2637            if (!Excluded)2638              return true;2639          } else {2640            const bool CommaSeparated =2641                Prev->isOneOf(tok::l_paren, tok::comma) &&2642                FormatTok->isOneOf(tok::comma, tok::r_paren);2643            if (CommaSeparated &&2644                // LParen is not preceded by ellipsis, comma.2645                !Prev->endsSequence(tok::comma, tok::ellipsis) &&2646                // RParen is not followed by comma, ellipsis.2647                !(FormatTok->is(tok::comma) &&2648                  Tokens->peekNextToken()->is(tok::ellipsis))) {2649              return true;2650            }2651            const bool ReturnParens =2652                Style.RemoveParentheses == FormatStyle::RPS_ReturnStatement &&2653                ((NestedLambdas.empty() && !IsDecltypeAutoFunction) ||2654                 (!NestedLambdas.empty() && !NestedLambdas.back())) &&2655                Prev->isOneOf(tok::kw_return, tok::kw_co_return) &&2656                FormatTok->is(tok::semi);2657            if (ReturnParens)2658              return true;2659          }2660          return false;2661        };2662        if (Prev->is(TT_TypenameMacro)) {2663          LParen->setFinalizedType(TT_TypeDeclarationParen);2664          RParen->setFinalizedType(TT_TypeDeclarationParen);2665        } else if (Prev->is(tok::greater) && RParen->Previous == LParen) {2666          Prev->setFinalizedType(TT_TemplateCloser);2667        } else if (OptionalParens()) {2668          LParen->Optional = true;2669          RParen->Optional = true;2670        }2671      }2672      return SeenEqual;2673    }2674    case tok::r_brace:2675      // A "}" inside parenthesis is an error if there wasn't a matching "{".2676      return SeenEqual;2677    case tok::l_square:2678      tryToParseLambda();2679      break;2680    case tok::l_brace:2681      if (!tryToParseBracedList())2682        parseChildBlock();2683      break;2684    case tok::at:2685      nextToken();2686      if (FormatTok->is(tok::l_brace)) {2687        nextToken();2688        parseBracedList();2689      }2690      break;2691    case tok::comma:2692      SeenComma = true;2693      nextToken();2694      break;2695    case tok::ellipsis:2696      MightBeFoldExpr = true;2697      nextToken();2698      break;2699    case tok::equal:2700      SeenEqual = true;2701      if (Style.isCSharp() && FormatTok->is(TT_FatArrow))2702        tryToParseChildBlock();2703      else2704        nextToken();2705      break;2706    case tok::kw_class:2707      if (Style.isJavaScript())2708        parseRecord(/*ParseAsExpr=*/true);2709      else2710        nextToken();2711      break;2712    case tok::identifier:2713      if (Style.isJavaScript() && (FormatTok->is(Keywords.kw_function)))2714        tryToParseJSFunction();2715      else2716        nextToken();2717      break;2718    case tok::kw_switch:2719      if (Style.isJava())2720        parseSwitch(/*IsExpr=*/true);2721      else2722        nextToken();2723      break;2724    case tok::kw_requires:2725      parseRequiresExpression();2726      break;2727    case tok::ampamp:2728      if (AmpAmpTokenType != TT_Unknown)2729        FormatTok->setFinalizedType(AmpAmpTokenType);2730      [[fallthrough]];2731    default:2732      nextToken();2733      break;2734    }2735  } while (!eof());2736  return SeenEqual;2737}2738 2739void UnwrappedLineParser::parseSquare(bool LambdaIntroducer) {2740  if (!LambdaIntroducer) {2741    assert(FormatTok->is(tok::l_square) && "'[' expected.");2742    if (tryToParseLambda())2743      return;2744  }2745  do {2746    switch (FormatTok->Tok.getKind()) {2747    case tok::l_paren:2748      parseParens();2749      break;2750    case tok::r_square:2751      nextToken();2752      return;2753    case tok::r_brace:2754      // A "}" inside parenthesis is an error if there wasn't a matching "{".2755      return;2756    case tok::l_square:2757      parseSquare();2758      break;2759    case tok::l_brace: {2760      if (!tryToParseBracedList())2761        parseChildBlock();2762      break;2763    }2764    case tok::at:2765    case tok::colon:2766      nextToken();2767      if (FormatTok->is(tok::l_brace)) {2768        nextToken();2769        parseBracedList();2770      }2771      break;2772    default:2773      nextToken();2774      break;2775    }2776  } while (!eof());2777}2778 2779void UnwrappedLineParser::keepAncestorBraces() {2780  if (!Style.RemoveBracesLLVM)2781    return;2782 2783  const int MaxNestingLevels = 2;2784  const int Size = NestedTooDeep.size();2785  if (Size >= MaxNestingLevels)2786    NestedTooDeep[Size - MaxNestingLevels] = true;2787  NestedTooDeep.push_back(false);2788}2789 2790static FormatToken *getLastNonComment(const UnwrappedLine &Line) {2791  for (const auto &Token : llvm::reverse(Line.Tokens))2792    if (Token.Tok->isNot(tok::comment))2793      return Token.Tok;2794 2795  return nullptr;2796}2797 2798void UnwrappedLineParser::parseUnbracedBody(bool CheckEOF) {2799  FormatToken *Tok = nullptr;2800 2801  if (Style.InsertBraces && !Line->InPPDirective && !Line->Tokens.empty() &&2802      PreprocessorDirectives.empty() && FormatTok->isNot(tok::semi)) {2803    Tok = Style.BraceWrapping.AfterControlStatement == FormatStyle::BWACS_Never2804              ? getLastNonComment(*Line)2805              : Line->Tokens.back().Tok;2806    assert(Tok);2807    if (Tok->BraceCount < 0) {2808      assert(Tok->BraceCount == -1);2809      Tok = nullptr;2810    } else {2811      Tok->BraceCount = -1;2812    }2813  }2814 2815  addUnwrappedLine();2816  ++Line->Level;2817  ++Line->UnbracedBodyLevel;2818  parseStructuralElement();2819  --Line->UnbracedBodyLevel;2820 2821  if (Tok) {2822    assert(!Line->InPPDirective);2823    Tok = nullptr;2824    for (const auto &L : llvm::reverse(*CurrentLines)) {2825      if (!L.InPPDirective && getLastNonComment(L)) {2826        Tok = L.Tokens.back().Tok;2827        break;2828      }2829    }2830    assert(Tok);2831    ++Tok->BraceCount;2832  }2833 2834  if (CheckEOF && eof())2835    addUnwrappedLine();2836 2837  --Line->Level;2838}2839 2840static void markOptionalBraces(FormatToken *LeftBrace) {2841  if (!LeftBrace)2842    return;2843 2844  assert(LeftBrace->is(tok::l_brace));2845 2846  FormatToken *RightBrace = LeftBrace->MatchingParen;2847  if (!RightBrace) {2848    assert(!LeftBrace->Optional);2849    return;2850  }2851 2852  assert(RightBrace->is(tok::r_brace));2853  assert(RightBrace->MatchingParen == LeftBrace);2854  assert(LeftBrace->Optional == RightBrace->Optional);2855 2856  LeftBrace->Optional = true;2857  RightBrace->Optional = true;2858}2859 2860void UnwrappedLineParser::handleAttributes() {2861  // Handle AttributeMacro, e.g. `if (x) UNLIKELY`.2862  if (FormatTok->isAttribute())2863    nextToken();2864  else if (FormatTok->is(tok::l_square))2865    handleCppAttributes();2866}2867 2868bool UnwrappedLineParser::handleCppAttributes() {2869  // Handle [[likely]] / [[unlikely]] attributes.2870  assert(FormatTok->is(tok::l_square));2871  if (!tryToParseSimpleAttribute())2872    return false;2873  parseSquare();2874  return true;2875}2876 2877/// Returns whether \c Tok begins a block.2878bool UnwrappedLineParser::isBlockBegin(const FormatToken &Tok) const {2879  // FIXME: rename the function or make2880  // Tok.isOneOf(tok::l_brace, TT_MacroBlockBegin) work.2881  return Style.isVerilog() ? Keywords.isVerilogBegin(Tok)2882                           : Tok.is(tok::l_brace);2883}2884 2885FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind,2886                                                  bool KeepBraces,2887                                                  bool IsVerilogAssert) {2888  assert((FormatTok->is(tok::kw_if) ||2889          (Style.isVerilog() &&2890           FormatTok->isOneOf(tok::kw_restrict, Keywords.kw_assert,2891                              Keywords.kw_assume, Keywords.kw_cover))) &&2892         "'if' expected");2893  nextToken();2894 2895  if (IsVerilogAssert) {2896    // Handle `assert #0` and `assert final`.2897    if (FormatTok->is(Keywords.kw_verilogHash)) {2898      nextToken();2899      if (FormatTok->is(tok::numeric_constant))2900        nextToken();2901    } else if (FormatTok->isOneOf(Keywords.kw_final, Keywords.kw_property,2902                                  Keywords.kw_sequence)) {2903      nextToken();2904    }2905  }2906 2907  // TableGen's if statement has the form of `if <cond> then { ... }`.2908  if (Style.isTableGen()) {2909    while (!eof() && FormatTok->isNot(Keywords.kw_then)) {2910      // Simply skip until then. This range only contains a value.2911      nextToken();2912    }2913  }2914 2915  // Handle `if !consteval`.2916  if (FormatTok->is(tok::exclaim))2917    nextToken();2918 2919  bool KeepIfBraces = true;2920  if (FormatTok->is(tok::kw_consteval)) {2921    nextToken();2922  } else {2923    KeepIfBraces = !Style.RemoveBracesLLVM || KeepBraces;2924    if (FormatTok->isOneOf(tok::kw_constexpr, tok::identifier))2925      nextToken();2926    if (FormatTok->is(tok::l_paren)) {2927      FormatTok->setFinalizedType(TT_ConditionLParen);2928      parseParens();2929    }2930  }2931  handleAttributes();2932  // The then action is optional in Verilog assert statements.2933  if (IsVerilogAssert && FormatTok->is(tok::semi)) {2934    nextToken();2935    addUnwrappedLine();2936    return nullptr;2937  }2938 2939  bool NeedsUnwrappedLine = false;2940  keepAncestorBraces();2941 2942  FormatToken *IfLeftBrace = nullptr;2943  IfStmtKind IfBlockKind = IfStmtKind::NotIf;2944 2945  if (isBlockBegin(*FormatTok)) {2946    FormatTok->setFinalizedType(TT_ControlStatementLBrace);2947    IfLeftBrace = FormatTok;2948    CompoundStatementIndenter Indenter(this, Style, Line->Level);2949    parseBlock(/*MustBeDeclaration=*/false, /*AddLevels=*/1u,2950               /*MunchSemi=*/true, KeepIfBraces, &IfBlockKind);2951    setPreviousRBraceType(TT_ControlStatementRBrace);2952    if (Style.BraceWrapping.BeforeElse)2953      addUnwrappedLine();2954    else2955      NeedsUnwrappedLine = true;2956  } else if (IsVerilogAssert && FormatTok->is(tok::kw_else)) {2957    addUnwrappedLine();2958  } else {2959    parseUnbracedBody();2960  }2961 2962  if (Style.RemoveBracesLLVM) {2963    assert(!NestedTooDeep.empty());2964    KeepIfBraces = KeepIfBraces ||2965                   (IfLeftBrace && !IfLeftBrace->MatchingParen) ||2966                   NestedTooDeep.back() || IfBlockKind == IfStmtKind::IfOnly ||2967                   IfBlockKind == IfStmtKind::IfElseIf;2968  }2969 2970  bool KeepElseBraces = KeepIfBraces;2971  FormatToken *ElseLeftBrace = nullptr;2972  IfStmtKind Kind = IfStmtKind::IfOnly;2973 2974  if (FormatTok->is(tok::kw_else)) {2975    if (Style.RemoveBracesLLVM) {2976      NestedTooDeep.back() = false;2977      Kind = IfStmtKind::IfElse;2978    }2979    nextToken();2980    handleAttributes();2981    if (isBlockBegin(*FormatTok)) {2982      const bool FollowedByIf = Tokens->peekNextToken()->is(tok::kw_if);2983      FormatTok->setFinalizedType(TT_ElseLBrace);2984      ElseLeftBrace = FormatTok;2985      CompoundStatementIndenter Indenter(this, Style, Line->Level);2986      IfStmtKind ElseBlockKind = IfStmtKind::NotIf;2987      FormatToken *IfLBrace =2988          parseBlock(/*MustBeDeclaration=*/false, /*AddLevels=*/1u,2989                     /*MunchSemi=*/true, KeepElseBraces, &ElseBlockKind);2990      setPreviousRBraceType(TT_ElseRBrace);2991      if (FormatTok->is(tok::kw_else)) {2992        KeepElseBraces = KeepElseBraces ||2993                         ElseBlockKind == IfStmtKind::IfOnly ||2994                         ElseBlockKind == IfStmtKind::IfElseIf;2995      } else if (FollowedByIf && IfLBrace && !IfLBrace->Optional) {2996        KeepElseBraces = true;2997        assert(ElseLeftBrace->MatchingParen);2998        markOptionalBraces(ElseLeftBrace);2999      }3000      addUnwrappedLine();3001    } else if (!IsVerilogAssert && FormatTok->is(tok::kw_if)) {3002      const FormatToken *Previous = Tokens->getPreviousToken();3003      assert(Previous);3004      const bool IsPrecededByComment = Previous->is(tok::comment);3005      if (IsPrecededByComment) {3006        addUnwrappedLine();3007        ++Line->Level;3008      }3009      bool TooDeep = true;3010      if (Style.RemoveBracesLLVM) {3011        Kind = IfStmtKind::IfElseIf;3012        TooDeep = NestedTooDeep.pop_back_val();3013      }3014      ElseLeftBrace = parseIfThenElse(/*IfKind=*/nullptr, KeepIfBraces);3015      if (Style.RemoveBracesLLVM)3016        NestedTooDeep.push_back(TooDeep);3017      if (IsPrecededByComment)3018        --Line->Level;3019    } else {3020      parseUnbracedBody(/*CheckEOF=*/true);3021    }3022  } else {3023    KeepIfBraces = KeepIfBraces || IfBlockKind == IfStmtKind::IfElse;3024    if (NeedsUnwrappedLine)3025      addUnwrappedLine();3026  }3027 3028  if (!Style.RemoveBracesLLVM)3029    return nullptr;3030 3031  assert(!NestedTooDeep.empty());3032  KeepElseBraces = KeepElseBraces ||3033                   (ElseLeftBrace && !ElseLeftBrace->MatchingParen) ||3034                   NestedTooDeep.back();3035 3036  NestedTooDeep.pop_back();3037 3038  if (!KeepIfBraces && !KeepElseBraces) {3039    markOptionalBraces(IfLeftBrace);3040    markOptionalBraces(ElseLeftBrace);3041  } else if (IfLeftBrace) {3042    FormatToken *IfRightBrace = IfLeftBrace->MatchingParen;3043    if (IfRightBrace) {3044      assert(IfRightBrace->MatchingParen == IfLeftBrace);3045      assert(!IfLeftBrace->Optional);3046      assert(!IfRightBrace->Optional);3047      IfLeftBrace->MatchingParen = nullptr;3048      IfRightBrace->MatchingParen = nullptr;3049    }3050  }3051 3052  if (IfKind)3053    *IfKind = Kind;3054 3055  return IfLeftBrace;3056}3057 3058void UnwrappedLineParser::parseTryCatch() {3059  assert(FormatTok->isOneOf(tok::kw_try, tok::kw___try) && "'try' expected");3060  nextToken();3061  bool NeedsUnwrappedLine = false;3062  bool HasCtorInitializer = false;3063  if (FormatTok->is(tok::colon)) {3064    auto *Colon = FormatTok;3065    // We are in a function try block, what comes is an initializer list.3066    nextToken();3067    if (FormatTok->is(tok::identifier)) {3068      HasCtorInitializer = true;3069      Colon->setFinalizedType(TT_CtorInitializerColon);3070    }3071 3072    // In case identifiers were removed by clang-tidy, what might follow is3073    // multiple commas in sequence - before the first identifier.3074    while (FormatTok->is(tok::comma))3075      nextToken();3076 3077    while (FormatTok->is(tok::identifier)) {3078      nextToken();3079      if (FormatTok->is(tok::l_paren)) {3080        parseParens();3081      } else if (FormatTok->is(tok::l_brace)) {3082        nextToken();3083        parseBracedList();3084      }3085 3086      // In case identifiers were removed by clang-tidy, what might follow is3087      // multiple commas in sequence - after the first identifier.3088      while (FormatTok->is(tok::comma))3089        nextToken();3090    }3091  }3092  // Parse try with resource.3093  if (Style.isJava() && FormatTok->is(tok::l_paren))3094    parseParens();3095 3096  keepAncestorBraces();3097 3098  if (FormatTok->is(tok::l_brace)) {3099    if (HasCtorInitializer)3100      FormatTok->setFinalizedType(TT_FunctionLBrace);3101    CompoundStatementIndenter Indenter(this, Style, Line->Level);3102    parseBlock();3103    if (Style.BraceWrapping.BeforeCatch)3104      addUnwrappedLine();3105    else3106      NeedsUnwrappedLine = true;3107  } else if (FormatTok->isNot(tok::kw_catch)) {3108    // The C++ standard requires a compound-statement after a try.3109    // If there's none, we try to assume there's a structuralElement3110    // and try to continue.3111    addUnwrappedLine();3112    ++Line->Level;3113    parseStructuralElement();3114    --Line->Level;3115  }3116  for (bool SeenCatch = false;;) {3117    if (FormatTok->is(tok::at))3118      nextToken();3119    if (FormatTok->isNoneOf(tok::kw_catch, Keywords.kw___except,3120                            tok::kw___finally, tok::objc_catch,3121                            tok::objc_finally) &&3122        !((Style.isJava() || Style.isJavaScript()) &&3123          FormatTok->is(Keywords.kw_finally))) {3124      break;3125    }3126    if (FormatTok->is(tok::kw_catch))3127      SeenCatch = true;3128    nextToken();3129    while (FormatTok->isNot(tok::l_brace)) {3130      if (FormatTok->is(tok::l_paren)) {3131        parseParens();3132        continue;3133      }3134      if (FormatTok->isOneOf(tok::semi, tok::r_brace) || eof()) {3135        if (Style.RemoveBracesLLVM)3136          NestedTooDeep.pop_back();3137        return;3138      }3139      nextToken();3140    }3141    if (SeenCatch) {3142      FormatTok->setFinalizedType(TT_ControlStatementLBrace);3143      SeenCatch = false;3144    }3145    NeedsUnwrappedLine = false;3146    Line->MustBeDeclaration = false;3147    CompoundStatementIndenter Indenter(this, Style, Line->Level);3148    parseBlock();3149    if (Style.BraceWrapping.BeforeCatch)3150      addUnwrappedLine();3151    else3152      NeedsUnwrappedLine = true;3153  }3154 3155  if (Style.RemoveBracesLLVM)3156    NestedTooDeep.pop_back();3157 3158  if (NeedsUnwrappedLine)3159    addUnwrappedLine();3160}3161 3162void UnwrappedLineParser::parseNamespaceOrExportBlock(unsigned AddLevels) {3163  bool ManageWhitesmithsBraces =3164      AddLevels == 0u && Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths;3165 3166  // If we're in Whitesmiths mode, indent the brace if we're not indenting3167  // the whole block.3168  if (ManageWhitesmithsBraces)3169    ++Line->Level;3170 3171  // Munch the semicolon after the block. This is more common than one would3172  // think. Putting the semicolon into its own line is very ugly.3173  parseBlock(/*MustBeDeclaration=*/true, AddLevels, /*MunchSemi=*/true,3174             /*KeepBraces=*/true, /*IfKind=*/nullptr, ManageWhitesmithsBraces);3175 3176  addUnwrappedLine(AddLevels > 0 ? LineLevel::Remove : LineLevel::Keep);3177 3178  if (ManageWhitesmithsBraces)3179    --Line->Level;3180}3181 3182void UnwrappedLineParser::parseNamespace() {3183  assert(FormatTok->isOneOf(tok::kw_namespace, TT_NamespaceMacro) &&3184         "'namespace' expected");3185 3186  const FormatToken &InitialToken = *FormatTok;3187  nextToken();3188  if (InitialToken.is(TT_NamespaceMacro)) {3189    parseParens();3190  } else {3191    while (FormatTok->isOneOf(tok::identifier, tok::coloncolon, tok::kw_inline,3192                              tok::l_square, tok::period, tok::l_paren) ||3193           (Style.isCSharp() && FormatTok->is(tok::kw_union))) {3194      if (FormatTok->is(tok::l_square))3195        parseSquare();3196      else if (FormatTok->is(tok::l_paren))3197        parseParens();3198      else3199        nextToken();3200    }3201  }3202  if (FormatTok->is(tok::l_brace)) {3203    FormatTok->setFinalizedType(TT_NamespaceLBrace);3204 3205    if (ShouldBreakBeforeBrace(Style, InitialToken, /*IsJavaRecord=*/false))3206      addUnwrappedLine();3207 3208    unsigned AddLevels =3209        Style.NamespaceIndentation == FormatStyle::NI_All ||3210                (Style.NamespaceIndentation == FormatStyle::NI_Inner &&3211                 DeclarationScopeStack.size() > 1)3212            ? 1u3213            : 0u;3214    parseNamespaceOrExportBlock(AddLevels);3215  }3216  // FIXME: Add error handling.3217}3218 3219void UnwrappedLineParser::parseCppExportBlock() {3220  parseNamespaceOrExportBlock(/*AddLevels=*/Style.IndentExportBlock ? 1 : 0);3221}3222 3223void UnwrappedLineParser::parseNew() {3224  assert(FormatTok->is(tok::kw_new) && "'new' expected");3225  nextToken();3226 3227  if (Style.isCSharp()) {3228    do {3229      // Handle constructor invocation, e.g. `new(field: value)`.3230      if (FormatTok->is(tok::l_paren))3231        parseParens();3232 3233      // Handle array initialization syntax, e.g. `new[] {10, 20, 30}`.3234      if (FormatTok->is(tok::l_brace))3235        parseBracedList();3236 3237      if (FormatTok->isOneOf(tok::semi, tok::comma))3238        return;3239 3240      nextToken();3241    } while (!eof());3242  }3243 3244  if (!Style.isJava())3245    return;3246 3247  // In Java, we can parse everything up to the parens, which aren't optional.3248  do {3249    // There should not be a ;, { or } before the new's open paren.3250    if (FormatTok->isOneOf(tok::semi, tok::l_brace, tok::r_brace))3251      return;3252 3253    // Consume the parens.3254    if (FormatTok->is(tok::l_paren)) {3255      parseParens();3256 3257      // If there is a class body of an anonymous class, consume that as child.3258      if (FormatTok->is(tok::l_brace))3259        parseChildBlock();3260      return;3261    }3262    nextToken();3263  } while (!eof());3264}3265 3266void UnwrappedLineParser::parseLoopBody(bool KeepBraces, bool WrapRightBrace) {3267  keepAncestorBraces();3268 3269  if (isBlockBegin(*FormatTok)) {3270    FormatTok->setFinalizedType(TT_ControlStatementLBrace);3271    FormatToken *LeftBrace = FormatTok;3272    CompoundStatementIndenter Indenter(this, Style, Line->Level);3273    parseBlock(/*MustBeDeclaration=*/false, /*AddLevels=*/1u,3274               /*MunchSemi=*/true, KeepBraces);3275    setPreviousRBraceType(TT_ControlStatementRBrace);3276    if (!KeepBraces) {3277      assert(!NestedTooDeep.empty());3278      if (!NestedTooDeep.back())3279        markOptionalBraces(LeftBrace);3280    }3281    if (WrapRightBrace)3282      addUnwrappedLine();3283  } else {3284    parseUnbracedBody();3285  }3286 3287  if (!KeepBraces)3288    NestedTooDeep.pop_back();3289}3290 3291void UnwrappedLineParser::parseForOrWhileLoop(bool HasParens) {3292  assert((FormatTok->isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) ||3293          (Style.isVerilog() &&3294           FormatTok->isOneOf(Keywords.kw_always, Keywords.kw_always_comb,3295                              Keywords.kw_always_ff, Keywords.kw_always_latch,3296                              Keywords.kw_final, Keywords.kw_initial,3297                              Keywords.kw_foreach, Keywords.kw_forever,3298                              Keywords.kw_repeat))) &&3299         "'for', 'while' or foreach macro expected");3300  const bool KeepBraces = !Style.RemoveBracesLLVM ||3301                          FormatTok->isNoneOf(tok::kw_for, tok::kw_while);3302 3303  nextToken();3304  // JS' for await ( ...3305  if (Style.isJavaScript() && FormatTok->is(Keywords.kw_await))3306    nextToken();3307  if (IsCpp && FormatTok->is(tok::kw_co_await))3308    nextToken();3309  if (HasParens && FormatTok->is(tok::l_paren)) {3310    // The type is only set for Verilog basically because we were afraid to3311    // change the existing behavior for loops. See the discussion on D121756 for3312    // details.3313    if (Style.isVerilog())3314      FormatTok->setFinalizedType(TT_ConditionLParen);3315    parseParens();3316  }3317 3318  if (Style.isVerilog()) {3319    // Event control.3320    parseVerilogSensitivityList();3321  } else if (Style.AllowShortLoopsOnASingleLine && FormatTok->is(tok::semi) &&3322             Tokens->getPreviousToken()->is(tok::r_paren)) {3323    nextToken();3324    addUnwrappedLine();3325    return;3326  }3327 3328  handleAttributes();3329  parseLoopBody(KeepBraces, /*WrapRightBrace=*/true);3330}3331 3332void UnwrappedLineParser::parseDoWhile() {3333  assert(FormatTok->is(tok::kw_do) && "'do' expected");3334  nextToken();3335 3336  parseLoopBody(/*KeepBraces=*/true, Style.BraceWrapping.BeforeWhile);3337 3338  // FIXME: Add error handling.3339  if (FormatTok->isNot(tok::kw_while)) {3340    addUnwrappedLine();3341    return;3342  }3343 3344  FormatTok->setFinalizedType(TT_DoWhile);3345 3346  // If in Whitesmiths mode, the line with the while() needs to be indented3347  // to the same level as the block.3348  if (Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths)3349    ++Line->Level;3350 3351  nextToken();3352  parseStructuralElement();3353}3354 3355void UnwrappedLineParser::parseLabel(bool LeftAlignLabel) {3356  nextToken();3357  unsigned OldLineLevel = Line->Level;3358 3359  if (LeftAlignLabel)3360    Line->Level = 0;3361  else if (Line->Level > 1 || (!Line->InPPDirective && Line->Level > 0))3362    --Line->Level;3363 3364  if (!Style.IndentCaseBlocks && CommentsBeforeNextToken.empty() &&3365      FormatTok->is(tok::l_brace)) {3366 3367    CompoundStatementIndenter Indenter(this, Line->Level,3368                                       Style.BraceWrapping.AfterCaseLabel,3369                                       Style.BraceWrapping.IndentBraces);3370    parseBlock();3371    if (FormatTok->is(tok::kw_break)) {3372      if (Style.BraceWrapping.AfterControlStatement ==3373          FormatStyle::BWACS_Always) {3374        addUnwrappedLine();3375        if (!Style.IndentCaseBlocks &&3376            Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths) {3377          ++Line->Level;3378        }3379      }3380      parseStructuralElement();3381    }3382    addUnwrappedLine();3383  } else {3384    if (FormatTok->is(tok::semi))3385      nextToken();3386    addUnwrappedLine();3387  }3388  Line->Level = OldLineLevel;3389  if (FormatTok->isNot(tok::l_brace)) {3390    parseStructuralElement();3391    addUnwrappedLine();3392  }3393}3394 3395void UnwrappedLineParser::parseCaseLabel() {3396  assert(FormatTok->is(tok::kw_case) && "'case' expected");3397  auto *Case = FormatTok;3398 3399  // FIXME: fix handling of complex expressions here.3400  do {3401    nextToken();3402    if (FormatTok->is(tok::colon)) {3403      FormatTok->setFinalizedType(TT_CaseLabelColon);3404      break;3405    }3406    if (Style.isJava() && FormatTok->is(tok::arrow)) {3407      FormatTok->setFinalizedType(TT_CaseLabelArrow);3408      Case->setFinalizedType(TT_SwitchExpressionLabel);3409      break;3410    }3411  } while (!eof());3412  parseLabel();3413}3414 3415void UnwrappedLineParser::parseSwitch(bool IsExpr) {3416  assert(FormatTok->is(tok::kw_switch) && "'switch' expected");3417  nextToken();3418  if (FormatTok->is(tok::l_paren))3419    parseParens();3420 3421  keepAncestorBraces();3422 3423  if (FormatTok->is(tok::l_brace)) {3424    CompoundStatementIndenter Indenter(this, Style, Line->Level);3425    FormatTok->setFinalizedType(IsExpr ? TT_SwitchExpressionLBrace3426                                       : TT_ControlStatementLBrace);3427    if (IsExpr)3428      parseChildBlock();3429    else3430      parseBlock();3431    setPreviousRBraceType(TT_ControlStatementRBrace);3432    if (!IsExpr)3433      addUnwrappedLine();3434  } else {3435    addUnwrappedLine();3436    ++Line->Level;3437    parseStructuralElement();3438    --Line->Level;3439  }3440 3441  if (Style.RemoveBracesLLVM)3442    NestedTooDeep.pop_back();3443}3444 3445void UnwrappedLineParser::parseAccessSpecifier() {3446  nextToken();3447  // Understand Qt's slots.3448  if (FormatTok->isOneOf(Keywords.kw_slots, Keywords.kw_qslots))3449    nextToken();3450  // Otherwise, we don't know what it is, and we'd better keep the next token.3451  if (FormatTok->is(tok::colon))3452    nextToken();3453  addUnwrappedLine();3454}3455 3456/// Parses a requires, decides if it is a clause or an expression.3457/// \pre The current token has to be the requires keyword.3458/// \returns true if it parsed a clause.3459bool UnwrappedLineParser::parseRequires(bool SeenEqual) {3460  assert(FormatTok->is(tok::kw_requires) && "'requires' expected");3461 3462  // We try to guess if it is a requires clause, or a requires expression. For3463  // that we first check the next token.3464  switch (Tokens->peekNextToken(/*SkipComment=*/true)->Tok.getKind()) {3465  case tok::l_brace:3466    // This can only be an expression, never a clause.3467    parseRequiresExpression();3468    return false;3469  case tok::l_paren:3470    // Clauses and expression can start with a paren, it's unclear what we have.3471    break;3472  default:3473    // All other tokens can only be a clause.3474    parseRequiresClause();3475    return true;3476  }3477 3478  // Looking forward we would have to decide if there are function declaration3479  // like arguments to the requires expression:3480  // requires (T t) {3481  // Or there is a constraint expression for the requires clause:3482  // requires (C<T> && ...3483 3484  // But first let's look behind.3485  auto *PreviousNonComment = FormatTok->getPreviousNonComment();3486 3487  if (!PreviousNonComment ||3488      PreviousNonComment->is(TT_RequiresExpressionLBrace)) {3489    // If there is no token, or an expression left brace, we are a requires3490    // clause within a requires expression.3491    parseRequiresClause();3492    return true;3493  }3494 3495  switch (PreviousNonComment->Tok.getKind()) {3496  case tok::greater:3497  case tok::r_paren:3498  case tok::kw_noexcept:3499  case tok::kw_const:3500  case tok::star:3501  case tok::amp:3502    // This is a requires clause.3503    parseRequiresClause();3504    return true;3505  case tok::ampamp: {3506    // This can be either:3507    // if (... && requires (T t) ...)3508    // Or3509    // void member(...) && requires (C<T> ...3510    // We check the one token before that for a const:3511    // void member(...) const && requires (C<T> ...3512    auto PrevPrev = PreviousNonComment->getPreviousNonComment();3513    if ((PrevPrev && PrevPrev->is(tok::kw_const)) || !SeenEqual) {3514      parseRequiresClause();3515      return true;3516    }3517    break;3518  }3519  default:3520    if (PreviousNonComment->isTypeOrIdentifier(LangOpts)) {3521      // This is a requires clause.3522      parseRequiresClause();3523      return true;3524    }3525    // It's an expression.3526    parseRequiresExpression();3527    return false;3528  }3529 3530  // Now we look forward and try to check if the paren content is a parameter3531  // list. The parameters can be cv-qualified and contain references or3532  // pointers.3533  // So we want basically to check for TYPE NAME, but TYPE can contain all kinds3534  // of stuff: typename, const, *, &, &&, ::, identifiers.3535 3536  unsigned StoredPosition = Tokens->getPosition();3537  FormatToken *NextToken = Tokens->getNextToken();3538  int Lookahead = 0;3539  auto PeekNext = [&Lookahead, &NextToken, this] {3540    ++Lookahead;3541    NextToken = Tokens->getNextToken();3542  };3543 3544  bool FoundType = false;3545  bool LastWasColonColon = false;3546  int OpenAngles = 0;3547 3548  for (; Lookahead < 50; PeekNext()) {3549    switch (NextToken->Tok.getKind()) {3550    case tok::kw_volatile:3551    case tok::kw_const:3552    case tok::comma:3553      if (OpenAngles == 0) {3554        FormatTok = Tokens->setPosition(StoredPosition);3555        parseRequiresExpression();3556        return false;3557      }3558      break;3559    case tok::eof:3560      // Break out of the loop.3561      Lookahead = 50;3562      break;3563    case tok::coloncolon:3564      LastWasColonColon = true;3565      break;3566    case tok::kw_decltype:3567    case tok::identifier:3568      if (FoundType && !LastWasColonColon && OpenAngles == 0) {3569        FormatTok = Tokens->setPosition(StoredPosition);3570        parseRequiresExpression();3571        return false;3572      }3573      FoundType = true;3574      LastWasColonColon = false;3575      break;3576    case tok::less:3577      ++OpenAngles;3578      break;3579    case tok::greater:3580      --OpenAngles;3581      break;3582    default:3583      if (NextToken->isTypeName(LangOpts)) {3584        FormatTok = Tokens->setPosition(StoredPosition);3585        parseRequiresExpression();3586        return false;3587      }3588      break;3589    }3590  }3591  // This seems to be a complicated expression, just assume it's a clause.3592  FormatTok = Tokens->setPosition(StoredPosition);3593  parseRequiresClause();3594  return true;3595}3596 3597/// Parses a requires clause.3598/// \sa parseRequiresExpression3599///3600/// Returns if it either has finished parsing the clause, or it detects, that3601/// the clause is incorrect.3602void UnwrappedLineParser::parseRequiresClause() {3603  assert(FormatTok->is(tok::kw_requires) && "'requires' expected");3604 3605  // If there is no previous token, we are within a requires expression,3606  // otherwise we will always have the template or function declaration in front3607  // of it.3608  bool InRequiresExpression =3609      !FormatTok->Previous ||3610      FormatTok->Previous->is(TT_RequiresExpressionLBrace);3611 3612  FormatTok->setFinalizedType(InRequiresExpression3613                                  ? TT_RequiresClauseInARequiresExpression3614                                  : TT_RequiresClause);3615  nextToken();3616 3617  // NOTE: parseConstraintExpression is only ever called from this function.3618  // It could be inlined into here.3619  parseConstraintExpression();3620 3621  if (!InRequiresExpression && FormatTok->Previous)3622    FormatTok->Previous->ClosesRequiresClause = true;3623}3624 3625/// Parses a requires expression.3626/// \sa parseRequiresClause3627///3628/// Returns if it either has finished parsing the expression, or it detects,3629/// that the expression is incorrect.3630void UnwrappedLineParser::parseRequiresExpression() {3631  assert(FormatTok->is(tok::kw_requires) && "'requires' expected");3632 3633  FormatTok->setFinalizedType(TT_RequiresExpression);3634  nextToken();3635 3636  if (FormatTok->is(tok::l_paren)) {3637    FormatTok->setFinalizedType(TT_RequiresExpressionLParen);3638    parseParens();3639  }3640 3641  if (FormatTok->is(tok::l_brace)) {3642    FormatTok->setFinalizedType(TT_RequiresExpressionLBrace);3643    parseChildBlock();3644  }3645}3646 3647/// Parses a constraint expression.3648///3649/// This is the body of a requires clause. It returns, when the parsing is3650/// complete, or the expression is incorrect.3651void UnwrappedLineParser::parseConstraintExpression() {3652  // The special handling for lambdas is needed since tryToParseLambda() eats a3653  // token and if a requires expression is the last part of a requires clause3654  // and followed by an attribute like [[nodiscard]] the ClosesRequiresClause is3655  // not set on the correct token. Thus we need to be aware if we even expect a3656  // lambda to be possible.3657  // template <typename T> requires requires { ... } [[nodiscard]] ...;3658  bool LambdaNextTimeAllowed = true;3659 3660  // Within lambda declarations, it is permitted to put a requires clause after3661  // its template parameter list, which would place the requires clause right3662  // before the parentheses of the parameters of the lambda declaration. Thus,3663  // we track if we expect to see grouping parentheses at all.3664  // Without this check, `requires foo<T> (T t)` in the below example would be3665  // seen as the whole requires clause, accidentally eating the parameters of3666  // the lambda.3667  // [&]<typename T> requires foo<T> (T t) { ... };3668  bool TopLevelParensAllowed = true;3669 3670  do {3671    bool LambdaThisTimeAllowed = std::exchange(LambdaNextTimeAllowed, false);3672 3673    switch (FormatTok->Tok.getKind()) {3674    case tok::kw_requires:3675      parseRequiresExpression();3676      break;3677 3678    case tok::l_paren:3679      if (!TopLevelParensAllowed)3680        return;3681      parseParens(/*AmpAmpTokenType=*/TT_BinaryOperator);3682      TopLevelParensAllowed = false;3683      break;3684 3685    case tok::l_square:3686      if (!LambdaThisTimeAllowed || !tryToParseLambda())3687        return;3688      break;3689 3690    case tok::kw_const:3691    case tok::semi:3692    case tok::kw_class:3693    case tok::kw_struct:3694    case tok::kw_union:3695      return;3696 3697    case tok::l_brace:3698      // Potential function body.3699      return;3700 3701    case tok::ampamp:3702    case tok::pipepipe:3703      FormatTok->setFinalizedType(TT_BinaryOperator);3704      nextToken();3705      LambdaNextTimeAllowed = true;3706      TopLevelParensAllowed = true;3707      break;3708 3709    case tok::comma:3710    case tok::comment:3711      LambdaNextTimeAllowed = LambdaThisTimeAllowed;3712      nextToken();3713      break;3714 3715    case tok::kw_sizeof:3716    case tok::greater:3717    case tok::greaterequal:3718    case tok::greatergreater:3719    case tok::less:3720    case tok::lessequal:3721    case tok::lessless:3722    case tok::equalequal:3723    case tok::exclaim:3724    case tok::exclaimequal:3725    case tok::plus:3726    case tok::minus:3727    case tok::star:3728    case tok::slash:3729      LambdaNextTimeAllowed = true;3730      TopLevelParensAllowed = true;3731      // Just eat them.3732      nextToken();3733      break;3734 3735    case tok::numeric_constant:3736    case tok::coloncolon:3737    case tok::kw_true:3738    case tok::kw_false:3739      TopLevelParensAllowed = false;3740      // Just eat them.3741      nextToken();3742      break;3743 3744    case tok::kw_static_cast:3745    case tok::kw_const_cast:3746    case tok::kw_reinterpret_cast:3747    case tok::kw_dynamic_cast:3748      nextToken();3749      if (FormatTok->isNot(tok::less))3750        return;3751 3752      nextToken();3753      parseBracedList(/*IsAngleBracket=*/true);3754      break;3755 3756    default:3757      if (!FormatTok->Tok.getIdentifierInfo()) {3758        // Identifiers are part of the default case, we check for more then3759        // tok::identifier to handle builtin type traits.3760        return;3761      }3762 3763      // We need to differentiate identifiers for a template deduction guide,3764      // variables, or function return types (the constraint expression has3765      // ended before that), and basically all other cases. But it's easier to3766      // check the other way around.3767      assert(FormatTok->Previous);3768      switch (FormatTok->Previous->Tok.getKind()) {3769      case tok::coloncolon:  // Nested identifier.3770      case tok::ampamp:      // Start of a function or variable for the3771      case tok::pipepipe:    // constraint expression. (binary)3772      case tok::exclaim:     // The same as above, but unary.3773      case tok::kw_requires: // Initial identifier of a requires clause.3774      case tok::equal:       // Initial identifier of a concept declaration.3775        break;3776      default:3777        return;3778      }3779 3780      // Read identifier with optional template declaration.3781      nextToken();3782      if (FormatTok->is(tok::less)) {3783        nextToken();3784        parseBracedList(/*IsAngleBracket=*/true);3785      }3786      TopLevelParensAllowed = false;3787      break;3788    }3789  } while (!eof());3790}3791 3792bool UnwrappedLineParser::parseEnum() {3793  const FormatToken &InitialToken = *FormatTok;3794 3795  // Won't be 'enum' for NS_ENUMs.3796  if (FormatTok->is(tok::kw_enum))3797    nextToken();3798 3799  // In TypeScript, "enum" can also be used as property name, e.g. in interface3800  // declarations. An "enum" keyword followed by a colon would be a syntax3801  // error and thus assume it is just an identifier.3802  if (Style.isJavaScript() && FormatTok->isOneOf(tok::colon, tok::question))3803    return false;3804 3805  // In protobuf, "enum" can be used as a field name.3806  if (Style.Language == FormatStyle::LK_Proto && FormatTok->is(tok::equal))3807    return false;3808 3809  if (IsCpp) {3810    // Eat up enum class ...3811    if (FormatTok->isOneOf(tok::kw_class, tok::kw_struct))3812      nextToken();3813    while (FormatTok->is(tok::l_square))3814      if (!handleCppAttributes())3815        return false;3816  }3817 3818  while (FormatTok->Tok.getIdentifierInfo() ||3819         FormatTok->isOneOf(tok::colon, tok::coloncolon, tok::less,3820                            tok::greater, tok::comma, tok::question,3821                            tok::l_square)) {3822    if (Style.isVerilog()) {3823      FormatTok->setFinalizedType(TT_VerilogDimensionedTypeName);3824      nextToken();3825      // In Verilog the base type can have dimensions.3826      while (FormatTok->is(tok::l_square))3827        parseSquare();3828    } else {3829      nextToken();3830    }3831    // We can have macros or attributes in between 'enum' and the enum name.3832    if (FormatTok->is(tok::l_paren))3833      parseParens();3834    if (FormatTok->is(tok::identifier)) {3835      nextToken();3836      // If there are two identifiers in a row, this is likely an elaborate3837      // return type. In Java, this can be "implements", etc.3838      if (IsCpp && FormatTok->is(tok::identifier))3839        return false;3840    }3841  }3842 3843  // Just a declaration or something is wrong.3844  if (FormatTok->isNot(tok::l_brace))3845    return true;3846  FormatTok->setFinalizedType(TT_EnumLBrace);3847  FormatTok->setBlockKind(BK_Block);3848 3849  if (Style.isJava()) {3850    // Java enums are different.3851    parseJavaEnumBody();3852    return true;3853  }3854  if (Style.Language == FormatStyle::LK_Proto) {3855    parseBlock(/*MustBeDeclaration=*/true);3856    return true;3857  }3858 3859  if (!Style.AllowShortEnumsOnASingleLine &&3860      ShouldBreakBeforeBrace(Style, InitialToken, /*IsJavaRecord=*/false)) {3861    addUnwrappedLine();3862  }3863  // Parse enum body.3864  nextToken();3865  if (!Style.AllowShortEnumsOnASingleLine) {3866    addUnwrappedLine();3867    Line->Level += 1;3868  }3869  bool HasError = !parseBracedList(/*IsAngleBracket=*/false, /*IsEnum=*/true);3870  if (!Style.AllowShortEnumsOnASingleLine)3871    Line->Level -= 1;3872  if (HasError) {3873    if (FormatTok->is(tok::semi))3874      nextToken();3875    addUnwrappedLine();3876  }3877  setPreviousRBraceType(TT_EnumRBrace);3878  return true;3879 3880  // There is no addUnwrappedLine() here so that we fall through to parsing a3881  // structural element afterwards. Thus, in "enum A {} n, m;",3882  // "} n, m;" will end up in one unwrapped line.3883}3884 3885bool UnwrappedLineParser::parseStructLike() {3886  // parseRecord falls through and does not yet add an unwrapped line as a3887  // record declaration or definition can start a structural element.3888  parseRecord();3889  // This does not apply to Java, JavaScript and C#.3890  if (Style.isJava() || Style.isJavaScript() || Style.isCSharp()) {3891    if (FormatTok->is(tok::semi))3892      nextToken();3893    addUnwrappedLine();3894    return true;3895  }3896  return false;3897}3898 3899namespace {3900// A class used to set and restore the Token position when peeking3901// ahead in the token source.3902class ScopedTokenPosition {3903  unsigned StoredPosition;3904  FormatTokenSource *Tokens;3905 3906public:3907  ScopedTokenPosition(FormatTokenSource *Tokens) : Tokens(Tokens) {3908    assert(Tokens && "Tokens expected to not be null");3909    StoredPosition = Tokens->getPosition();3910  }3911 3912  ~ScopedTokenPosition() { Tokens->setPosition(StoredPosition); }3913};3914} // namespace3915 3916// Look to see if we have [[ by looking ahead, if3917// its not then rewind to the original position.3918bool UnwrappedLineParser::tryToParseSimpleAttribute() {3919  ScopedTokenPosition AutoPosition(Tokens);3920  FormatToken *Tok = Tokens->getNextToken();3921  // We already read the first [ check for the second.3922  if (Tok->isNot(tok::l_square))3923    return false;3924  // Double check that the attribute is just something3925  // fairly simple.3926  while (Tok->isNot(tok::eof)) {3927    if (Tok->is(tok::r_square))3928      break;3929    Tok = Tokens->getNextToken();3930  }3931  if (Tok->is(tok::eof))3932    return false;3933  Tok = Tokens->getNextToken();3934  if (Tok->isNot(tok::r_square))3935    return false;3936  Tok = Tokens->getNextToken();3937  if (Tok->is(tok::semi))3938    return false;3939  return true;3940}3941 3942void UnwrappedLineParser::parseJavaEnumBody() {3943  assert(FormatTok->is(tok::l_brace));3944  const FormatToken *OpeningBrace = FormatTok;3945 3946  // Determine whether the enum is simple, i.e. does not have a semicolon or3947  // constants with class bodies. Simple enums can be formatted like braced3948  // lists, contracted to a single line, etc.3949  unsigned StoredPosition = Tokens->getPosition();3950  bool IsSimple = true;3951  FormatToken *Tok = Tokens->getNextToken();3952  while (Tok->isNot(tok::eof)) {3953    if (Tok->is(tok::r_brace))3954      break;3955    if (Tok->isOneOf(tok::l_brace, tok::semi)) {3956      IsSimple = false;3957      break;3958    }3959    // FIXME: This will also mark enums with braces in the arguments to enum3960    // constants as "not simple". This is probably fine in practice, though.3961    Tok = Tokens->getNextToken();3962  }3963  FormatTok = Tokens->setPosition(StoredPosition);3964 3965  if (IsSimple) {3966    nextToken();3967    parseBracedList();3968    addUnwrappedLine();3969    return;3970  }3971 3972  // Parse the body of a more complex enum.3973  // First add a line for everything up to the "{".3974  nextToken();3975  addUnwrappedLine();3976  ++Line->Level;3977 3978  // Parse the enum constants.3979  while (!eof()) {3980    if (FormatTok->is(tok::l_brace)) {3981      // Parse the constant's class body.3982      parseBlock(/*MustBeDeclaration=*/true, /*AddLevels=*/1u,3983                 /*MunchSemi=*/false);3984    } else if (FormatTok->is(tok::l_paren)) {3985      parseParens();3986    } else if (FormatTok->is(tok::comma)) {3987      nextToken();3988      addUnwrappedLine();3989    } else if (FormatTok->is(tok::semi)) {3990      nextToken();3991      addUnwrappedLine();3992      break;3993    } else if (FormatTok->is(tok::r_brace)) {3994      addUnwrappedLine();3995      break;3996    } else {3997      nextToken();3998    }3999  }4000 4001  // Parse the class body after the enum's ";" if any.4002  parseLevel(OpeningBrace);4003  nextToken();4004  --Line->Level;4005  addUnwrappedLine();4006}4007 4008void UnwrappedLineParser::parseRecord(bool ParseAsExpr, bool IsJavaRecord) {4009  assert(!IsJavaRecord || FormatTok->is(Keywords.kw_record));4010  const FormatToken &InitialToken = *FormatTok;4011  nextToken();4012 4013  FormatToken *ClassName =4014      IsJavaRecord && FormatTok->is(tok::identifier) ? FormatTok : nullptr;4015  bool IsDerived = false;4016  auto IsNonMacroIdentifier = [](const FormatToken *Tok) {4017    return Tok->is(tok::identifier) && Tok->TokenText != Tok->TokenText.upper();4018  };4019  // JavaScript/TypeScript supports anonymous classes like:4020  // a = class extends foo { }4021  bool JSPastExtendsOrImplements = false;4022  // The actual identifier can be a nested name specifier, and in macros4023  // it is often token-pasted.4024  // An [[attribute]] can be before the identifier.4025  while (FormatTok->isOneOf(tok::identifier, tok::coloncolon, tok::hashhash,4026                            tok::kw_alignas, tok::l_square) ||4027         FormatTok->isAttribute() ||4028         ((Style.isJava() || Style.isJavaScript()) &&4029          FormatTok->isOneOf(tok::period, tok::comma))) {4030    if (Style.isJavaScript() &&4031        FormatTok->isOneOf(Keywords.kw_extends, Keywords.kw_implements)) {4032      JSPastExtendsOrImplements = true;4033      // JavaScript/TypeScript supports inline object types in4034      // extends/implements positions:4035      //     class Foo implements {bar: number} { }4036      nextToken();4037      if (FormatTok->is(tok::l_brace)) {4038        tryToParseBracedList();4039        continue;4040      }4041    }4042    if (FormatTok->is(tok::l_square) && handleCppAttributes())4043      continue;4044    auto *Previous = FormatTok;4045    nextToken();4046    switch (FormatTok->Tok.getKind()) {4047    case tok::l_paren:4048      // We can have macros in between 'class' and the class name.4049      if (IsJavaRecord || !IsNonMacroIdentifier(Previous) ||4050          // e.g. `struct macro(a) S { int i; };`4051          Previous->Previous == &InitialToken) {4052        parseParens();4053      }4054      break;4055    case tok::coloncolon:4056    case tok::hashhash:4057      break;4058    default:4059      if (JSPastExtendsOrImplements || ClassName ||4060          Previous->isNot(tok::identifier) || Previous->is(TT_AttributeMacro)) {4061        break;4062      }4063      if (const auto Text = Previous->TokenText;4064          Text.size() == 1 || Text != Text.upper()) {4065        ClassName = Previous;4066      }4067    }4068  }4069 4070  auto IsListInitialization = [&] {4071    if (!ClassName || IsDerived || JSPastExtendsOrImplements)4072      return false;4073    assert(FormatTok->is(tok::l_brace));4074    const auto *Prev = FormatTok->getPreviousNonComment();4075    assert(Prev);4076    return Prev != ClassName && Prev->is(tok::identifier) &&4077           Prev->isNot(Keywords.kw_final) && tryToParseBracedList();4078  };4079 4080  if (FormatTok->isOneOf(tok::colon, tok::less)) {4081    int AngleNestingLevel = 0;4082    do {4083      if (FormatTok->is(tok::less))4084        ++AngleNestingLevel;4085      else if (FormatTok->is(tok::greater))4086        --AngleNestingLevel;4087 4088      if (AngleNestingLevel == 0) {4089        if (FormatTok->is(tok::colon)) {4090          IsDerived = true;4091        } else if (!IsDerived && FormatTok->is(tok::identifier) &&4092                   FormatTok->Previous->is(tok::coloncolon)) {4093          ClassName = FormatTok;4094        } else if (FormatTok->is(tok::l_paren) &&4095                   IsNonMacroIdentifier(FormatTok->Previous)) {4096          break;4097        }4098      }4099      if (FormatTok->is(tok::l_brace)) {4100        if (AngleNestingLevel == 0 && IsListInitialization())4101          return;4102        calculateBraceTypes(/*ExpectClassBody=*/true);4103        if (!tryToParseBracedList())4104          break;4105      }4106      if (FormatTok->is(tok::l_square)) {4107        FormatToken *Previous = FormatTok->Previous;4108        if (!Previous || (Previous->isNot(tok::r_paren) &&4109                          !Previous->isTypeOrIdentifier(LangOpts))) {4110          // Don't try parsing a lambda if we had a closing parenthesis before,4111          // it was probably a pointer to an array: int (*)[].4112          if (!tryToParseLambda())4113            continue;4114        } else {4115          parseSquare();4116          continue;4117        }4118      }4119      if (FormatTok->is(tok::semi))4120        return;4121      if (Style.isCSharp() && FormatTok->is(Keywords.kw_where)) {4122        addUnwrappedLine();4123        nextToken();4124        parseCSharpGenericTypeConstraint();4125        break;4126      }4127      nextToken();4128    } while (!eof());4129  }4130 4131  auto GetBraceTypes =4132      [](const FormatToken &RecordTok) -> std::pair<TokenType, TokenType> {4133    switch (RecordTok.Tok.getKind()) {4134    case tok::kw_class:4135      return {TT_ClassLBrace, TT_ClassRBrace};4136    case tok::kw_struct:4137      return {TT_StructLBrace, TT_StructRBrace};4138    case tok::kw_union:4139      return {TT_UnionLBrace, TT_UnionRBrace};4140    default:4141      // Useful for e.g. interface.4142      return {TT_RecordLBrace, TT_RecordRBrace};4143    }4144  };4145  if (FormatTok->is(tok::l_brace)) {4146    if (IsListInitialization())4147      return;4148    if (ClassName)4149      ClassName->setFinalizedType(TT_ClassHeadName);4150    auto [OpenBraceType, ClosingBraceType] = GetBraceTypes(InitialToken);4151    FormatTok->setFinalizedType(OpenBraceType);4152    if (ParseAsExpr) {4153      parseChildBlock();4154    } else {4155      if (ShouldBreakBeforeBrace(Style, InitialToken, IsJavaRecord))4156        addUnwrappedLine();4157 4158      unsigned AddLevels = Style.IndentAccessModifiers ? 2u : 1u;4159      parseBlock(/*MustBeDeclaration=*/true, AddLevels, /*MunchSemi=*/false);4160    }4161    setPreviousRBraceType(ClosingBraceType);4162  }4163  // There is no addUnwrappedLine() here so that we fall through to parsing a4164  // structural element afterwards. Thus, in "class A {} n, m;",4165  // "} n, m;" will end up in one unwrapped line.4166}4167 4168void UnwrappedLineParser::parseObjCMethod() {4169  assert(FormatTok->isOneOf(tok::l_paren, tok::identifier) &&4170         "'(' or identifier expected.");4171  do {4172    if (FormatTok->is(tok::semi)) {4173      nextToken();4174      addUnwrappedLine();4175      return;4176    } else if (FormatTok->is(tok::l_brace)) {4177      if (Style.BraceWrapping.AfterFunction)4178        addUnwrappedLine();4179      parseBlock();4180      addUnwrappedLine();4181      return;4182    } else {4183      nextToken();4184    }4185  } while (!eof());4186}4187 4188void UnwrappedLineParser::parseObjCProtocolList() {4189  assert(FormatTok->is(tok::less) && "'<' expected.");4190  do {4191    nextToken();4192    // Early exit in case someone forgot a close angle.4193    if (FormatTok->isOneOf(tok::semi, tok::l_brace, tok::objc_end))4194      return;4195  } while (!eof() && FormatTok->isNot(tok::greater));4196  nextToken(); // Skip '>'.4197}4198 4199void UnwrappedLineParser::parseObjCUntilAtEnd() {4200  do {4201    if (FormatTok->is(tok::objc_end)) {4202      nextToken();4203      addUnwrappedLine();4204      break;4205    }4206    if (FormatTok->is(tok::l_brace)) {4207      parseBlock();4208      // In ObjC interfaces, nothing should be following the "}".4209      addUnwrappedLine();4210    } else if (FormatTok->is(tok::r_brace)) {4211      // Ignore stray "}". parseStructuralElement doesn't consume them.4212      nextToken();4213      addUnwrappedLine();4214    } else if (FormatTok->isOneOf(tok::minus, tok::plus)) {4215      nextToken();4216      parseObjCMethod();4217    } else {4218      parseStructuralElement();4219    }4220  } while (!eof());4221}4222 4223void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {4224  assert(FormatTok->isOneOf(tok::objc_interface, tok::objc_implementation));4225  nextToken();4226  nextToken(); // interface name4227 4228  // @interface can be followed by a lightweight generic4229  // specialization list, then either a base class or a category.4230  if (FormatTok->is(tok::less))4231    parseObjCLightweightGenerics();4232  if (FormatTok->is(tok::colon)) {4233    nextToken();4234    nextToken(); // base class name4235    // The base class can also have lightweight generics applied to it.4236    if (FormatTok->is(tok::less))4237      parseObjCLightweightGenerics();4238  } else if (FormatTok->is(tok::l_paren)) {4239    // Skip category, if present.4240    parseParens();4241  }4242 4243  if (FormatTok->is(tok::less))4244    parseObjCProtocolList();4245 4246  if (FormatTok->is(tok::l_brace)) {4247    if (Style.BraceWrapping.AfterObjCDeclaration)4248      addUnwrappedLine();4249    parseBlock(/*MustBeDeclaration=*/true);4250  }4251 4252  // With instance variables, this puts '}' on its own line.  Without instance4253  // variables, this ends the @interface line.4254  addUnwrappedLine();4255 4256  parseObjCUntilAtEnd();4257}4258 4259void UnwrappedLineParser::parseObjCLightweightGenerics() {4260  assert(FormatTok->is(tok::less));4261  // Unlike protocol lists, generic parameterizations support4262  // nested angles:4263  //4264  // @interface Foo<ValueType : id <NSCopying, NSSecureCoding>> :4265  //     NSObject <NSCopying, NSSecureCoding>4266  //4267  // so we need to count how many open angles we have left.4268  unsigned NumOpenAngles = 1;4269  do {4270    nextToken();4271    // Early exit in case someone forgot a close angle.4272    if (FormatTok->isOneOf(tok::semi, tok::l_brace, tok::objc_end))4273      break;4274    if (FormatTok->is(tok::less)) {4275      ++NumOpenAngles;4276    } else if (FormatTok->is(tok::greater)) {4277      assert(NumOpenAngles > 0 && "'>' makes NumOpenAngles negative");4278      --NumOpenAngles;4279    }4280  } while (!eof() && NumOpenAngles != 0);4281  nextToken(); // Skip '>'.4282}4283 4284// Returns true for the declaration/definition form of @protocol,4285// false for the expression form.4286bool UnwrappedLineParser::parseObjCProtocol() {4287  assert(FormatTok->is(tok::objc_protocol));4288  nextToken();4289 4290  if (FormatTok->is(tok::l_paren)) {4291    // The expression form of @protocol, e.g. "Protocol* p = @protocol(foo);".4292    return false;4293  }4294 4295  // The definition/declaration form,4296  // @protocol Foo4297  // - (int)someMethod;4298  // @end4299 4300  nextToken(); // protocol name4301 4302  if (FormatTok->is(tok::less))4303    parseObjCProtocolList();4304 4305  // Check for protocol declaration.4306  if (FormatTok->is(tok::semi)) {4307    nextToken();4308    addUnwrappedLine();4309    return true;4310  }4311 4312  addUnwrappedLine();4313  parseObjCUntilAtEnd();4314  return true;4315}4316 4317void UnwrappedLineParser::parseJavaScriptEs6ImportExport() {4318  bool IsImport = FormatTok->is(Keywords.kw_import);4319  assert(IsImport || FormatTok->is(tok::kw_export));4320  nextToken();4321 4322  // Consume the "default" in "export default class/function".4323  if (FormatTok->is(tok::kw_default))4324    nextToken();4325 4326  // Consume "async function", "function" and "default function", so that these4327  // get parsed as free-standing JS functions, i.e. do not require a trailing4328  // semicolon.4329  if (FormatTok->is(Keywords.kw_async))4330    nextToken();4331  if (FormatTok->is(Keywords.kw_function)) {4332    nextToken();4333    return;4334  }4335 4336  // For imports, `export *`, `export {...}`, consume the rest of the line up4337  // to the terminating `;`. For everything else, just return and continue4338  // parsing the structural element, i.e. the declaration or expression for4339  // `export default`.4340  if (!IsImport && FormatTok->isNoneOf(tok::l_brace, tok::star) &&4341      !FormatTok->isStringLiteral() &&4342      !(FormatTok->is(Keywords.kw_type) &&4343        Tokens->peekNextToken()->isOneOf(tok::l_brace, tok::star))) {4344    return;4345  }4346 4347  while (!eof()) {4348    if (FormatTok->is(tok::semi))4349      return;4350    if (Line->Tokens.empty()) {4351      // Common issue: Automatic Semicolon Insertion wrapped the line, so the4352      // import statement should terminate.4353      return;4354    }4355    if (FormatTok->is(tok::l_brace)) {4356      FormatTok->setBlockKind(BK_Block);4357      nextToken();4358      parseBracedList();4359    } else {4360      nextToken();4361    }4362  }4363}4364 4365void UnwrappedLineParser::parseStatementMacro() {4366  nextToken();4367  if (FormatTok->is(tok::l_paren))4368    parseParens();4369  if (FormatTok->is(tok::semi))4370    nextToken();4371  addUnwrappedLine();4372}4373 4374void UnwrappedLineParser::parseVerilogHierarchyIdentifier() {4375  // consume things like a::`b.c[d:e] or a::*4376  while (true) {4377    if (FormatTok->isOneOf(tok::star, tok::period, tok::periodstar,4378                           tok::coloncolon, tok::hash) ||4379        Keywords.isVerilogIdentifier(*FormatTok)) {4380      nextToken();4381    } else if (FormatTok->is(tok::l_square)) {4382      parseSquare();4383    } else {4384      break;4385    }4386  }4387}4388 4389void UnwrappedLineParser::parseVerilogSensitivityList() {4390  if (FormatTok->isNot(tok::at))4391    return;4392  nextToken();4393  // A block event expression has 2 at signs.4394  if (FormatTok->is(tok::at))4395    nextToken();4396  switch (FormatTok->Tok.getKind()) {4397  case tok::star:4398    nextToken();4399    break;4400  case tok::l_paren:4401    parseParens();4402    break;4403  default:4404    parseVerilogHierarchyIdentifier();4405    break;4406  }4407}4408 4409unsigned UnwrappedLineParser::parseVerilogHierarchyHeader() {4410  unsigned AddLevels = 0;4411 4412  if (FormatTok->is(Keywords.kw_clocking)) {4413    nextToken();4414    if (Keywords.isVerilogIdentifier(*FormatTok))4415      nextToken();4416    parseVerilogSensitivityList();4417    if (FormatTok->is(tok::semi))4418      nextToken();4419  } else if (FormatTok->isOneOf(tok::kw_case, Keywords.kw_casex,4420                                Keywords.kw_casez, Keywords.kw_randcase,4421                                Keywords.kw_randsequence)) {4422    if (Style.IndentCaseLabels)4423      AddLevels++;4424    nextToken();4425    if (FormatTok->is(tok::l_paren)) {4426      FormatTok->setFinalizedType(TT_ConditionLParen);4427      parseParens();4428    }4429    if (FormatTok->isOneOf(Keywords.kw_inside, Keywords.kw_matches))4430      nextToken();4431    // The case header has no semicolon.4432  } else {4433    // "module" etc.4434    nextToken();4435    // all the words like the name of the module and specifiers like4436    // "automatic" and the width of function return type4437    while (true) {4438      if (FormatTok->is(tok::l_square)) {4439        auto Prev = FormatTok->getPreviousNonComment();4440        if (Prev && Keywords.isVerilogIdentifier(*Prev))4441          Prev->setFinalizedType(TT_VerilogDimensionedTypeName);4442        parseSquare();4443      } else if (Keywords.isVerilogIdentifier(*FormatTok) ||4444                 FormatTok->isOneOf(tok::hash, tok::hashhash, tok::coloncolon,4445                                    Keywords.kw_automatic, tok::kw_static)) {4446        nextToken();4447      } else {4448        break;4449      }4450    }4451 4452    auto NewLine = [this]() {4453      addUnwrappedLine();4454      Line->IsContinuation = true;4455    };4456 4457    // package imports4458    while (FormatTok->is(Keywords.kw_import)) {4459      NewLine();4460      nextToken();4461      parseVerilogHierarchyIdentifier();4462      if (FormatTok->is(tok::semi))4463        nextToken();4464    }4465 4466    // parameters and ports4467    if (FormatTok->is(Keywords.kw_verilogHash)) {4468      NewLine();4469      nextToken();4470      if (FormatTok->is(tok::l_paren)) {4471        FormatTok->setFinalizedType(TT_VerilogMultiLineListLParen);4472        parseParens();4473      }4474    }4475    if (FormatTok->is(tok::l_paren)) {4476      NewLine();4477      FormatTok->setFinalizedType(TT_VerilogMultiLineListLParen);4478      parseParens();4479    }4480 4481    // extends and implements4482    if (FormatTok->is(Keywords.kw_extends)) {4483      NewLine();4484      nextToken();4485      parseVerilogHierarchyIdentifier();4486      if (FormatTok->is(tok::l_paren))4487        parseParens();4488    }4489    if (FormatTok->is(Keywords.kw_implements)) {4490      NewLine();4491      do {4492        nextToken();4493        parseVerilogHierarchyIdentifier();4494      } while (FormatTok->is(tok::comma));4495    }4496 4497    // Coverage event for cover groups.4498    if (FormatTok->is(tok::at)) {4499      NewLine();4500      parseVerilogSensitivityList();4501    }4502 4503    if (FormatTok->is(tok::semi))4504      nextToken(/*LevelDifference=*/1);4505    addUnwrappedLine();4506  }4507 4508  return AddLevels;4509}4510 4511void UnwrappedLineParser::parseVerilogTable() {4512  assert(FormatTok->is(Keywords.kw_table));4513  nextToken(/*LevelDifference=*/1);4514  addUnwrappedLine();4515 4516  auto InitialLevel = Line->Level++;4517  while (!eof() && !Keywords.isVerilogEnd(*FormatTok)) {4518    FormatToken *Tok = FormatTok;4519    nextToken();4520    if (Tok->is(tok::semi))4521      addUnwrappedLine();4522    else if (Tok->isOneOf(tok::star, tok::colon, tok::question, tok::minus))4523      Tok->setFinalizedType(TT_VerilogTableItem);4524  }4525  Line->Level = InitialLevel;4526  nextToken(/*LevelDifference=*/-1);4527  addUnwrappedLine();4528}4529 4530void UnwrappedLineParser::parseVerilogCaseLabel() {4531  // The label will get unindented in AnnotatingParser. If there are no leading4532  // spaces, indent the rest here so that things inside the block will be4533  // indented relative to things outside. We don't use parseLabel because we4534  // don't know whether this colon is a label or a ternary expression at this4535  // point.4536  auto OrigLevel = Line->Level;4537  auto FirstLine = CurrentLines->size();4538  if (Line->Level == 0 || (Line->InPPDirective && Line->Level <= 1))4539    ++Line->Level;4540  else if (!Style.IndentCaseBlocks && Keywords.isVerilogBegin(*FormatTok))4541    --Line->Level;4542  parseStructuralElement();4543  // Restore the indentation in both the new line and the line that has the4544  // label.4545  if (CurrentLines->size() > FirstLine)4546    (*CurrentLines)[FirstLine].Level = OrigLevel;4547  Line->Level = OrigLevel;4548}4549 4550void UnwrappedLineParser::parseVerilogExtern() {4551  assert(4552      FormatTok->isOneOf(tok::kw_extern, tok::kw_export, Keywords.kw_import));4553  nextToken();4554  // "DPI-C"4555  if (FormatTok->is(tok::string_literal))4556    nextToken();4557  if (FormatTok->isOneOf(Keywords.kw_context, Keywords.kw_pure))4558    nextToken();4559  if (Keywords.isVerilogIdentifier(*FormatTok))4560    nextToken();4561  if (FormatTok->is(tok::equal))4562    nextToken();4563  if (Keywords.isVerilogHierarchy(*FormatTok))4564    parseVerilogHierarchyHeader();4565}4566 4567bool UnwrappedLineParser::containsExpansion(const UnwrappedLine &Line) const {4568  for (const auto &N : Line.Tokens) {4569    if (N.Tok->MacroCtx)4570      return true;4571    for (const UnwrappedLine &Child : N.Children)4572      if (containsExpansion(Child))4573        return true;4574  }4575  return false;4576}4577 4578void UnwrappedLineParser::addUnwrappedLine(LineLevel AdjustLevel) {4579  if (Line->Tokens.empty())4580    return;4581  LLVM_DEBUG({4582    if (!parsingPPDirective()) {4583      llvm::dbgs() << "Adding unwrapped line:\n";4584      printDebugInfo(*Line);4585    }4586  });4587 4588  // If this line closes a block when in Whitesmiths mode, remember that4589  // information so that the level can be decreased after the line is added.4590  // This has to happen after the addition of the line since the line itself4591  // needs to be indented.4592  bool ClosesWhitesmithsBlock =4593      Line->MatchingOpeningBlockLineIndex != UnwrappedLine::kInvalidIndex &&4594      Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths;4595 4596  // If the current line was expanded from a macro call, we use it to4597  // reconstruct an unwrapped line from the structure of the expanded unwrapped4598  // line and the unexpanded token stream.4599  if (!parsingPPDirective() && !InExpansion && containsExpansion(*Line)) {4600    if (!Reconstruct)4601      Reconstruct.emplace(Line->Level, Unexpanded);4602    Reconstruct->addLine(*Line);4603 4604    // While the reconstructed unexpanded lines are stored in the normal4605    // flow of lines, the expanded lines are stored on the side to be analyzed4606    // in an extra step.4607    CurrentExpandedLines.push_back(std::move(*Line));4608 4609    if (Reconstruct->finished()) {4610      UnwrappedLine Reconstructed = std::move(*Reconstruct).takeResult();4611      assert(!Reconstructed.Tokens.empty() &&4612             "Reconstructed must at least contain the macro identifier.");4613      assert(!parsingPPDirective());4614      LLVM_DEBUG({4615        llvm::dbgs() << "Adding unexpanded line:\n";4616        printDebugInfo(Reconstructed);4617      });4618      ExpandedLines[Reconstructed.Tokens.begin()->Tok] = CurrentExpandedLines;4619      Lines.push_back(std::move(Reconstructed));4620      CurrentExpandedLines.clear();4621      Reconstruct.reset();4622    }4623  } else {4624    // At the top level we only get here when no unexpansion is going on, or4625    // when conditional formatting led to unfinished macro reconstructions.4626    assert(!Reconstruct || (CurrentLines != &Lines) || !PPStack.empty());4627    CurrentLines->push_back(std::move(*Line));4628  }4629  Line->Tokens.clear();4630  Line->MatchingOpeningBlockLineIndex = UnwrappedLine::kInvalidIndex;4631  Line->FirstStartColumn = 0;4632  Line->IsContinuation = false;4633  Line->SeenDecltypeAuto = false;4634 4635  if (ClosesWhitesmithsBlock && AdjustLevel == LineLevel::Remove)4636    --Line->Level;4637  if (!parsingPPDirective() && !PreprocessorDirectives.empty()) {4638    CurrentLines->append(4639        std::make_move_iterator(PreprocessorDirectives.begin()),4640        std::make_move_iterator(PreprocessorDirectives.end()));4641    PreprocessorDirectives.clear();4642  }4643  // Disconnect the current token from the last token on the previous line.4644  FormatTok->Previous = nullptr;4645}4646 4647bool UnwrappedLineParser::eof() const { return FormatTok->is(tok::eof); }4648 4649bool UnwrappedLineParser::isOnNewLine(const FormatToken &FormatTok) {4650  return (Line->InPPDirective || FormatTok.HasUnescapedNewline) &&4651         FormatTok.NewlinesBefore > 0;4652}4653 4654// Checks if \p FormatTok is a line comment that continues the line comment4655// section on \p Line.4656static bool4657continuesLineCommentSection(const FormatToken &FormatTok,4658                            const UnwrappedLine &Line, const FormatStyle &Style,4659                            const llvm::Regex &CommentPragmasRegex) {4660  if (Line.Tokens.empty() || Style.ReflowComments != FormatStyle::RCS_Always)4661    return false;4662 4663  StringRef IndentContent = FormatTok.TokenText;4664  if (FormatTok.TokenText.starts_with("//") ||4665      FormatTok.TokenText.starts_with("/*")) {4666    IndentContent = FormatTok.TokenText.substr(2);4667  }4668  if (CommentPragmasRegex.match(IndentContent))4669    return false;4670 4671  // If Line starts with a line comment, then FormatTok continues the comment4672  // section if its original column is greater or equal to the original start4673  // column of the line.4674  //4675  // Define the min column token of a line as follows: if a line ends in '{' or4676  // contains a '{' followed by a line comment, then the min column token is4677  // that '{'. Otherwise, the min column token of the line is the first token of4678  // the line.4679  //4680  // If Line starts with a token other than a line comment, then FormatTok4681  // continues the comment section if its original column is greater than the4682  // original start column of the min column token of the line.4683  //4684  // For example, the second line comment continues the first in these cases:4685  //4686  // // first line4687  // // second line4688  //4689  // and:4690  //4691  // // first line4692  //  // second line4693  //4694  // and:4695  //4696  // int i; // first line4697  //  // second line4698  //4699  // and:4700  //4701  // do { // first line4702  //      // second line4703  //   int i;4704  // } while (true);4705  //4706  // and:4707  //4708  // enum {4709  //   a, // first line4710  //    // second line4711  //   b4712  // };4713  //4714  // The second line comment doesn't continue the first in these cases:4715  //4716  //   // first line4717  //  // second line4718  //4719  // and:4720  //4721  // int i; // first line4722  // // second line4723  //4724  // and:4725  //4726  // do { // first line4727  //   // second line4728  //   int i;4729  // } while (true);4730  //4731  // and:4732  //4733  // enum {4734  //   a, // first line4735  //   // second line4736  // };4737  const FormatToken *MinColumnToken = Line.Tokens.front().Tok;4738 4739  // Scan for '{//'. If found, use the column of '{' as a min column for line4740  // comment section continuation.4741  const FormatToken *PreviousToken = nullptr;4742  for (const UnwrappedLineNode &Node : Line.Tokens) {4743    if (PreviousToken && PreviousToken->is(tok::l_brace) &&4744        isLineComment(*Node.Tok)) {4745      MinColumnToken = PreviousToken;4746      break;4747    }4748    PreviousToken = Node.Tok;4749 4750    // Grab the last newline preceding a token in this unwrapped line.4751    if (Node.Tok->NewlinesBefore > 0)4752      MinColumnToken = Node.Tok;4753  }4754  if (PreviousToken && PreviousToken->is(tok::l_brace))4755    MinColumnToken = PreviousToken;4756 4757  return continuesLineComment(FormatTok, /*Previous=*/Line.Tokens.back().Tok,4758                              MinColumnToken);4759}4760 4761void UnwrappedLineParser::flushComments(bool NewlineBeforeNext) {4762  bool JustComments = Line->Tokens.empty();4763  for (FormatToken *Tok : CommentsBeforeNextToken) {4764    // Line comments that belong to the same line comment section are put on the4765    // same line since later we might want to reflow content between them.4766    // Additional fine-grained breaking of line comment sections is controlled4767    // by the class BreakableLineCommentSection in case it is desirable to keep4768    // several line comment sections in the same unwrapped line.4769    //4770    // FIXME: Consider putting separate line comment sections as children to the4771    // unwrapped line instead.4772    Tok->ContinuesLineCommentSection =4773        continuesLineCommentSection(*Tok, *Line, Style, CommentPragmasRegex);4774    if (isOnNewLine(*Tok) && JustComments && !Tok->ContinuesLineCommentSection)4775      addUnwrappedLine();4776    pushToken(Tok);4777  }4778  if (NewlineBeforeNext && JustComments)4779    addUnwrappedLine();4780  CommentsBeforeNextToken.clear();4781}4782 4783void UnwrappedLineParser::nextToken(int LevelDifference) {4784  if (eof())4785    return;4786  flushComments(isOnNewLine(*FormatTok));4787  pushToken(FormatTok);4788  FormatToken *Previous = FormatTok;4789  if (!Style.isJavaScript())4790    readToken(LevelDifference);4791  else4792    readTokenWithJavaScriptASI();4793  FormatTok->Previous = Previous;4794  if (Style.isVerilog()) {4795    // Blocks in Verilog can have `begin` and `end` instead of braces.  For4796    // keywords like `begin`, we can't treat them the same as left braces4797    // because some contexts require one of them.  For example structs use4798    // braces and if blocks use keywords, and a left brace can occur in an if4799    // statement, but it is not a block.  For keywords like `end`, we simply4800    // treat them the same as right braces.4801    if (Keywords.isVerilogEnd(*FormatTok))4802      FormatTok->Tok.setKind(tok::r_brace);4803  }4804}4805 4806void UnwrappedLineParser::distributeComments(4807    const ArrayRef<FormatToken *> &Comments, const FormatToken *NextTok) {4808  // Whether or not a line comment token continues a line is controlled by4809  // the method continuesLineCommentSection, with the following caveat:4810  //4811  // Define a trail of Comments to be a nonempty proper postfix of Comments such4812  // that each comment line from the trail is aligned with the next token, if4813  // the next token exists. If a trail exists, the beginning of the maximal4814  // trail is marked as a start of a new comment section.4815  //4816  // For example in this code:4817  //4818  // int a; // line about a4819  //   // line 1 about b4820  //   // line 2 about b4821  //   int b;4822  //4823  // the two lines about b form a maximal trail, so there are two sections, the4824  // first one consisting of the single comment "// line about a" and the4825  // second one consisting of the next two comments.4826  if (Comments.empty())4827    return;4828  bool ShouldPushCommentsInCurrentLine = true;4829  bool HasTrailAlignedWithNextToken = false;4830  unsigned StartOfTrailAlignedWithNextToken = 0;4831  if (NextTok) {4832    // We are skipping the first element intentionally.4833    for (unsigned i = Comments.size() - 1; i > 0; --i) {4834      if (Comments[i]->OriginalColumn == NextTok->OriginalColumn) {4835        HasTrailAlignedWithNextToken = true;4836        StartOfTrailAlignedWithNextToken = i;4837      }4838    }4839  }4840  for (unsigned i = 0, e = Comments.size(); i < e; ++i) {4841    FormatToken *FormatTok = Comments[i];4842    if (HasTrailAlignedWithNextToken && i == StartOfTrailAlignedWithNextToken) {4843      FormatTok->ContinuesLineCommentSection = false;4844    } else {4845      FormatTok->ContinuesLineCommentSection = continuesLineCommentSection(4846          *FormatTok, *Line, Style, CommentPragmasRegex);4847    }4848    if (!FormatTok->ContinuesLineCommentSection &&4849        (isOnNewLine(*FormatTok) || FormatTok->IsFirst)) {4850      ShouldPushCommentsInCurrentLine = false;4851    }4852    if (ShouldPushCommentsInCurrentLine)4853      pushToken(FormatTok);4854    else4855      CommentsBeforeNextToken.push_back(FormatTok);4856  }4857}4858 4859void UnwrappedLineParser::readToken(int LevelDifference) {4860  SmallVector<FormatToken *, 1> Comments;4861  bool PreviousWasComment = false;4862  bool FirstNonCommentOnLine = false;4863  do {4864    FormatTok = Tokens->getNextToken();4865    assert(FormatTok);4866    while (FormatTok->isOneOf(TT_ConflictStart, TT_ConflictEnd,4867                              TT_ConflictAlternative)) {4868      if (FormatTok->is(TT_ConflictStart))4869        conditionalCompilationStart(/*Unreachable=*/false);4870      else if (FormatTok->is(TT_ConflictAlternative))4871        conditionalCompilationAlternative();4872      else if (FormatTok->is(TT_ConflictEnd))4873        conditionalCompilationEnd();4874      FormatTok = Tokens->getNextToken();4875      FormatTok->MustBreakBefore = true;4876      FormatTok->MustBreakBeforeFinalized = true;4877    }4878 4879    auto IsFirstNonCommentOnLine = [](bool FirstNonCommentOnLine,4880                                      const FormatToken &Tok,4881                                      bool PreviousWasComment) {4882      auto IsFirstOnLine = [](const FormatToken &Tok) {4883        return Tok.HasUnescapedNewline || Tok.IsFirst;4884      };4885 4886      // Consider preprocessor directives preceded by block comments as first4887      // on line.4888      if (PreviousWasComment)4889        return FirstNonCommentOnLine || IsFirstOnLine(Tok);4890      return IsFirstOnLine(Tok);4891    };4892 4893    FirstNonCommentOnLine = IsFirstNonCommentOnLine(4894        FirstNonCommentOnLine, *FormatTok, PreviousWasComment);4895    PreviousWasComment = FormatTok->is(tok::comment);4896 4897    while (!Line->InPPDirective && FormatTok->is(tok::hash) &&4898           FirstNonCommentOnLine) {4899      // In Verilog, the backtick is used for macro invocations. In TableGen,4900      // the single hash is used for the paste operator.4901      const auto *Next = Tokens->peekNextToken();4902      if ((Style.isVerilog() && !Keywords.isVerilogPPDirective(*Next)) ||4903          (Style.isTableGen() &&4904           Next->isNoneOf(tok::kw_else, tok::pp_define, tok::pp_ifdef,4905                          tok::pp_ifndef, tok::pp_endif))) {4906        break;4907      }4908      distributeComments(Comments, FormatTok);4909      Comments.clear();4910      // If there is an unfinished unwrapped line, we flush the preprocessor4911      // directives only after that unwrapped line was finished later.4912      bool SwitchToPreprocessorLines = !Line->Tokens.empty();4913      ScopedLineState BlockState(*this, SwitchToPreprocessorLines);4914      assert((LevelDifference >= 0 ||4915              static_cast<unsigned>(-LevelDifference) <= Line->Level) &&4916             "LevelDifference makes Line->Level negative");4917      Line->Level += LevelDifference;4918      // Comments stored before the preprocessor directive need to be output4919      // before the preprocessor directive, at the same level as the4920      // preprocessor directive, as we consider them to apply to the directive.4921      if (Style.IndentPPDirectives == FormatStyle::PPDIS_BeforeHash &&4922          PPBranchLevel > 0) {4923        Line->Level += PPBranchLevel;4924      }4925      assert(Line->Level >= Line->UnbracedBodyLevel);4926      Line->Level -= Line->UnbracedBodyLevel;4927      flushComments(isOnNewLine(*FormatTok));4928      parsePPDirective();4929      PreviousWasComment = FormatTok->is(tok::comment);4930      FirstNonCommentOnLine = IsFirstNonCommentOnLine(4931          FirstNonCommentOnLine, *FormatTok, PreviousWasComment);4932    }4933 4934    if (!PPStack.empty() && (PPStack.back().Kind == PP_Unreachable) &&4935        !Line->InPPDirective) {4936      continue;4937    }4938 4939    if (FormatTok->is(tok::identifier) &&4940        Macros.defined(FormatTok->TokenText) &&4941        // FIXME: Allow expanding macros in preprocessor directives.4942        !Line->InPPDirective) {4943      FormatToken *ID = FormatTok;4944      unsigned Position = Tokens->getPosition();4945 4946      // To correctly parse the code, we need to replace the tokens of the macro4947      // call with its expansion.4948      auto PreCall = std::move(Line);4949      Line.reset(new UnwrappedLine);4950      bool OldInExpansion = InExpansion;4951      InExpansion = true;4952      // We parse the macro call into a new line.4953      auto Args = parseMacroCall();4954      InExpansion = OldInExpansion;4955      assert(Line->Tokens.front().Tok == ID);4956      // And remember the unexpanded macro call tokens.4957      auto UnexpandedLine = std::move(Line);4958      // Reset to the old line.4959      Line = std::move(PreCall);4960 4961      LLVM_DEBUG({4962        llvm::dbgs() << "Macro call: " << ID->TokenText << "(";4963        if (Args) {4964          llvm::dbgs() << "(";4965          for (const auto &Arg : Args.value())4966            for (const auto &T : Arg)4967              llvm::dbgs() << T->TokenText << " ";4968          llvm::dbgs() << ")";4969        }4970        llvm::dbgs() << "\n";4971      });4972      if (Macros.objectLike(ID->TokenText) && Args &&4973          !Macros.hasArity(ID->TokenText, Args->size())) {4974        // The macro is either4975        // - object-like, but we got argumnets, or4976        // - overloaded to be both object-like and function-like, but none of4977        //   the function-like arities match the number of arguments.4978        // Thus, expand as object-like macro.4979        LLVM_DEBUG(llvm::dbgs()4980                   << "Macro \"" << ID->TokenText4981                   << "\" not overloaded for arity " << Args->size()4982                   << "or not function-like, using object-like overload.");4983        Args.reset();4984        UnexpandedLine->Tokens.resize(1);4985        Tokens->setPosition(Position);4986        nextToken();4987        assert(!Args && Macros.objectLike(ID->TokenText));4988      }4989      if ((!Args && Macros.objectLike(ID->TokenText)) ||4990          (Args && Macros.hasArity(ID->TokenText, Args->size()))) {4991        // Next, we insert the expanded tokens in the token stream at the4992        // current position, and continue parsing.4993        Unexpanded[ID] = std::move(UnexpandedLine);4994        SmallVector<FormatToken *, 8> Expansion =4995            Macros.expand(ID, std::move(Args));4996        if (!Expansion.empty())4997          FormatTok = Tokens->insertTokens(Expansion);4998 4999        LLVM_DEBUG({5000          llvm::dbgs() << "Expanded: ";5001          for (const auto &T : Expansion)5002            llvm::dbgs() << T->TokenText << " ";5003          llvm::dbgs() << "\n";5004        });5005      } else {5006        LLVM_DEBUG({5007          llvm::dbgs() << "Did not expand macro \"" << ID->TokenText5008                       << "\", because it was used ";5009          if (Args)5010            llvm::dbgs() << "with " << Args->size();5011          else5012            llvm::dbgs() << "without";5013          llvm::dbgs() << " arguments, which doesn't match any definition.\n";5014        });5015        Tokens->setPosition(Position);5016        FormatTok = ID;5017      }5018    }5019 5020    if (FormatTok->isNot(tok::comment)) {5021      distributeComments(Comments, FormatTok);5022      Comments.clear();5023      return;5024    }5025 5026    Comments.push_back(FormatTok);5027  } while (!eof());5028 5029  distributeComments(Comments, nullptr);5030  Comments.clear();5031}5032 5033namespace {5034template <typename Iterator>5035void pushTokens(Iterator Begin, Iterator End,5036                SmallVectorImpl<FormatToken *> &Into) {5037  for (auto I = Begin; I != End; ++I) {5038    Into.push_back(I->Tok);5039    for (const auto &Child : I->Children)5040      pushTokens(Child.Tokens.begin(), Child.Tokens.end(), Into);5041  }5042}5043} // namespace5044 5045std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>>5046UnwrappedLineParser::parseMacroCall() {5047  std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>> Args;5048  assert(Line->Tokens.empty());5049  nextToken();5050  if (FormatTok->isNot(tok::l_paren))5051    return Args;5052  unsigned Position = Tokens->getPosition();5053  FormatToken *Tok = FormatTok;5054  nextToken();5055  Args.emplace();5056  auto ArgStart = std::prev(Line->Tokens.end());5057 5058  int Parens = 0;5059  do {5060    switch (FormatTok->Tok.getKind()) {5061    case tok::l_paren:5062      ++Parens;5063      nextToken();5064      break;5065    case tok::r_paren: {5066      if (Parens > 0) {5067        --Parens;5068        nextToken();5069        break;5070      }5071      Args->push_back({});5072      pushTokens(std::next(ArgStart), Line->Tokens.end(), Args->back());5073      nextToken();5074      return Args;5075    }5076    case tok::comma: {5077      if (Parens > 0) {5078        nextToken();5079        break;5080      }5081      Args->push_back({});5082      pushTokens(std::next(ArgStart), Line->Tokens.end(), Args->back());5083      nextToken();5084      ArgStart = std::prev(Line->Tokens.end());5085      break;5086    }5087    default:5088      nextToken();5089      break;5090    }5091  } while (!eof());5092  Line->Tokens.resize(1);5093  Tokens->setPosition(Position);5094  FormatTok = Tok;5095  return {};5096}5097 5098void UnwrappedLineParser::pushToken(FormatToken *Tok) {5099  Line->Tokens.push_back(UnwrappedLineNode(Tok));5100  if (AtEndOfPPLine) {5101    auto &Tok = *Line->Tokens.back().Tok;5102    Tok.MustBreakBefore = true;5103    Tok.MustBreakBeforeFinalized = true;5104    Tok.FirstAfterPPLine = true;5105    AtEndOfPPLine = false;5106  }5107}5108 5109} // end namespace format5110} // end namespace clang5111