brintos

brintos / llvm-project-archived public Read only

0
0
Text · 247.1 KiB · 79cfa73 Raw
6582 lines · cpp
1//===--- TokenAnnotator.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 implements a token annotator, i.e. creates11/// \c AnnotatedTokens out of \c FormatTokens with required extra information.12///13//===----------------------------------------------------------------------===//14 15#include "TokenAnnotator.h"16#include "FormatToken.h"17#include "clang/Basic/TokenKinds.h"18#include "llvm/ADT/SmallPtrSet.h"19#include "llvm/Support/Debug.h"20 21#define DEBUG_TYPE "format-token-annotator"22 23namespace clang {24namespace format {25 26static bool mustBreakAfterAttributes(const FormatToken &Tok,27                                     const FormatStyle &Style) {28  switch (Style.BreakAfterAttributes) {29  case FormatStyle::ABS_Always:30    return true;31  case FormatStyle::ABS_Leave:32    return Tok.NewlinesBefore > 0;33  default:34    return false;35  }36}37 38namespace {39 40/// Returns \c true if the line starts with a token that can start a statement41/// with an initializer.42static bool startsWithInitStatement(const AnnotatedLine &Line) {43  return Line.startsWith(tok::kw_for) || Line.startsWith(tok::kw_if) ||44         Line.startsWith(tok::kw_switch);45}46 47/// Returns \c true if the token can be used as an identifier in48/// an Objective-C \c \@selector, \c false otherwise.49///50/// Because getFormattingLangOpts() always lexes source code as51/// Objective-C++, C++ keywords like \c new and \c delete are52/// lexed as tok::kw_*, not tok::identifier, even for Objective-C.53///54/// For Objective-C and Objective-C++, both identifiers and keywords55/// are valid inside @selector(...) (or a macro which56/// invokes @selector(...)). So, we allow treat any identifier or57/// keyword as a potential Objective-C selector component.58static bool canBeObjCSelectorComponent(const FormatToken &Tok) {59  return Tok.Tok.getIdentifierInfo();60}61 62/// With `Left` being '(', check if we're at either `[...](` or63/// `[...]<...>(`, where the [ opens a lambda capture list.64// FIXME: this doesn't cover attributes/constraints before the l_paren.65static bool isLambdaParameterList(const FormatToken *Left) {66  // Skip <...> if present.67  if (Left->Previous && Left->Previous->is(tok::greater) &&68      Left->Previous->MatchingParen &&69      Left->Previous->MatchingParen->is(TT_TemplateOpener)) {70    Left = Left->Previous->MatchingParen;71  }72 73  // Check for `[...]`.74  return Left->Previous && Left->Previous->is(tok::r_square) &&75         Left->Previous->MatchingParen &&76         Left->Previous->MatchingParen->is(TT_LambdaLSquare);77}78 79/// Returns \c true if the token is followed by a boolean condition, \c false80/// otherwise.81static bool isKeywordWithCondition(const FormatToken &Tok) {82  return Tok.isOneOf(tok::kw_if, tok::kw_for, tok::kw_while, tok::kw_switch,83                     tok::kw_constexpr, tok::kw_catch);84}85 86/// Returns \c true if the token starts a C++ attribute, \c false otherwise.87static bool isCppAttribute(bool IsCpp, const FormatToken &Tok) {88  if (!IsCpp || !Tok.startsSequence(tok::l_square, tok::l_square))89    return false;90  // The first square bracket is part of an ObjC array literal91  if (Tok.Previous && Tok.Previous->is(tok::at))92    return false;93  const FormatToken *AttrTok = Tok.Next->Next;94  if (!AttrTok)95    return false;96  // C++17 '[[using ns: foo, bar(baz, blech)]]'97  // We assume nobody will name an ObjC variable 'using'.98  if (AttrTok->startsSequence(tok::kw_using, tok::identifier, tok::colon))99    return true;100  if (AttrTok->isNot(tok::identifier))101    return false;102  while (AttrTok && !AttrTok->startsSequence(tok::r_square, tok::r_square)) {103    // ObjC message send. We assume nobody will use : in a C++11 attribute104    // specifier parameter, although this is technically valid:105    // [[foo(:)]].106    if (AttrTok->is(tok::colon) ||107        AttrTok->startsSequence(tok::identifier, tok::identifier) ||108        AttrTok->startsSequence(tok::r_paren, tok::identifier)) {109      return false;110    }111    if (AttrTok->is(tok::ellipsis))112      return true;113    AttrTok = AttrTok->Next;114  }115  return AttrTok && AttrTok->startsSequence(tok::r_square, tok::r_square);116}117 118/// A parser that gathers additional information about tokens.119///120/// The \c TokenAnnotator tries to match parenthesis and square brakets and121/// store a parenthesis levels. It also tries to resolve matching "<" and ">"122/// into template parameter lists.123class AnnotatingParser {124public:125  AnnotatingParser(const FormatStyle &Style, AnnotatedLine &Line,126                   const AdditionalKeywords &Keywords,127                   SmallVector<ScopeType> &Scopes)128      : Style(Style), Line(Line), CurrentToken(Line.First), AutoFound(false),129        IsCpp(Style.isCpp()), LangOpts(getFormattingLangOpts(Style)),130        Keywords(Keywords), Scopes(Scopes), TemplateDeclarationDepth(0) {131    Contexts.push_back(Context(tok::unknown, 1, /*IsExpression=*/false));132    resetTokenMetadata();133  }134 135private:136  ScopeType getScopeType(const FormatToken &Token) const {137    switch (Token.getType()) {138    case TT_ClassLBrace:139    case TT_StructLBrace:140    case TT_UnionLBrace:141      return ST_Class;142    case TT_CompoundRequirementLBrace:143      return ST_CompoundRequirement;144    default:145      return ST_Other;146    }147  }148 149  bool parseAngle() {150    if (!CurrentToken)151      return false;152 153    auto *Left = CurrentToken->Previous; // The '<'.154    if (!Left)155      return false;156 157    if (NonTemplateLess.count(Left) > 0)158      return false;159 160    const auto *BeforeLess = Left->Previous;161 162    if (BeforeLess) {163      if (BeforeLess->Tok.isLiteral())164        return false;165      if (BeforeLess->is(tok::r_brace))166        return false;167      if (BeforeLess->is(tok::r_paren) && Contexts.size() > 1 &&168          !(BeforeLess->MatchingParen &&169            BeforeLess->MatchingParen->is(TT_OverloadedOperatorLParen))) {170        return false;171      }172      if (BeforeLess->is(tok::kw_operator) && CurrentToken->is(tok::l_paren))173        return false;174    }175 176    Left->ParentBracket = Contexts.back().ContextKind;177    ScopedContextCreator ContextCreator(*this, tok::less, 12);178    Contexts.back().IsExpression = false;179 180    // If there's a template keyword before the opening angle bracket, this is a181    // template parameter, not an argument.182    if (BeforeLess && BeforeLess->isNot(tok::kw_template))183      Contexts.back().ContextType = Context::TemplateArgument;184 185    if (Style.isJava() && CurrentToken->is(tok::question))186      next();187 188    for (bool SeenTernaryOperator = false, MaybeAngles = true; CurrentToken;) {189      const bool InExpr = Contexts[Contexts.size() - 2].IsExpression;190      if (CurrentToken->is(tok::greater)) {191        const auto *Next = CurrentToken->Next;192        if (CurrentToken->isNot(TT_TemplateCloser)) {193          // Try to do a better job at looking for ">>" within the condition of194          // a statement. Conservatively insert spaces between consecutive ">"195          // tokens to prevent splitting right shift operators and potentially196          // altering program semantics. This check is overly conservative and197          // will prevent spaces from being inserted in select nested template198          // parameter cases, but should not alter program semantics.199          if (Next && Next->is(tok::greater) &&200              Left->ParentBracket != tok::less &&201              CurrentToken->getStartOfNonWhitespace() ==202                  Next->getStartOfNonWhitespace().getLocWithOffset(-1)) {203            return false;204          }205          if (InExpr && SeenTernaryOperator &&206              (!Next || Next->isNoneOf(tok::l_paren, tok::l_brace))) {207            return false;208          }209          if (!MaybeAngles)210            return false;211        }212        Left->MatchingParen = CurrentToken;213        CurrentToken->MatchingParen = Left;214        // In TT_Proto, we must distignuish between:215        //   map<key, value>216        //   msg < item: data >217        //   msg: < item: data >218        // In TT_TextProto, map<key, value> does not occur.219        if (Style.isTextProto() ||220            (Style.Language == FormatStyle::LK_Proto && BeforeLess &&221             BeforeLess->isOneOf(TT_SelectorName, TT_DictLiteral))) {222          CurrentToken->setType(TT_DictLiteral);223        } else {224          CurrentToken->setType(TT_TemplateCloser);225          CurrentToken->Tok.setLength(1);226        }227        if (Next && Next->Tok.isLiteral())228          return false;229        next();230        return true;231      }232      if (BeforeLess && BeforeLess->is(TT_TemplateName)) {233        next();234        continue;235      }236      if (CurrentToken->is(tok::question) && Style.isJava()) {237        next();238        continue;239      }240      if (CurrentToken->isOneOf(tok::r_paren, tok::r_square, tok::r_brace))241        return false;242      const auto &Prev = *CurrentToken->Previous;243      // If a && or || is found and interpreted as a binary operator, this set244      // of angles is likely part of something like "a < b && c > d". If the245      // angles are inside an expression, the ||/&& might also be a binary246      // operator that was misinterpreted because we are parsing template247      // parameters.248      // FIXME: This is getting out of hand, write a decent parser.249      if (MaybeAngles && InExpr && !Line.startsWith(tok::kw_template) &&250          Prev.is(TT_BinaryOperator) &&251          Prev.isOneOf(tok::pipepipe, tok::ampamp)) {252        MaybeAngles = false;253      }254      if (Prev.isOneOf(tok::question, tok::colon) && !Style.isProto())255        SeenTernaryOperator = true;256      updateParameterCount(Left, CurrentToken);257      if (Style.Language == FormatStyle::LK_Proto) {258        if (FormatToken *Previous = CurrentToken->getPreviousNonComment()) {259          if (CurrentToken->is(tok::colon) ||260              (CurrentToken->isOneOf(tok::l_brace, tok::less) &&261               Previous->isNot(tok::colon))) {262            Previous->setType(TT_SelectorName);263          }264        }265      } else if (Style.isTableGen()) {266        if (CurrentToken->isOneOf(tok::comma, tok::equal)) {267          // They appear as separators. Unless they are not in class definition.268          next();269          continue;270        }271        // In angle, there must be Value like tokens. Types are also able to be272        // parsed in the same way with Values.273        if (!parseTableGenValue())274          return false;275        continue;276      }277      if (!consumeToken())278        return false;279    }280    return false;281  }282 283  bool parseUntouchableParens() {284    while (CurrentToken) {285      CurrentToken->Finalized = true;286      switch (CurrentToken->Tok.getKind()) {287      case tok::l_paren:288        next();289        if (!parseUntouchableParens())290          return false;291        continue;292      case tok::r_paren:293        next();294        return true;295      default:296        // no-op297        break;298      }299      next();300    }301    return false;302  }303 304  bool parseParens(bool IsIf = false) {305    if (!CurrentToken)306      return false;307    assert(CurrentToken->Previous && "Unknown previous token");308    FormatToken &OpeningParen = *CurrentToken->Previous;309    assert(OpeningParen.is(tok::l_paren));310    FormatToken *PrevNonComment = OpeningParen.getPreviousNonComment();311    OpeningParen.ParentBracket = Contexts.back().ContextKind;312    ScopedContextCreator ContextCreator(*this, tok::l_paren, 1);313 314    // FIXME: This is a bit of a hack. Do better.315    Contexts.back().ColonIsForRangeExpr =316        Contexts.size() == 2 && Contexts[0].ColonIsForRangeExpr;317 318    if (OpeningParen.Previous &&319        OpeningParen.Previous->is(TT_UntouchableMacroFunc)) {320      OpeningParen.Finalized = true;321      return parseUntouchableParens();322    }323 324    bool StartsObjCSelector = false;325    if (!Style.isVerilog()) {326      if (FormatToken *MaybeSel = OpeningParen.Previous) {327        // @selector( starts a selector.328        if (MaybeSel->is(tok::objc_selector) && MaybeSel->Previous &&329            MaybeSel->Previous->is(tok::at)) {330          StartsObjCSelector = true;331        }332      }333    }334 335    if (OpeningParen.is(TT_OverloadedOperatorLParen)) {336      // Find the previous kw_operator token.337      FormatToken *Prev = &OpeningParen;338      while (Prev->isNot(tok::kw_operator)) {339        Prev = Prev->Previous;340        assert(Prev && "Expect a kw_operator prior to the OperatorLParen!");341      }342 343      // If faced with "a.operator*(argument)" or "a->operator*(argument)",344      // i.e. the operator is called as a member function,345      // then the argument must be an expression.346      bool OperatorCalledAsMemberFunction =347          Prev->Previous && Prev->Previous->isOneOf(tok::period, tok::arrow);348      Contexts.back().IsExpression = OperatorCalledAsMemberFunction;349    } else if (OpeningParen.is(TT_VerilogInstancePortLParen)) {350      Contexts.back().IsExpression = true;351      Contexts.back().ContextType = Context::VerilogInstancePortList;352    } else if (Style.isJavaScript() &&353               (Line.startsWith(Keywords.kw_type, tok::identifier) ||354                Line.startsWith(tok::kw_export, Keywords.kw_type,355                                tok::identifier))) {356      // type X = (...);357      // export type X = (...);358      Contexts.back().IsExpression = false;359    } else if (OpeningParen.Previous &&360               (OpeningParen.Previous->isOneOf(361                    tok::kw_noexcept, tok::kw_explicit, tok::kw_while,362                    tok::l_paren, tok::comma, TT_CastRParen,363                    TT_BinaryOperator) ||364                OpeningParen.Previous->isIf())) {365      // if and while usually contain expressions.366      Contexts.back().IsExpression = true;367    } else if (Style.isJavaScript() && OpeningParen.Previous &&368               (OpeningParen.Previous->is(Keywords.kw_function) ||369                (OpeningParen.Previous->endsSequence(tok::identifier,370                                                     Keywords.kw_function)))) {371      // function(...) or function f(...)372      Contexts.back().IsExpression = false;373    } else if (Style.isJavaScript() && OpeningParen.Previous &&374               OpeningParen.Previous->is(TT_JsTypeColon)) {375      // let x: (SomeType);376      Contexts.back().IsExpression = false;377    } else if (isLambdaParameterList(&OpeningParen)) {378      // This is a parameter list of a lambda expression.379      OpeningParen.setType(TT_LambdaDefinitionLParen);380      Contexts.back().IsExpression = false;381    } else if (OpeningParen.is(TT_RequiresExpressionLParen)) {382      Contexts.back().IsExpression = false;383    } else if (OpeningParen.Previous &&384               OpeningParen.Previous->is(tok::kw__Generic)) {385      Contexts.back().ContextType = Context::C11GenericSelection;386      Contexts.back().IsExpression = true;387    } else if (OpeningParen.Previous &&388               OpeningParen.Previous->TokenText == "Q_PROPERTY") {389      Contexts.back().ContextType = Context::QtProperty;390      Contexts.back().IsExpression = false;391    } else if (Line.InPPDirective &&392               (!OpeningParen.Previous ||393                OpeningParen.Previous->isNot(tok::identifier))) {394      Contexts.back().IsExpression = true;395    } else if (Contexts[Contexts.size() - 2].CaretFound) {396      // This is the parameter list of an ObjC block.397      Contexts.back().IsExpression = false;398    } else if (OpeningParen.Previous &&399               OpeningParen.Previous->is(TT_ForEachMacro)) {400      // The first argument to a foreach macro is a declaration.401      Contexts.back().ContextType = Context::ForEachMacro;402      Contexts.back().IsExpression = false;403    } else if (OpeningParen.Previous && OpeningParen.Previous->MatchingParen &&404               OpeningParen.Previous->MatchingParen->isOneOf(405                   TT_ObjCBlockLParen, TT_FunctionTypeLParen)) {406      Contexts.back().IsExpression = false;407    } else if (!Line.MustBeDeclaration &&408               (!Line.InPPDirective || (Line.InMacroBody && !Scopes.empty()))) {409      bool IsForOrCatch =410          OpeningParen.Previous &&411          OpeningParen.Previous->isOneOf(tok::kw_for, tok::kw_catch);412      Contexts.back().IsExpression = !IsForOrCatch;413    }414 415    if (Style.isTableGen()) {416      if (FormatToken *Prev = OpeningParen.Previous) {417        if (Prev->is(TT_TableGenCondOperator)) {418          Contexts.back().IsTableGenCondOpe = true;419          Contexts.back().IsExpression = true;420        } else if (Contexts.size() > 1 &&421                   Contexts[Contexts.size() - 2].IsTableGenBangOpe) {422          // Hack to handle bang operators. The parent context's flag423          // was set by parseTableGenSimpleValue().424          // We have to specify the context outside because the prev of "(" may425          // be ">", not the bang operator in this case.426          Contexts.back().IsTableGenBangOpe = true;427          Contexts.back().IsExpression = true;428        } else {429          // Otherwise, this paren seems DAGArg.430          if (!parseTableGenDAGArg())431            return false;432          return parseTableGenDAGArgAndList(&OpeningParen);433        }434      }435    }436 437    // Infer the role of the l_paren based on the previous token if we haven't438    // detected one yet.439    if (PrevNonComment && OpeningParen.is(TT_Unknown)) {440      if (PrevNonComment->isAttribute()) {441        OpeningParen.setType(TT_AttributeLParen);442      } else if (PrevNonComment->isOneOf(TT_TypenameMacro, tok::kw_decltype,443                                         tok::kw_typeof,444#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) tok::kw___##Trait,445#include "clang/Basic/TransformTypeTraits.def"446                                         tok::kw__Atomic)) {447        OpeningParen.setType(TT_TypeDeclarationParen);448        // decltype() and typeof() usually contain expressions.449        if (PrevNonComment->isOneOf(tok::kw_decltype, tok::kw_typeof))450          Contexts.back().IsExpression = true;451      }452    }453 454    if (StartsObjCSelector)455      OpeningParen.setType(TT_ObjCSelector);456 457    const bool IsStaticAssert =458        PrevNonComment && PrevNonComment->is(tok::kw_static_assert);459    if (IsStaticAssert)460      Contexts.back().InStaticAssertFirstArgument = true;461 462    // MightBeFunctionType and ProbablyFunctionType are used for463    // function pointer and reference types as well as Objective-C464    // block types:465    //466    // void (*FunctionPointer)(void);467    // void (&FunctionReference)(void);468    // void (&&FunctionReference)(void);469    // void (^ObjCBlock)(void);470    bool MightBeFunctionType = !Contexts[Contexts.size() - 2].IsExpression;471    bool ProbablyFunctionType =472        CurrentToken->isPointerOrReference() || CurrentToken->is(tok::caret);473    bool HasMultipleLines = false;474    bool HasMultipleParametersOnALine = false;475    bool MightBeObjCForRangeLoop =476        OpeningParen.Previous && OpeningParen.Previous->is(tok::kw_for);477    FormatToken *PossibleObjCForInToken = nullptr;478    while (CurrentToken) {479      const auto &Prev = *CurrentToken->Previous;480      const auto *PrevPrev = Prev.Previous;481      if (Prev.is(TT_PointerOrReference) &&482          PrevPrev->isOneOf(tok::l_paren, tok::coloncolon)) {483        ProbablyFunctionType = true;484      }485      if (CurrentToken->is(tok::comma))486        MightBeFunctionType = false;487      if (Prev.is(TT_BinaryOperator))488        Contexts.back().IsExpression = true;489      if (CurrentToken->is(tok::r_paren)) {490        if (Prev.is(TT_PointerOrReference) &&491            (PrevPrev == &OpeningParen || PrevPrev->is(tok::coloncolon))) {492          MightBeFunctionType = true;493        }494        if (OpeningParen.isNot(TT_CppCastLParen) && MightBeFunctionType &&495            ProbablyFunctionType && CurrentToken->Next &&496            (CurrentToken->Next->is(tok::l_paren) ||497             (CurrentToken->Next->is(tok::l_square) &&498              (Line.MustBeDeclaration ||499               (PrevNonComment && PrevNonComment->isTypeName(LangOpts)))))) {500          OpeningParen.setType(OpeningParen.Next->is(tok::caret)501                                   ? TT_ObjCBlockLParen502                                   : TT_FunctionTypeLParen);503        }504        OpeningParen.MatchingParen = CurrentToken;505        CurrentToken->MatchingParen = &OpeningParen;506 507        if (CurrentToken->Next && CurrentToken->Next->is(tok::l_brace) &&508            OpeningParen.Previous && OpeningParen.Previous->is(tok::l_paren)) {509          // Detect the case where macros are used to generate lambdas or510          // function bodies, e.g.:511          //   auto my_lambda = MACRO((Type *type, int i) { .. body .. });512          for (FormatToken *Tok = &OpeningParen; Tok != CurrentToken;513               Tok = Tok->Next) {514            if (Tok->is(TT_BinaryOperator) && Tok->isPointerOrReference())515              Tok->setType(TT_PointerOrReference);516          }517        }518 519        if (StartsObjCSelector) {520          CurrentToken->setType(TT_ObjCSelector);521          if (Contexts.back().FirstObjCSelectorName) {522            Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =523                Contexts.back().LongestObjCSelectorName;524          }525        }526 527        if (OpeningParen.is(TT_AttributeLParen))528          CurrentToken->setType(TT_AttributeRParen);529        if (OpeningParen.is(TT_TypeDeclarationParen))530          CurrentToken->setType(TT_TypeDeclarationParen);531        if (OpeningParen.Previous &&532            OpeningParen.Previous->is(TT_JavaAnnotation)) {533          CurrentToken->setType(TT_JavaAnnotation);534        }535        if (OpeningParen.Previous &&536            OpeningParen.Previous->is(TT_LeadingJavaAnnotation)) {537          CurrentToken->setType(TT_LeadingJavaAnnotation);538        }539 540        if (!HasMultipleLines)541          OpeningParen.setPackingKind(PPK_Inconclusive);542        else if (HasMultipleParametersOnALine)543          OpeningParen.setPackingKind(PPK_BinPacked);544        else545          OpeningParen.setPackingKind(PPK_OnePerLine);546 547        next();548        return true;549      }550      if (CurrentToken->isOneOf(tok::r_square, tok::r_brace))551        return false;552 553      if (CurrentToken->is(tok::l_brace) && OpeningParen.is(TT_ObjCBlockLParen))554        OpeningParen.setType(TT_Unknown);555      if (CurrentToken->is(tok::comma) && CurrentToken->Next &&556          !CurrentToken->Next->HasUnescapedNewline &&557          !CurrentToken->Next->isTrailingComment()) {558        HasMultipleParametersOnALine = true;559      }560      bool ProbablyFunctionTypeLParen =561          (CurrentToken->is(tok::l_paren) && CurrentToken->Next &&562           CurrentToken->Next->isOneOf(tok::star, tok::amp, tok::caret));563      if ((Prev.isOneOf(tok::kw_const, tok::kw_auto) ||564           Prev.isTypeName(LangOpts)) &&565          !(CurrentToken->is(tok::l_brace) ||566            (CurrentToken->is(tok::l_paren) && !ProbablyFunctionTypeLParen))) {567        Contexts.back().IsExpression = false;568      }569      if (CurrentToken->isOneOf(tok::semi, tok::colon)) {570        MightBeObjCForRangeLoop = false;571        if (PossibleObjCForInToken) {572          PossibleObjCForInToken->setType(TT_Unknown);573          PossibleObjCForInToken = nullptr;574        }575      }576      if (IsIf && CurrentToken->is(tok::semi)) {577        for (auto *Tok = OpeningParen.Next;578             Tok != CurrentToken &&579             Tok->isNoneOf(tok::equal, tok::l_paren, tok::l_brace);580             Tok = Tok->Next) {581          if (Tok->isPointerOrReference())582            Tok->setFinalizedType(TT_PointerOrReference);583        }584      }585      if (MightBeObjCForRangeLoop && CurrentToken->is(Keywords.kw_in)) {586        PossibleObjCForInToken = CurrentToken;587        PossibleObjCForInToken->setType(TT_ObjCForIn);588      }589      // When we discover a 'new', we set CanBeExpression to 'false' in order to590      // parse the type correctly. Reset that after a comma.591      if (CurrentToken->is(tok::comma)) {592        if (IsStaticAssert)593          Contexts.back().InStaticAssertFirstArgument = false;594        else595          Contexts.back().CanBeExpression = true;596      }597 598      if (Style.isTableGen()) {599        if (CurrentToken->is(tok::comma)) {600          if (Contexts.back().IsTableGenCondOpe)601            CurrentToken->setType(TT_TableGenCondOperatorComma);602          next();603        } else if (CurrentToken->is(tok::colon)) {604          if (Contexts.back().IsTableGenCondOpe)605            CurrentToken->setType(TT_TableGenCondOperatorColon);606          next();607        }608        // In TableGen there must be Values in parens.609        if (!parseTableGenValue())610          return false;611        continue;612      }613 614      FormatToken *Tok = CurrentToken;615      if (!consumeToken())616        return false;617      updateParameterCount(&OpeningParen, Tok);618      if (CurrentToken && CurrentToken->HasUnescapedNewline)619        HasMultipleLines = true;620    }621    return false;622  }623 624  bool isCSharpAttributeSpecifier(const FormatToken &Tok) {625    if (!Style.isCSharp())626      return false;627 628    // `identifier[i]` is not an attribute.629    if (Tok.Previous && Tok.Previous->is(tok::identifier))630      return false;631 632    // Chains of [] in `identifier[i][j][k]` are not attributes.633    if (Tok.Previous && Tok.Previous->is(tok::r_square)) {634      auto *MatchingParen = Tok.Previous->MatchingParen;635      if (!MatchingParen || MatchingParen->is(TT_ArraySubscriptLSquare))636        return false;637    }638 639    const FormatToken *AttrTok = Tok.Next;640    if (!AttrTok)641      return false;642 643    // Just an empty declaration e.g. string [].644    if (AttrTok->is(tok::r_square))645      return false;646 647    // Move along the tokens inbetween the '[' and ']' e.g. [STAThread].648    while (AttrTok && AttrTok->isNot(tok::r_square))649      AttrTok = AttrTok->Next;650 651    if (!AttrTok)652      return false;653 654    // Allow an attribute to be the only content of a file.655    AttrTok = AttrTok->Next;656    if (!AttrTok)657      return true;658 659    // Limit this to being an access modifier that follows.660    if (AttrTok->isAccessSpecifierKeyword() ||661        AttrTok->isOneOf(tok::comment, tok::kw_class, tok::kw_static,662                         tok::l_square, Keywords.kw_internal)) {663      return true;664    }665 666    // incase its a [XXX] retval func(....667    if (AttrTok->Next &&668        AttrTok->Next->startsSequence(tok::identifier, tok::l_paren)) {669      return true;670    }671 672    return false;673  }674 675  bool parseSquare() {676    if (!CurrentToken)677      return false;678 679    // A '[' could be an index subscript (after an identifier or after680    // ')' or ']'), it could be the start of an Objective-C method681    // expression, it could the start of an Objective-C array literal,682    // or it could be a C++ attribute specifier [[foo::bar]].683    FormatToken *Left = CurrentToken->Previous;684    Left->ParentBracket = Contexts.back().ContextKind;685    FormatToken *Parent = Left->getPreviousNonComment();686 687    // Cases where '>' is followed by '['.688    // In C++, this can happen either in array of templates (foo<int>[10])689    // or when array is a nested template type (unique_ptr<type1<type2>[]>).690    bool CppArrayTemplates =691        IsCpp && Parent && Parent->is(TT_TemplateCloser) &&692        (Contexts.back().CanBeExpression || Contexts.back().IsExpression ||693         Contexts.back().ContextType == Context::TemplateArgument);694 695    const bool IsInnerSquare = Contexts.back().InCpp11AttributeSpecifier;696    const bool IsCpp11AttributeSpecifier =697        isCppAttribute(IsCpp, *Left) || IsInnerSquare;698 699    // Treat C# Attributes [STAThread] much like C++ attributes [[...]].700    bool IsCSharpAttributeSpecifier =701        isCSharpAttributeSpecifier(*Left) ||702        Contexts.back().InCSharpAttributeSpecifier;703 704    bool InsideInlineASM = Line.startsWith(tok::kw_asm);705    bool IsCppStructuredBinding = Left->isCppStructuredBinding(IsCpp);706    bool StartsObjCMethodExpr =707        !IsCppStructuredBinding && !InsideInlineASM && !CppArrayTemplates &&708        IsCpp && !IsCpp11AttributeSpecifier && !IsCSharpAttributeSpecifier &&709        Contexts.back().CanBeExpression && Left->isNot(TT_LambdaLSquare) &&710        CurrentToken->isNoneOf(tok::l_brace, tok::r_square) &&711        // Do not consider '[' after a comma inside a braced initializer the712        // start of an ObjC method expression. In braced initializer lists,713        // commas are list separators and should not trigger ObjC parsing.714        (!Parent || !Parent->is(tok::comma) ||715         Contexts.back().ContextKind != tok::l_brace) &&716        (!Parent ||717         Parent->isOneOf(tok::colon, tok::l_square, tok::l_paren,718                         tok::kw_return, tok::kw_throw) ||719         Parent->isUnaryOperator() ||720         // FIXME(bug 36976): ObjC return types shouldn't use TT_CastRParen.721         Parent->isOneOf(TT_ObjCForIn, TT_CastRParen) ||722         (getBinOpPrecedence(Parent->Tok.getKind(), true, true) >723          prec::Unknown));724    bool ColonFound = false;725 726    unsigned BindingIncrease = 1;727    if (IsCppStructuredBinding) {728      Left->setType(TT_StructuredBindingLSquare);729    } else if (Left->is(TT_Unknown)) {730      if (StartsObjCMethodExpr) {731        Left->setType(TT_ObjCMethodExpr);732      } else if (InsideInlineASM) {733        Left->setType(TT_InlineASMSymbolicNameLSquare);734      } else if (IsCpp11AttributeSpecifier) {735        if (!IsInnerSquare) {736          Left->setType(TT_AttributeLSquare);737          if (Left->Previous)738            Left->Previous->EndsCppAttributeGroup = false;739        }740      } else if (Style.isJavaScript() && Parent &&741                 Contexts.back().ContextKind == tok::l_brace &&742                 Parent->isOneOf(tok::l_brace, tok::comma)) {743        Left->setType(TT_JsComputedPropertyName);744      } else if (IsCpp && Contexts.back().ContextKind == tok::l_brace &&745                 Parent && Parent->isOneOf(tok::l_brace, tok::comma)) {746        Left->setType(TT_DesignatedInitializerLSquare);747      } else if (IsCSharpAttributeSpecifier) {748        Left->setType(TT_AttributeLSquare);749      } else if (CurrentToken->is(tok::r_square) && Parent &&750                 Parent->is(TT_TemplateCloser)) {751        Left->setType(TT_ArraySubscriptLSquare);752      } else if (Style.isProto()) {753        // Square braces in LK_Proto can either be message field attributes:754        //755        // optional Aaa aaa = 1 [756        //   (aaa) = aaa757        // ];758        //759        // extensions 123 [760        //   (aaa) = aaa761        // ];762        //763        // or text proto extensions (in options):764        //765        // option (Aaa.options) = {766        //   [type.type/type] {767        //     key: value768        //   }769        // }770        //771        // or repeated fields (in options):772        //773        // option (Aaa.options) = {774        //   keys: [ 1, 2, 3 ]775        // }776        //777        // In the first and the third case we want to spread the contents inside778        // the square braces; in the second we want to keep them inline.779        Left->setType(TT_ArrayInitializerLSquare);780        if (!Left->endsSequence(tok::l_square, tok::numeric_constant,781                                tok::equal) &&782            !Left->endsSequence(tok::l_square, tok::numeric_constant,783                                tok::identifier) &&784            !Left->endsSequence(tok::l_square, tok::colon, TT_SelectorName)) {785          Left->setType(TT_ProtoExtensionLSquare);786          BindingIncrease = 10;787        }788      } else if (!CppArrayTemplates && Parent &&789                 Parent->isOneOf(TT_BinaryOperator, TT_TemplateCloser, tok::at,790                                 tok::comma, tok::l_paren, tok::l_square,791                                 tok::question, tok::colon, tok::kw_return,792                                 // Should only be relevant to JavaScript:793                                 tok::kw_default)) {794        Left->setType(TT_ArrayInitializerLSquare);795      } else {796        BindingIncrease = 10;797        Left->setType(TT_ArraySubscriptLSquare);798      }799    }800 801    ScopedContextCreator ContextCreator(*this, tok::l_square, BindingIncrease);802    Contexts.back().IsExpression = true;803    if (Style.isJavaScript() && Parent && Parent->is(TT_JsTypeColon))804      Contexts.back().IsExpression = false;805 806    Contexts.back().ColonIsObjCMethodExpr = StartsObjCMethodExpr;807    Contexts.back().InCpp11AttributeSpecifier = IsCpp11AttributeSpecifier;808    Contexts.back().InCSharpAttributeSpecifier = IsCSharpAttributeSpecifier;809 810    while (CurrentToken) {811      if (CurrentToken->is(tok::r_square)) {812        if (IsCpp11AttributeSpecifier && !IsInnerSquare) {813          CurrentToken->setType(TT_AttributeRSquare);814          CurrentToken->EndsCppAttributeGroup = true;815        }816        if (IsCSharpAttributeSpecifier) {817          CurrentToken->setType(TT_AttributeRSquare);818        } else if (((CurrentToken->Next &&819                     CurrentToken->Next->is(tok::l_paren)) ||820                    (CurrentToken->Previous &&821                     CurrentToken->Previous->Previous == Left)) &&822                   Left->is(TT_ObjCMethodExpr)) {823          // An ObjC method call is rarely followed by an open parenthesis. It824          // also can't be composed of just one token, unless it's a macro that825          // will be expanded to more tokens.826          // FIXME: Do we incorrectly label ":" with this?827          StartsObjCMethodExpr = false;828          Left->setType(TT_Unknown);829        }830        if (StartsObjCMethodExpr && CurrentToken->Previous != Left) {831          CurrentToken->setType(TT_ObjCMethodExpr);832          // If we haven't seen a colon yet, make sure the last identifier833          // before the r_square is tagged as a selector name component.834          if (!ColonFound && CurrentToken->Previous &&835              CurrentToken->Previous->is(TT_Unknown) &&836              canBeObjCSelectorComponent(*CurrentToken->Previous)) {837            CurrentToken->Previous->setType(TT_SelectorName);838          }839          // determineStarAmpUsage() thinks that '*' '[' is allocating an840          // array of pointers, but if '[' starts a selector then '*' is a841          // binary operator.842          if (Parent && Parent->is(TT_PointerOrReference))843            Parent->overwriteFixedType(TT_BinaryOperator);844        }845        Left->MatchingParen = CurrentToken;846        CurrentToken->MatchingParen = Left;847        // FirstObjCSelectorName is set when a colon is found. This does848        // not work, however, when the method has no parameters.849        // Here, we set FirstObjCSelectorName when the end of the method call is850        // reached, in case it was not set already.851        if (!Contexts.back().FirstObjCSelectorName) {852          FormatToken *Previous = CurrentToken->getPreviousNonComment();853          if (Previous && Previous->is(TT_SelectorName)) {854            Previous->ObjCSelectorNameParts = 1;855            Contexts.back().FirstObjCSelectorName = Previous;856          }857        } else {858          Left->ParameterCount =859              Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts;860        }861        if (Contexts.back().FirstObjCSelectorName) {862          Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =863              Contexts.back().LongestObjCSelectorName;864          if (Left->BlockParameterCount > 1)865            Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 0;866        }867        if (Style.isTableGen() && Left->is(TT_TableGenListOpener))868          CurrentToken->setType(TT_TableGenListCloser);869        next();870        return true;871      }872      if (CurrentToken->isOneOf(tok::r_paren, tok::r_brace))873        return false;874      if (CurrentToken->is(tok::colon)) {875        if (IsCpp11AttributeSpecifier &&876            CurrentToken->endsSequence(tok::colon, tok::identifier,877                                       tok::kw_using)) {878          // Remember that this is a [[using ns: foo]] C++ attribute, so we879          // don't add a space before the colon (unlike other colons).880          CurrentToken->setType(TT_AttributeColon);881        } else if (!Style.isVerilog() && !Line.InPragmaDirective &&882                   Left->isOneOf(TT_ArraySubscriptLSquare,883                                 TT_DesignatedInitializerLSquare)) {884          Left->setType(TT_ObjCMethodExpr);885          StartsObjCMethodExpr = true;886          Contexts.back().ColonIsObjCMethodExpr = true;887          if (Parent && Parent->is(tok::r_paren)) {888            // FIXME(bug 36976): ObjC return types shouldn't use TT_CastRParen.889            Parent->setType(TT_CastRParen);890          }891        }892        ColonFound = true;893      }894      if (CurrentToken->is(tok::comma) && Left->is(TT_ObjCMethodExpr) &&895          !ColonFound) {896        Left->setType(TT_ArrayInitializerLSquare);897      }898      FormatToken *Tok = CurrentToken;899      if (Style.isTableGen()) {900        if (CurrentToken->isOneOf(tok::comma, tok::minus, tok::ellipsis)) {901          // '-' and '...' appears as a separator in slice.902          next();903        } else {904          // In TableGen there must be a list of Values in square brackets.905          // It must be ValueList or SliceElements.906          if (!parseTableGenValue())907            return false;908        }909        updateParameterCount(Left, Tok);910        continue;911      }912      if (!consumeToken())913        return false;914      updateParameterCount(Left, Tok);915    }916    return false;917  }918 919  void skipToNextNonComment() {920    next();921    while (CurrentToken && CurrentToken->is(tok::comment))922      next();923  }924 925  // Simplified parser for TableGen Value. Returns true on success.926  // It consists of SimpleValues, SimpleValues with Suffixes, and Value followed927  // by '#', paste operator.928  // There also exists the case the Value is parsed as NameValue.929  // In this case, the Value ends if '{' is found.930  bool parseTableGenValue(bool ParseNameMode = false) {931    if (!CurrentToken)932      return false;933    while (CurrentToken->is(tok::comment))934      next();935    if (!parseTableGenSimpleValue())936      return false;937    if (!CurrentToken)938      return true;939    // Value "#" [Value]940    if (CurrentToken->is(tok::hash)) {941      if (CurrentToken->Next &&942          CurrentToken->Next->isOneOf(tok::colon, tok::semi, tok::l_brace)) {943        // Trailing paste operator.944        // These are only the allowed cases in TGParser::ParseValue().945        CurrentToken->setType(TT_TableGenTrailingPasteOperator);946        next();947        return true;948      }949      FormatToken *HashTok = CurrentToken;950      skipToNextNonComment();951      HashTok->setType(TT_Unknown);952      if (!parseTableGenValue(ParseNameMode))953        return false;954      if (!CurrentToken)955        return true;956    }957    // In name mode, '{' is regarded as the end of the value.958    // See TGParser::ParseValue in TGParser.cpp959    if (ParseNameMode && CurrentToken->is(tok::l_brace))960      return true;961    // These tokens indicates this is a value with suffixes.962    if (CurrentToken->isOneOf(tok::l_brace, tok::l_square, tok::period)) {963      CurrentToken->setType(TT_TableGenValueSuffix);964      FormatToken *Suffix = CurrentToken;965      skipToNextNonComment();966      if (Suffix->is(tok::l_square))967        return parseSquare();968      if (Suffix->is(tok::l_brace)) {969        Scopes.push_back(getScopeType(*Suffix));970        return parseBrace();971      }972    }973    return true;974  }975 976  // TokVarName    ::=  "$" ualpha (ualpha |  "0"..."9")*977  // Appears as a part of DagArg.978  // This does not change the current token on fail.979  bool tryToParseTableGenTokVar() {980    if (!CurrentToken)981      return false;982    if (CurrentToken->is(tok::identifier) &&983        CurrentToken->TokenText.front() == '$') {984      skipToNextNonComment();985      return true;986    }987    return false;988  }989 990  // DagArg       ::=  Value [":" TokVarName] | TokVarName991  // Appears as a part of SimpleValue6.992  bool parseTableGenDAGArg(bool AlignColon = false) {993    if (tryToParseTableGenTokVar())994      return true;995    if (parseTableGenValue()) {996      if (CurrentToken && CurrentToken->is(tok::colon)) {997        if (AlignColon)998          CurrentToken->setType(TT_TableGenDAGArgListColonToAlign);999        else1000          CurrentToken->setType(TT_TableGenDAGArgListColon);1001        skipToNextNonComment();1002        return tryToParseTableGenTokVar();1003      }1004      return true;1005    }1006    return false;1007  }1008 1009  // Judge if the token is a operator ID to insert line break in DAGArg.1010  // That is, TableGenBreakingDAGArgOperators is empty (by the definition of the1011  // option) or the token is in the list.1012  bool isTableGenDAGArgBreakingOperator(const FormatToken &Tok) {1013    auto &Opes = Style.TableGenBreakingDAGArgOperators;1014    // If the list is empty, all operators are breaking operators.1015    if (Opes.empty())1016      return true;1017    // Otherwise, the operator is limited to normal identifiers.1018    if (Tok.isNot(tok::identifier) ||1019        Tok.isOneOf(TT_TableGenBangOperator, TT_TableGenCondOperator)) {1020      return false;1021    }1022    // The case next is colon, it is not a operator of identifier.1023    if (!Tok.Next || Tok.Next->is(tok::colon))1024      return false;1025    return llvm::is_contained(Opes, Tok.TokenText.str());1026  }1027 1028  // SimpleValue6 ::=  "(" DagArg [DagArgList] ")"1029  // This parses SimpleValue 6's inside part of "(" ")"1030  bool parseTableGenDAGArgAndList(FormatToken *Opener) {1031    FormatToken *FirstTok = CurrentToken;1032    if (!parseTableGenDAGArg())1033      return false;1034    bool BreakInside = false;1035    if (Style.TableGenBreakInsideDAGArg != FormatStyle::DAS_DontBreak) {1036      // Specialized detection for DAGArgOperator, that determines the way of1037      // line break for this DAGArg elements.1038      if (isTableGenDAGArgBreakingOperator(*FirstTok)) {1039        // Special case for identifier DAGArg operator.1040        BreakInside = true;1041        Opener->setType(TT_TableGenDAGArgOpenerToBreak);1042        if (FirstTok->isOneOf(TT_TableGenBangOperator,1043                              TT_TableGenCondOperator)) {1044          // Special case for bang/cond operators. Set the whole operator as1045          // the DAGArg operator. Always break after it.1046          CurrentToken->Previous->setType(TT_TableGenDAGArgOperatorToBreak);1047        } else if (FirstTok->is(tok::identifier)) {1048          if (Style.TableGenBreakInsideDAGArg == FormatStyle::DAS_BreakAll)1049            FirstTok->setType(TT_TableGenDAGArgOperatorToBreak);1050          else1051            FirstTok->setType(TT_TableGenDAGArgOperatorID);1052        }1053      }1054    }1055    // Parse the [DagArgList] part1056    return parseTableGenDAGArgList(Opener, BreakInside);1057  }1058 1059  // DagArgList   ::=  "," DagArg [DagArgList]1060  // This parses SimpleValue 6's [DagArgList] part.1061  bool parseTableGenDAGArgList(FormatToken *Opener, bool BreakInside) {1062    ScopedContextCreator ContextCreator(*this, tok::l_paren, 0);1063    Contexts.back().IsTableGenDAGArgList = true;1064    bool FirstDAGArgListElm = true;1065    while (CurrentToken) {1066      if (!FirstDAGArgListElm && CurrentToken->is(tok::comma)) {1067        CurrentToken->setType(BreakInside ? TT_TableGenDAGArgListCommaToBreak1068                                          : TT_TableGenDAGArgListComma);1069        skipToNextNonComment();1070      }1071      if (CurrentToken && CurrentToken->is(tok::r_paren)) {1072        CurrentToken->setType(TT_TableGenDAGArgCloser);1073        Opener->MatchingParen = CurrentToken;1074        CurrentToken->MatchingParen = Opener;1075        skipToNextNonComment();1076        return true;1077      }1078      if (!parseTableGenDAGArg(1079              BreakInside &&1080              Style.AlignConsecutiveTableGenBreakingDAGArgColons.Enabled)) {1081        return false;1082      }1083      FirstDAGArgListElm = false;1084    }1085    return false;1086  }1087 1088  bool parseTableGenSimpleValue() {1089    assert(Style.isTableGen());1090    if (!CurrentToken)1091      return false;1092    FormatToken *Tok = CurrentToken;1093    skipToNextNonComment();1094    // SimpleValue 1, 2, 3: Literals1095    if (Tok->isOneOf(tok::numeric_constant, tok::string_literal,1096                     TT_TableGenMultiLineString, tok::kw_true, tok::kw_false,1097                     tok::question, tok::kw_int)) {1098      return true;1099    }1100    // SimpleValue 4: ValueList, Type1101    if (Tok->is(tok::l_brace)) {1102      Scopes.push_back(getScopeType(*Tok));1103      return parseBrace();1104    }1105    // SimpleValue 5: List initializer1106    if (Tok->is(tok::l_square)) {1107      Tok->setType(TT_TableGenListOpener);1108      if (!parseSquare())1109        return false;1110      if (Tok->is(tok::less)) {1111        CurrentToken->setType(TT_TemplateOpener);1112        return parseAngle();1113      }1114      return true;1115    }1116    // SimpleValue 6: DAGArg [DAGArgList]1117    // SimpleValue6 ::=  "(" DagArg [DagArgList] ")"1118    if (Tok->is(tok::l_paren)) {1119      Tok->setType(TT_TableGenDAGArgOpener);1120      // Nested DAGArg requires space before '(' as separator.1121      if (Contexts.back().IsTableGenDAGArgList)1122        Tok->SpacesRequiredBefore = 1;1123      return parseTableGenDAGArgAndList(Tok);1124    }1125    // SimpleValue 9: Bang operator1126    if (Tok->is(TT_TableGenBangOperator)) {1127      if (CurrentToken && CurrentToken->is(tok::less)) {1128        CurrentToken->setType(TT_TemplateOpener);1129        skipToNextNonComment();1130        if (!parseAngle())1131          return false;1132      }1133      if (!CurrentToken || CurrentToken->isNot(tok::l_paren))1134        return false;1135      next();1136      // FIXME: Hack using inheritance to child context1137      Contexts.back().IsTableGenBangOpe = true;1138      bool Result = parseParens();1139      Contexts.back().IsTableGenBangOpe = false;1140      return Result;1141    }1142    // SimpleValue 9: Cond operator1143    if (Tok->is(TT_TableGenCondOperator)) {1144      if (!CurrentToken || CurrentToken->isNot(tok::l_paren))1145        return false;1146      next();1147      return parseParens();1148    }1149    // We have to check identifier at the last because the kind of bang/cond1150    // operators are also identifier.1151    // SimpleValue 7: Identifiers1152    if (Tok->is(tok::identifier)) {1153      // SimpleValue 8: Anonymous record1154      if (CurrentToken && CurrentToken->is(tok::less)) {1155        CurrentToken->setType(TT_TemplateOpener);1156        skipToNextNonComment();1157        return parseAngle();1158      }1159      return true;1160    }1161 1162    return false;1163  }1164 1165  bool couldBeInStructArrayInitializer() const {1166    if (Contexts.size() < 2)1167      return false;1168    // We want to back up no more then 2 context levels i.e.1169    // . { { <-1170    const auto End = std::next(Contexts.rbegin(), 2);1171    auto Last = Contexts.rbegin();1172    unsigned Depth = 0;1173    for (; Last != End; ++Last)1174      if (Last->ContextKind == tok::l_brace)1175        ++Depth;1176    return Depth == 2 && Last->ContextKind != tok::l_brace;1177  }1178 1179  bool parseBrace() {1180    if (!CurrentToken)1181      return true;1182 1183    assert(CurrentToken->Previous);1184    FormatToken &OpeningBrace = *CurrentToken->Previous;1185    assert(OpeningBrace.is(tok::l_brace));1186    OpeningBrace.ParentBracket = Contexts.back().ContextKind;1187 1188    if (Contexts.back().CaretFound)1189      OpeningBrace.overwriteFixedType(TT_ObjCBlockLBrace);1190    Contexts.back().CaretFound = false;1191 1192    ScopedContextCreator ContextCreator(*this, tok::l_brace, 1);1193    Contexts.back().ColonIsDictLiteral = true;1194    if (OpeningBrace.is(BK_BracedInit))1195      Contexts.back().IsExpression = true;1196    if (Style.isJavaScript() && OpeningBrace.Previous &&1197        OpeningBrace.Previous->is(TT_JsTypeColon)) {1198      Contexts.back().IsExpression = false;1199    }1200    if (Style.isVerilog() &&1201        (!OpeningBrace.getPreviousNonComment() ||1202         OpeningBrace.getPreviousNonComment()->isNot(Keywords.kw_apostrophe))) {1203      Contexts.back().VerilogMayBeConcatenation = true;1204    }1205    if (Style.isTableGen())1206      Contexts.back().ColonIsDictLiteral = false;1207 1208    unsigned CommaCount = 0;1209    while (CurrentToken) {1210      if (CurrentToken->is(tok::r_brace)) {1211        assert(!Scopes.empty());1212        assert(Scopes.back() == getScopeType(OpeningBrace));1213        Scopes.pop_back();1214        assert(OpeningBrace.Optional == CurrentToken->Optional);1215        OpeningBrace.MatchingParen = CurrentToken;1216        CurrentToken->MatchingParen = &OpeningBrace;1217        if (Style.AlignArrayOfStructures != FormatStyle::AIAS_None) {1218          if (OpeningBrace.ParentBracket == tok::l_brace &&1219              couldBeInStructArrayInitializer() && CommaCount > 0) {1220            Contexts.back().ContextType = Context::StructArrayInitializer;1221          }1222        }1223        next();1224        return true;1225      }1226      if (CurrentToken->isOneOf(tok::r_paren, tok::r_square))1227        return false;1228      updateParameterCount(&OpeningBrace, CurrentToken);1229      if (CurrentToken->isOneOf(tok::colon, tok::l_brace, tok::less)) {1230        FormatToken *Previous = CurrentToken->getPreviousNonComment();1231        if (Previous->is(TT_JsTypeOptionalQuestion))1232          Previous = Previous->getPreviousNonComment();1233        if ((CurrentToken->is(tok::colon) && !Style.isTableGen() &&1234             (!Contexts.back().ColonIsDictLiteral || !IsCpp)) ||1235            Style.isProto()) {1236          OpeningBrace.setType(TT_DictLiteral);1237          if (Previous->Tok.getIdentifierInfo() ||1238              Previous->is(tok::string_literal)) {1239            Previous->setType(TT_SelectorName);1240          }1241        }1242        if (CurrentToken->is(tok::colon) && OpeningBrace.is(TT_Unknown) &&1243            !Style.isTableGen()) {1244          OpeningBrace.setType(TT_DictLiteral);1245        } else if (Style.isJavaScript()) {1246          OpeningBrace.overwriteFixedType(TT_DictLiteral);1247        }1248      }1249      if (CurrentToken->is(tok::comma)) {1250        if (Style.isJavaScript())1251          OpeningBrace.overwriteFixedType(TT_DictLiteral);1252        ++CommaCount;1253      }1254      if (!consumeToken())1255        return false;1256    }1257    return true;1258  }1259 1260  void updateParameterCount(FormatToken *Left, FormatToken *Current) {1261    // For ObjC methods, the number of parameters is calculated differently as1262    // method declarations have a different structure (the parameters are not1263    // inside a bracket scope).1264    if (Current->is(tok::l_brace) && Current->is(BK_Block))1265      ++Left->BlockParameterCount;1266    if (Current->is(tok::comma)) {1267      ++Left->ParameterCount;1268      if (!Left->Role)1269        Left->Role.reset(new CommaSeparatedList(Style));1270      Left->Role->CommaFound(Current);1271    } else if (Left->ParameterCount == 0 && Current->isNot(tok::comment)) {1272      Left->ParameterCount = 1;1273    }1274  }1275 1276  bool parseConditional() {1277    while (CurrentToken) {1278      if (CurrentToken->is(tok::colon) && CurrentToken->is(TT_Unknown)) {1279        CurrentToken->setType(TT_ConditionalExpr);1280        next();1281        return true;1282      }1283      if (!consumeToken())1284        return false;1285    }1286    return false;1287  }1288 1289  bool parseTemplateDeclaration() {1290    if (!CurrentToken || CurrentToken->isNot(tok::less))1291      return false;1292 1293    CurrentToken->setType(TT_TemplateOpener);1294    next();1295 1296    TemplateDeclarationDepth++;1297    const bool WellFormed = parseAngle();1298    TemplateDeclarationDepth--;1299    if (!WellFormed)1300      return false;1301 1302    if (CurrentToken && TemplateDeclarationDepth == 0)1303      CurrentToken->Previous->ClosesTemplateDeclaration = true;1304 1305    return true;1306  }1307 1308  bool consumeToken() {1309    if (IsCpp) {1310      const auto *Prev = CurrentToken->getPreviousNonComment();1311      if (Prev && Prev->is(TT_AttributeRSquare) &&1312          CurrentToken->isOneOf(tok::kw_if, tok::kw_switch, tok::kw_case,1313                                tok::kw_default, tok::kw_for, tok::kw_while) &&1314          mustBreakAfterAttributes(*CurrentToken, Style)) {1315        CurrentToken->MustBreakBefore = true;1316      }1317    }1318    FormatToken *Tok = CurrentToken;1319    next();1320    // In Verilog primitives' state tables, `:`, `?`, and `-` aren't normal1321    // operators.1322    if (Tok->is(TT_VerilogTableItem))1323      return true;1324    // Multi-line string itself is a single annotated token.1325    if (Tok->is(TT_TableGenMultiLineString))1326      return true;1327    auto *Prev = Tok->getPreviousNonComment();1328    auto *Next = Tok->getNextNonComment();1329    switch (bool IsIf = false; Tok->Tok.getKind()) {1330    case tok::plus:1331    case tok::minus:1332      if (!Prev && Line.MustBeDeclaration)1333        Tok->setType(TT_ObjCMethodSpecifier);1334      break;1335    case tok::colon:1336      if (!Prev)1337        return false;1338      // Goto labels and case labels are already identified in1339      // UnwrappedLineParser.1340      if (Tok->isTypeFinalized())1341        break;1342      // Colons from ?: are handled in parseConditional().1343      if (Style.isJavaScript()) {1344        if (Contexts.back().ColonIsForRangeExpr || // colon in for loop1345            (Contexts.size() == 1 &&               // switch/case labels1346             Line.First->isNoneOf(tok::kw_enum, tok::kw_case)) ||1347            Contexts.back().ContextKind == tok::l_paren ||  // function params1348            Contexts.back().ContextKind == tok::l_square || // array type1349            (!Contexts.back().IsExpression &&1350             Contexts.back().ContextKind == tok::l_brace) || // object type1351            (Contexts.size() == 1 &&1352             Line.MustBeDeclaration)) { // method/property declaration1353          Contexts.back().IsExpression = false;1354          Tok->setType(TT_JsTypeColon);1355          break;1356        }1357      } else if (Style.isCSharp()) {1358        if (Contexts.back().InCSharpAttributeSpecifier) {1359          Tok->setType(TT_AttributeColon);1360          break;1361        }1362        if (Contexts.back().ContextKind == tok::l_paren) {1363          Tok->setType(TT_CSharpNamedArgumentColon);1364          break;1365        }1366      } else if (Style.isVerilog() && Tok->isNot(TT_BinaryOperator)) {1367        // The distribution weight operators are labeled1368        // TT_BinaryOperator by the lexer.1369        if (Keywords.isVerilogEnd(*Prev) || Keywords.isVerilogBegin(*Prev)) {1370          Tok->setType(TT_VerilogBlockLabelColon);1371        } else if (Contexts.back().ContextKind == tok::l_square) {1372          Tok->setType(TT_BitFieldColon);1373        } else if (Contexts.back().ColonIsDictLiteral) {1374          Tok->setType(TT_DictLiteral);1375        } else if (Contexts.size() == 1) {1376          // In Verilog a case label doesn't have the case keyword. We1377          // assume a colon following an expression is a case label.1378          // Colons from ?: are annotated in parseConditional().1379          Tok->setType(TT_CaseLabelColon);1380          if (Line.Level > 1 || (!Line.InPPDirective && Line.Level > 0))1381            --Line.Level;1382        }1383        break;1384      }1385      if (Line.First->isOneOf(Keywords.kw_module, Keywords.kw_import) ||1386          Line.First->startsSequence(tok::kw_export, Keywords.kw_module) ||1387          Line.First->startsSequence(tok::kw_export, Keywords.kw_import)) {1388        Tok->setType(TT_ModulePartitionColon);1389      } else if (Line.First->is(tok::kw_asm)) {1390        Tok->setType(TT_InlineASMColon);1391      } else if (Contexts.back().ColonIsDictLiteral || Style.isProto()) {1392        Tok->setType(TT_DictLiteral);1393        if (Style.isTextProto())1394          Prev->setType(TT_SelectorName);1395      } else if (Contexts.back().ColonIsObjCMethodExpr ||1396                 Line.startsWith(TT_ObjCMethodSpecifier)) {1397        Tok->setType(TT_ObjCMethodExpr);1398        const auto *PrevPrev = Prev->Previous;1399        // Ensure we tag all identifiers in method declarations as1400        // TT_SelectorName.1401        bool UnknownIdentifierInMethodDeclaration =1402            Line.startsWith(TT_ObjCMethodSpecifier) &&1403            Prev->is(tok::identifier) && Prev->is(TT_Unknown);1404        if (!PrevPrev ||1405            // FIXME(bug 36976): ObjC return types shouldn't use TT_CastRParen.1406            !(PrevPrev->is(TT_CastRParen) ||1407              (PrevPrev->is(TT_ObjCMethodExpr) && PrevPrev->is(tok::colon))) ||1408            PrevPrev->is(tok::r_square) ||1409            Contexts.back().LongestObjCSelectorName == 0 ||1410            UnknownIdentifierInMethodDeclaration) {1411          Prev->setType(TT_SelectorName);1412          if (!Contexts.back().FirstObjCSelectorName)1413            Contexts.back().FirstObjCSelectorName = Prev;1414          else if (Prev->ColumnWidth > Contexts.back().LongestObjCSelectorName)1415            Contexts.back().LongestObjCSelectorName = Prev->ColumnWidth;1416          Prev->ParameterIndex =1417              Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts;1418          ++Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts;1419        }1420      } else if (Contexts.back().ColonIsForRangeExpr) {1421        Tok->setType(TT_RangeBasedForLoopColon);1422        for (auto *Token = Prev;1423             Token && Token->isNoneOf(tok::semi, tok::l_paren);1424             Token = Token->Previous) {1425          if (Token->isPointerOrReference())1426            Token->setFinalizedType(TT_PointerOrReference);1427        }1428      } else if (Contexts.back().ContextType == Context::C11GenericSelection) {1429        Tok->setType(TT_GenericSelectionColon);1430        if (Prev->isPointerOrReference())1431          Prev->setFinalizedType(TT_PointerOrReference);1432      } else if ((CurrentToken && CurrentToken->is(tok::numeric_constant)) ||1433                 (Prev->is(TT_StartOfName) && !Scopes.empty() &&1434                  Scopes.back() == ST_Class)) {1435        Tok->setType(TT_BitFieldColon);1436      } else if (Contexts.size() == 1 &&1437                 Line.getFirstNonComment()->isNoneOf(tok::kw_enum, tok::kw_case,1438                                                     tok::kw_default) &&1439                 !Line.startsWith(tok::kw_typedef, tok::kw_enum)) {1440        if (Prev->isOneOf(tok::r_paren, tok::kw_noexcept) ||1441            Prev->ClosesRequiresClause) {1442          Tok->setType(TT_CtorInitializerColon);1443        } else if (Prev->is(tok::kw_try)) {1444          // Member initializer list within function try block.1445          FormatToken *PrevPrev = Prev->getPreviousNonComment();1446          if (!PrevPrev)1447            break;1448          if (PrevPrev && PrevPrev->isOneOf(tok::r_paren, tok::kw_noexcept))1449            Tok->setType(TT_CtorInitializerColon);1450        } else {1451          Tok->setType(TT_InheritanceColon);1452          if (Prev->isAccessSpecifierKeyword())1453            Line.Type = LT_AccessModifier;1454        }1455      } else if (canBeObjCSelectorComponent(*Prev) && Next &&1456                 (Next->isOneOf(tok::r_paren, tok::comma) ||1457                  (canBeObjCSelectorComponent(*Next) && Next->Next &&1458                   Next->Next->is(tok::colon)))) {1459        // This handles a special macro in ObjC code where selectors including1460        // the colon are passed as macro arguments.1461        Tok->setType(TT_ObjCSelector);1462      }1463      break;1464    case tok::pipe:1465    case tok::amp:1466      // | and & in declarations/type expressions represent union and1467      // intersection types, respectively.1468      if (Style.isJavaScript() && !Contexts.back().IsExpression)1469        Tok->setType(TT_JsTypeOperator);1470      break;1471    case tok::kw_if:1472      if (Style.isTableGen()) {1473        // In TableGen it has the form 'if' <value> 'then'.1474        if (!parseTableGenValue())1475          return false;1476        if (CurrentToken && CurrentToken->is(Keywords.kw_then))1477          next(); // skip then1478        break;1479      }1480      if (CurrentToken &&1481          CurrentToken->isOneOf(tok::kw_constexpr, tok::identifier)) {1482        next();1483      }1484      IsIf = true;1485      [[fallthrough]];1486    case tok::kw_while:1487      if (CurrentToken && CurrentToken->is(tok::l_paren)) {1488        next();1489        if (!parseParens(IsIf))1490          return false;1491      }1492      break;1493    case tok::kw_for:1494      if (Style.isJavaScript()) {1495        // x.for and {for: ...}1496        if ((Prev && Prev->is(tok::period)) || (Next && Next->is(tok::colon)))1497          break;1498        // JS' for await ( ...1499        if (CurrentToken && CurrentToken->is(Keywords.kw_await))1500          next();1501      }1502      if (IsCpp && CurrentToken && CurrentToken->is(tok::kw_co_await))1503        next();1504      Contexts.back().ColonIsForRangeExpr = true;1505      if (!CurrentToken || CurrentToken->isNot(tok::l_paren))1506        return false;1507      next();1508      if (!parseParens())1509        return false;1510      break;1511    case tok::l_paren:1512      // When faced with 'operator()()', the kw_operator handler incorrectly1513      // marks the first l_paren as a OverloadedOperatorLParen. Here, we make1514      // the first two parens OverloadedOperators and the second l_paren an1515      // OverloadedOperatorLParen.1516      if (Prev && Prev->is(tok::r_paren) && Prev->MatchingParen &&1517          Prev->MatchingParen->is(TT_OverloadedOperatorLParen)) {1518        Prev->setType(TT_OverloadedOperator);1519        Prev->MatchingParen->setType(TT_OverloadedOperator);1520        Tok->setType(TT_OverloadedOperatorLParen);1521      }1522 1523      if (Style.isVerilog()) {1524        // Identify the parameter list and port list in a module instantiation.1525        // This is still needed when we already have1526        // UnwrappedLineParser::parseVerilogHierarchyHeader because that1527        // function is only responsible for the definition, not the1528        // instantiation.1529        auto IsInstancePort = [&]() {1530          const FormatToken *PrevPrev;1531          // In the following example all 4 left parentheses will be treated as1532          // 'TT_VerilogInstancePortLParen'.1533          //1534          //   module_x instance_1(port_1); // Case A.1535          //   module_x #(parameter_1)      // Case B.1536          //       instance_2(port_1),      // Case C.1537          //       instance_3(port_1);      // Case D.1538          if (!Prev || !(PrevPrev = Prev->getPreviousNonComment()))1539            return false;1540          // Case A.1541          if (Keywords.isVerilogIdentifier(*Prev) &&1542              Keywords.isVerilogIdentifier(*PrevPrev)) {1543            return true;1544          }1545          // Case B.1546          if (Prev->is(Keywords.kw_verilogHash) &&1547              Keywords.isVerilogIdentifier(*PrevPrev)) {1548            return true;1549          }1550          // Case C.1551          if (Keywords.isVerilogIdentifier(*Prev) && PrevPrev->is(tok::r_paren))1552            return true;1553          // Case D.1554          if (Keywords.isVerilogIdentifier(*Prev) && PrevPrev->is(tok::comma)) {1555            const FormatToken *PrevParen = PrevPrev->getPreviousNonComment();1556            if (PrevParen && PrevParen->is(tok::r_paren) &&1557                PrevParen->MatchingParen &&1558                PrevParen->MatchingParen->is(TT_VerilogInstancePortLParen)) {1559              return true;1560            }1561          }1562          return false;1563        };1564 1565        if (IsInstancePort())1566          Tok->setType(TT_VerilogInstancePortLParen);1567      }1568 1569      if (!parseParens())1570        return false;1571      if (Line.MustBeDeclaration && Contexts.size() == 1 &&1572          !Contexts.back().IsExpression && !Line.startsWith(TT_ObjCProperty) &&1573          !Line.startsWith(tok::l_paren) &&1574          Tok->isNoneOf(TT_TypeDeclarationParen, TT_RequiresExpressionLParen)) {1575        if (!Prev ||1576            (!Prev->isAttribute() &&1577             Prev->isNoneOf(TT_RequiresClause, TT_LeadingJavaAnnotation,1578                            TT_BinaryOperator))) {1579          Line.MightBeFunctionDecl = true;1580          Tok->MightBeFunctionDeclParen = true;1581        }1582      }1583      break;1584    case tok::l_square:1585      if (Style.isTableGen())1586        Tok->setType(TT_TableGenListOpener);1587      if (!parseSquare())1588        return false;1589      break;1590    case tok::l_brace:1591      if (IsCpp) {1592        if (Tok->is(TT_RequiresExpressionLBrace))1593          Line.Type = LT_RequiresExpression;1594      } else if (Style.isTextProto()) {1595        if (Prev && Prev->isNot(TT_DictLiteral))1596          Prev->setType(TT_SelectorName);1597      }1598      Scopes.push_back(getScopeType(*Tok));1599      if (!parseBrace())1600        return false;1601      break;1602    case tok::less:1603      if (parseAngle()) {1604        Tok->setType(TT_TemplateOpener);1605        // In TT_Proto, we must distignuish between:1606        //   map<key, value>1607        //   msg < item: data >1608        //   msg: < item: data >1609        // In TT_TextProto, map<key, value> does not occur.1610        if (Style.isTextProto() ||1611            (Style.Language == FormatStyle::LK_Proto && Prev &&1612             Prev->isOneOf(TT_SelectorName, TT_DictLiteral))) {1613          Tok->setType(TT_DictLiteral);1614          if (Prev && Prev->isNot(TT_DictLiteral))1615            Prev->setType(TT_SelectorName);1616        }1617        if (Style.isTableGen())1618          Tok->setType(TT_TemplateOpener);1619      } else {1620        Tok->setType(TT_BinaryOperator);1621        NonTemplateLess.insert(Tok);1622        CurrentToken = Tok;1623        next();1624      }1625      break;1626    case tok::r_paren:1627    case tok::r_square:1628      return false;1629    case tok::r_brace:1630      // Don't pop scope when encountering unbalanced r_brace.1631      if (!Scopes.empty())1632        Scopes.pop_back();1633      // Lines can start with '}'.1634      if (Prev)1635        return false;1636      break;1637    case tok::greater:1638      if (!Style.isTextProto() && Tok->is(TT_Unknown))1639        Tok->setType(TT_BinaryOperator);1640      if (Prev && Prev->is(TT_TemplateCloser))1641        Tok->SpacesRequiredBefore = 1;1642      break;1643    case tok::kw_operator:1644      if (Style.isProto())1645        break;1646      // Handle C++ user-defined conversion function.1647      if (IsCpp && CurrentToken) {1648        const auto *Info = CurrentToken->Tok.getIdentifierInfo();1649        // What follows Tok is an identifier or a non-operator keyword.1650        if (Info && !(CurrentToken->isPlacementOperator() ||1651                      CurrentToken->is(tok::kw_co_await) ||1652                      Info->isCPlusPlusOperatorKeyword())) {1653          FormatToken *LParen;1654          if (CurrentToken->startsSequence(tok::kw_decltype, tok::l_paren,1655                                           tok::kw_auto, tok::r_paren)) {1656            // Skip `decltype(auto)`.1657            LParen = CurrentToken->Next->Next->Next->Next;1658          } else {1659            // Skip to l_paren.1660            for (LParen = CurrentToken->Next;1661                 LParen && LParen->isNot(tok::l_paren); LParen = LParen->Next) {1662              if (LParen->isPointerOrReference())1663                LParen->setFinalizedType(TT_PointerOrReference);1664            }1665          }1666          if (LParen && LParen->is(tok::l_paren)) {1667            if (!Contexts.back().IsExpression) {1668              Tok->setFinalizedType(TT_FunctionDeclarationName);1669              LParen->setFinalizedType(TT_FunctionDeclarationLParen);1670            }1671            break;1672          }1673        }1674      }1675      while (CurrentToken &&1676             CurrentToken->isNoneOf(tok::l_paren, tok::semi, tok::r_paren)) {1677        if (CurrentToken->isOneOf(tok::star, tok::amp))1678          CurrentToken->setType(TT_PointerOrReference);1679        auto Next = CurrentToken->getNextNonComment();1680        if (!Next)1681          break;1682        if (Next->is(tok::less))1683          next();1684        else1685          consumeToken();1686        if (!CurrentToken)1687          break;1688        auto Previous = CurrentToken->getPreviousNonComment();1689        assert(Previous);1690        if (CurrentToken->is(tok::comma) && Previous->isNot(tok::kw_operator))1691          break;1692        if (Previous->isOneOf(TT_BinaryOperator, TT_UnaryOperator, tok::comma,1693                              tok::arrow) ||1694            Previous->isPointerOrReference() ||1695            // User defined literal.1696            Previous->TokenText.starts_with("\"\"")) {1697          Previous->setType(TT_OverloadedOperator);1698          if (CurrentToken->isOneOf(tok::less, tok::greater))1699            break;1700        }1701      }1702      if (CurrentToken && CurrentToken->is(tok::l_paren))1703        CurrentToken->setType(TT_OverloadedOperatorLParen);1704      if (CurrentToken && CurrentToken->Previous->is(TT_BinaryOperator))1705        CurrentToken->Previous->setType(TT_OverloadedOperator);1706      break;1707    case tok::question:1708      if (Style.isJavaScript() && Next &&1709          Next->isOneOf(tok::semi, tok::comma, tok::colon, tok::r_paren,1710                        tok::r_brace, tok::r_square)) {1711        // Question marks before semicolons, colons, etc. indicate optional1712        // types (fields, parameters), e.g.1713        //   function(x?: string, y?) {...}1714        //   class X { y?; }1715        Tok->setType(TT_JsTypeOptionalQuestion);1716        break;1717      }1718      // Declarations cannot be conditional expressions, this can only be part1719      // of a type declaration.1720      if (Line.MustBeDeclaration && !Contexts.back().IsExpression &&1721          Style.isJavaScript()) {1722        break;1723      }1724      if (Style.isCSharp()) {1725        // `Type?)`, `Type?>`, `Type? name;`, and `Type? name =` can only be1726        // nullable types.1727        if (Next && (Next->isOneOf(tok::r_paren, tok::greater) ||1728                     Next->startsSequence(tok::identifier, tok::semi) ||1729                     Next->startsSequence(tok::identifier, tok::equal))) {1730          Tok->setType(TT_CSharpNullable);1731          break;1732        }1733 1734        // Line.MustBeDeclaration will be true for `Type? name;`.1735        // But not1736        // cond ? "A" : "B";1737        // cond ? id : "B";1738        // cond ? cond2 ? "A" : "B" : "C";1739        if (!Contexts.back().IsExpression && Line.MustBeDeclaration &&1740            (!Next || Next->isNoneOf(tok::identifier, tok::string_literal) ||1741             !Next->Next || Next->Next->isNoneOf(tok::colon, tok::question))) {1742          Tok->setType(TT_CSharpNullable);1743          break;1744        }1745      }1746      parseConditional();1747      break;1748    case tok::kw_template:1749      parseTemplateDeclaration();1750      break;1751    case tok::comma:1752      switch (Contexts.back().ContextType) {1753      case Context::CtorInitializer:1754        Tok->setType(TT_CtorInitializerComma);1755        break;1756      case Context::InheritanceList:1757        Tok->setType(TT_InheritanceComma);1758        break;1759      case Context::VerilogInstancePortList:1760        Tok->setType(TT_VerilogInstancePortComma);1761        break;1762      default:1763        if (Style.isVerilog() && Contexts.size() == 1 &&1764            Line.startsWith(Keywords.kw_assign)) {1765          Tok->setFinalizedType(TT_VerilogAssignComma);1766        } else if (Contexts.back().FirstStartOfName &&1767                   (Contexts.size() == 1 || startsWithInitStatement(Line))) {1768          Contexts.back().FirstStartOfName->PartOfMultiVariableDeclStmt = true;1769          Line.IsMultiVariableDeclStmt = true;1770        }1771        break;1772      }1773      if (Contexts.back().ContextType == Context::ForEachMacro)1774        Contexts.back().IsExpression = true;1775      break;1776    case tok::kw_default:1777      // Unindent case labels.1778      if (Style.isVerilog() && Keywords.isVerilogEndOfLabel(*Tok) &&1779          (Line.Level > 1 || (!Line.InPPDirective && Line.Level > 0))) {1780        --Line.Level;1781      }1782      break;1783    case tok::identifier:1784      if (Tok->isOneOf(Keywords.kw___has_include,1785                       Keywords.kw___has_include_next)) {1786        parseHasInclude();1787      }1788      if (IsCpp) {1789        if (Next && Next->is(tok::l_paren) && Prev &&1790            Prev->isOneOf(tok::kw___cdecl, tok::kw___stdcall,1791                          tok::kw___fastcall, tok::kw___thiscall,1792                          tok::kw___regcall, tok::kw___vectorcall)) {1793          Tok->setFinalizedType(TT_FunctionDeclarationName);1794          Next->setFinalizedType(TT_FunctionDeclarationLParen);1795        }1796      } else if (Style.isCSharp()) {1797        if (Tok->is(Keywords.kw_where) && Next && Next->isNot(tok::l_paren)) {1798          Tok->setType(TT_CSharpGenericTypeConstraint);1799          parseCSharpGenericTypeConstraint();1800          if (!Prev)1801            Line.IsContinuation = true;1802        }1803      } else if (Style.isTableGen()) {1804        if (Tok->is(Keywords.kw_assert)) {1805          if (!parseTableGenValue())1806            return false;1807        } else if (Tok->isOneOf(Keywords.kw_def, Keywords.kw_defm) &&1808                   (!Next || Next->isNoneOf(tok::colon, tok::l_brace))) {1809          // The case NameValue appears.1810          if (!parseTableGenValue(true))1811            return false;1812        }1813      }1814      if (Style.AllowBreakBeforeQtProperty &&1815          Contexts.back().ContextType == Context::QtProperty &&1816          Tok->isQtProperty()) {1817        Tok->setFinalizedType(TT_QtProperty);1818      }1819      break;1820    case tok::arrow:1821      if (Tok->isNot(TT_LambdaArrow) && Prev && Prev->is(tok::kw_noexcept))1822        Tok->setType(TT_TrailingReturnArrow);1823      break;1824    case tok::equal:1825      // In TableGen, there must be a value after "=";1826      if (Style.isTableGen() && !parseTableGenValue())1827        return false;1828      break;1829    default:1830      break;1831    }1832    return true;1833  }1834 1835  void parseCSharpGenericTypeConstraint() {1836    int OpenAngleBracketsCount = 0;1837    while (CurrentToken) {1838      if (CurrentToken->is(tok::less)) {1839        // parseAngle is too greedy and will consume the whole line.1840        CurrentToken->setType(TT_TemplateOpener);1841        ++OpenAngleBracketsCount;1842        next();1843      } else if (CurrentToken->is(tok::greater)) {1844        CurrentToken->setType(TT_TemplateCloser);1845        --OpenAngleBracketsCount;1846        next();1847      } else if (CurrentToken->is(tok::comma) && OpenAngleBracketsCount == 0) {1848        // We allow line breaks after GenericTypeConstraintComma's1849        // so do not flag commas in Generics as GenericTypeConstraintComma's.1850        CurrentToken->setType(TT_CSharpGenericTypeConstraintComma);1851        next();1852      } else if (CurrentToken->is(Keywords.kw_where)) {1853        CurrentToken->setType(TT_CSharpGenericTypeConstraint);1854        next();1855      } else if (CurrentToken->is(tok::colon)) {1856        CurrentToken->setType(TT_CSharpGenericTypeConstraintColon);1857        next();1858      } else {1859        next();1860      }1861    }1862  }1863 1864  void parseIncludeDirective() {1865    if (CurrentToken && CurrentToken->is(tok::less)) {1866      next();1867      while (CurrentToken) {1868        // Mark tokens up to the trailing line comments as implicit string1869        // literals.1870        if (CurrentToken->isNot(tok::comment) &&1871            !CurrentToken->TokenText.starts_with("//")) {1872          CurrentToken->setType(TT_ImplicitStringLiteral);1873        }1874        next();1875      }1876    }1877  }1878 1879  void parseWarningOrError() {1880    next();1881    // We still want to format the whitespace left of the first token of the1882    // warning or error.1883    next();1884    while (CurrentToken) {1885      CurrentToken->setType(TT_ImplicitStringLiteral);1886      next();1887    }1888  }1889 1890  void parsePragma() {1891    next(); // Consume "pragma".1892    if (CurrentToken &&1893        CurrentToken->isOneOf(Keywords.kw_mark, Keywords.kw_option,1894                              Keywords.kw_region)) {1895      bool IsMarkOrRegion =1896          CurrentToken->isOneOf(Keywords.kw_mark, Keywords.kw_region);1897      next();1898      next(); // Consume first token (so we fix leading whitespace).1899      while (CurrentToken) {1900        if (IsMarkOrRegion || CurrentToken->Previous->is(TT_BinaryOperator))1901          CurrentToken->setType(TT_ImplicitStringLiteral);1902        next();1903      }1904    }1905  }1906 1907  void parseHasInclude() {1908    if (!CurrentToken || CurrentToken->isNot(tok::l_paren))1909      return;1910    next(); // '('1911    parseIncludeDirective();1912    next(); // ')'1913  }1914 1915  LineType parsePreprocessorDirective() {1916    bool IsFirstToken = CurrentToken->IsFirst;1917    LineType Type = LT_PreprocessorDirective;1918    next();1919    if (!CurrentToken)1920      return Type;1921 1922    if (Style.isJavaScript() && IsFirstToken) {1923      // JavaScript files can contain shebang lines of the form:1924      // #!/usr/bin/env node1925      // Treat these like C++ #include directives.1926      while (CurrentToken) {1927        // Tokens cannot be comments here.1928        CurrentToken->setType(TT_ImplicitStringLiteral);1929        next();1930      }1931      return LT_ImportStatement;1932    }1933 1934    if (CurrentToken->is(tok::numeric_constant)) {1935      CurrentToken->SpacesRequiredBefore = 1;1936      return Type;1937    }1938    // Hashes in the middle of a line can lead to any strange token1939    // sequence.1940    if (!CurrentToken->Tok.getIdentifierInfo())1941      return Type;1942    // In Verilog macro expansions start with a backtick just like preprocessor1943    // directives. Thus we stop if the word is not a preprocessor directive.1944    if (Style.isVerilog() && !Keywords.isVerilogPPDirective(*CurrentToken))1945      return LT_Invalid;1946    switch (CurrentToken->Tok.getIdentifierInfo()->getPPKeywordID()) {1947    case tok::pp_include:1948    case tok::pp_include_next:1949    case tok::pp_import:1950      next();1951      parseIncludeDirective();1952      Type = LT_ImportStatement;1953      break;1954    case tok::pp_error:1955    case tok::pp_warning:1956      parseWarningOrError();1957      break;1958    case tok::pp_pragma:1959      parsePragma();1960      break;1961    case tok::pp_if:1962    case tok::pp_elif:1963      Contexts.back().IsExpression = true;1964      next();1965      if (CurrentToken)1966        CurrentToken->SpacesRequiredBefore = 1;1967      parseLine();1968      break;1969    default:1970      break;1971    }1972    while (CurrentToken) {1973      FormatToken *Tok = CurrentToken;1974      next();1975      if (Tok->is(tok::l_paren)) {1976        parseParens();1977      } else if (Tok->isOneOf(Keywords.kw___has_include,1978                              Keywords.kw___has_include_next)) {1979        parseHasInclude();1980      }1981    }1982    return Type;1983  }1984 1985public:1986  LineType parseLine() {1987    if (!CurrentToken)1988      return LT_Invalid;1989    NonTemplateLess.clear();1990    if (!Line.InMacroBody && CurrentToken->is(tok::hash)) {1991      // We were not yet allowed to use C++17 optional when this was being1992      // written. So we used LT_Invalid to mark that the line is not a1993      // preprocessor directive.1994      auto Type = parsePreprocessorDirective();1995      if (Type != LT_Invalid)1996        return Type;1997    }1998 1999    // Directly allow to 'import <string-literal>' to support protocol buffer2000    // definitions (github.com/google/protobuf) or missing "#" (either way we2001    // should not break the line).2002    IdentifierInfo *Info = CurrentToken->Tok.getIdentifierInfo();2003    if ((Style.isJava() && CurrentToken->is(Keywords.kw_package)) ||2004        (!Style.isVerilog() && Info &&2005         Info->getPPKeywordID() == tok::pp_import && CurrentToken->Next &&2006         CurrentToken->Next->isOneOf(tok::string_literal, tok::identifier,2007                                     tok::kw_static))) {2008      next();2009      parseIncludeDirective();2010      return LT_ImportStatement;2011    }2012 2013    // If this line starts and ends in '<' and '>', respectively, it is likely2014    // part of "#define <a/b.h>".2015    if (CurrentToken->is(tok::less) && Line.Last->is(tok::greater)) {2016      parseIncludeDirective();2017      return LT_ImportStatement;2018    }2019 2020    // In .proto files, top-level options and package statements are very2021    // similar to import statements and should not be line-wrapped.2022    if (Style.Language == FormatStyle::LK_Proto && Line.Level == 0 &&2023        CurrentToken->isOneOf(Keywords.kw_option, Keywords.kw_package)) {2024      next();2025      if (CurrentToken && CurrentToken->is(tok::identifier)) {2026        while (CurrentToken)2027          next();2028        return LT_ImportStatement;2029      }2030    }2031 2032    bool KeywordVirtualFound = false;2033    bool ImportStatement = false;2034 2035    // import {...} from '...';2036    if (Style.isJavaScript() && CurrentToken->is(Keywords.kw_import))2037      ImportStatement = true;2038 2039    while (CurrentToken) {2040      if (CurrentToken->is(tok::kw_virtual))2041        KeywordVirtualFound = true;2042      if (Style.isJavaScript()) {2043        // export {...} from '...';2044        // An export followed by "from 'some string';" is a re-export from2045        // another module identified by a URI and is treated as a2046        // LT_ImportStatement (i.e. prevent wraps on it for long URIs).2047        // Just "export {...};" or "export class ..." should not be treated as2048        // an import in this sense.2049        if (Line.First->is(tok::kw_export) &&2050            CurrentToken->is(Keywords.kw_from) && CurrentToken->Next &&2051            CurrentToken->Next->isStringLiteral()) {2052          ImportStatement = true;2053        }2054        if (isClosureImportStatement(*CurrentToken))2055          ImportStatement = true;2056      }2057      if (!consumeToken())2058        return LT_Invalid;2059    }2060    if (const auto Type = Line.Type; Type == LT_AccessModifier ||2061                                     Type == LT_RequiresExpression ||2062                                     Type == LT_SimpleRequirement) {2063      return Type;2064    }2065    if (KeywordVirtualFound)2066      return LT_VirtualFunctionDecl;2067    if (ImportStatement)2068      return LT_ImportStatement;2069 2070    if (Line.startsWith(TT_ObjCMethodSpecifier)) {2071      if (Contexts.back().FirstObjCSelectorName) {2072        Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =2073            Contexts.back().LongestObjCSelectorName;2074      }2075      return LT_ObjCMethodDecl;2076    }2077 2078    for (const auto &ctx : Contexts)2079      if (ctx.ContextType == Context::StructArrayInitializer)2080        return LT_ArrayOfStructInitializer;2081 2082    return LT_Other;2083  }2084 2085private:2086  bool isClosureImportStatement(const FormatToken &Tok) {2087    // FIXME: Closure-library specific stuff should not be hard-coded but be2088    // configurable.2089    return Tok.TokenText == "goog" && Tok.Next && Tok.Next->is(tok::period) &&2090           Tok.Next->Next &&2091           (Tok.Next->Next->TokenText == "module" ||2092            Tok.Next->Next->TokenText == "provide" ||2093            Tok.Next->Next->TokenText == "require" ||2094            Tok.Next->Next->TokenText == "requireType" ||2095            Tok.Next->Next->TokenText == "forwardDeclare") &&2096           Tok.Next->Next->Next && Tok.Next->Next->Next->is(tok::l_paren);2097  }2098 2099  void resetTokenMetadata() {2100    if (!CurrentToken)2101      return;2102 2103    // Reset token type in case we have already looked at it and then2104    // recovered from an error (e.g. failure to find the matching >).2105    if (!CurrentToken->isTypeFinalized() &&2106        CurrentToken->isNoneOf(2107            TT_LambdaLSquare, TT_LambdaLBrace, TT_AttributeMacro, TT_IfMacro,2108            TT_ForEachMacro, TT_TypenameMacro, TT_FunctionLBrace,2109            TT_ImplicitStringLiteral, TT_InlineASMBrace, TT_FatArrow,2110            TT_LambdaArrow, TT_NamespaceMacro, TT_OverloadedOperator,2111            TT_RegexLiteral, TT_TemplateString, TT_ObjCStringLiteral,2112            TT_UntouchableMacroFunc, TT_StatementAttributeLikeMacro,2113            TT_FunctionLikeOrFreestandingMacro, TT_ClassLBrace, TT_EnumLBrace,2114            TT_RecordLBrace, TT_StructLBrace, TT_UnionLBrace, TT_RequiresClause,2115            TT_RequiresClauseInARequiresExpression, TT_RequiresExpression,2116            TT_RequiresExpressionLParen, TT_RequiresExpressionLBrace,2117            TT_CompoundRequirementLBrace, TT_BracedListLBrace,2118            TT_FunctionLikeMacro)) {2119      CurrentToken->setType(TT_Unknown);2120    }2121    CurrentToken->Role.reset();2122    CurrentToken->MatchingParen = nullptr;2123    CurrentToken->FakeLParens.clear();2124    CurrentToken->FakeRParens = 0;2125  }2126 2127  void next() {2128    if (!CurrentToken)2129      return;2130 2131    CurrentToken->NestingLevel = Contexts.size() - 1;2132    CurrentToken->BindingStrength = Contexts.back().BindingStrength;2133    modifyContext(*CurrentToken);2134    determineTokenType(*CurrentToken);2135    CurrentToken = CurrentToken->Next;2136 2137    resetTokenMetadata();2138  }2139 2140  /// A struct to hold information valid in a specific context, e.g.2141  /// a pair of parenthesis.2142  struct Context {2143    Context(tok::TokenKind ContextKind, unsigned BindingStrength,2144            bool IsExpression)2145        : ContextKind(ContextKind), BindingStrength(BindingStrength),2146          IsExpression(IsExpression) {}2147 2148    tok::TokenKind ContextKind;2149    unsigned BindingStrength;2150    bool IsExpression;2151    unsigned LongestObjCSelectorName = 0;2152    bool ColonIsForRangeExpr = false;2153    bool ColonIsDictLiteral = false;2154    bool ColonIsObjCMethodExpr = false;2155    FormatToken *FirstObjCSelectorName = nullptr;2156    FormatToken *FirstStartOfName = nullptr;2157    bool CanBeExpression = true;2158    bool CaretFound = false;2159    bool InCpp11AttributeSpecifier = false;2160    bool InCSharpAttributeSpecifier = false;2161    bool InStaticAssertFirstArgument = false;2162    bool VerilogAssignmentFound = false;2163    // Whether the braces may mean concatenation instead of structure or array2164    // literal.2165    bool VerilogMayBeConcatenation = false;2166    bool IsTableGenDAGArgList = false;2167    bool IsTableGenBangOpe = false;2168    bool IsTableGenCondOpe = false;2169    enum {2170      Unknown,2171      // Like the part after `:` in a constructor.2172      //   Context(...) : IsExpression(IsExpression)2173      CtorInitializer,2174      // Like in the parentheses in a foreach.2175      ForEachMacro,2176      // Like the inheritance list in a class declaration.2177      //   class Input : public IO2178      InheritanceList,2179      // Like in the braced list.2180      //   int x[] = {};2181      StructArrayInitializer,2182      // Like in `static_cast<int>`.2183      TemplateArgument,2184      // C11 _Generic selection.2185      C11GenericSelection,2186      QtProperty,2187      // Like in the outer parentheses in `ffnand ff1(.q());`.2188      VerilogInstancePortList,2189    } ContextType = Unknown;2190  };2191 2192  /// Puts a new \c Context onto the stack \c Contexts for the lifetime2193  /// of each instance.2194  struct ScopedContextCreator {2195    AnnotatingParser &P;2196 2197    ScopedContextCreator(AnnotatingParser &P, tok::TokenKind ContextKind,2198                         unsigned Increase)2199        : P(P) {2200      P.Contexts.push_back(Context(ContextKind,2201                                   P.Contexts.back().BindingStrength + Increase,2202                                   P.Contexts.back().IsExpression));2203    }2204 2205    ~ScopedContextCreator() {2206      if (P.Style.AlignArrayOfStructures != FormatStyle::AIAS_None) {2207        if (P.Contexts.back().ContextType == Context::StructArrayInitializer) {2208          P.Contexts.pop_back();2209          P.Contexts.back().ContextType = Context::StructArrayInitializer;2210          return;2211        }2212      }2213      P.Contexts.pop_back();2214    }2215  };2216 2217  void modifyContext(const FormatToken &Current) {2218    auto AssignmentStartsExpression = [&]() {2219      if (Current.getPrecedence() != prec::Assignment)2220        return false;2221 2222      if (Line.First->isOneOf(tok::kw_using, tok::kw_return))2223        return false;2224      if (Line.First->is(tok::kw_template)) {2225        assert(Current.Previous);2226        if (Current.Previous->is(tok::kw_operator)) {2227          // `template ... operator=` cannot be an expression.2228          return false;2229        }2230 2231        // `template` keyword can start a variable template.2232        const FormatToken *Tok = Line.First->getNextNonComment();2233        assert(Tok); // Current token is on the same line.2234        if (Tok->isNot(TT_TemplateOpener)) {2235          // Explicit template instantiations do not have `<>`.2236          return false;2237        }2238 2239        // This is the default value of a template parameter, determine if it's2240        // type or non-type.2241        if (Contexts.back().ContextKind == tok::less) {2242          assert(Current.Previous->Previous);2243          return Current.Previous->Previous->isNoneOf(tok::kw_typename,2244                                                      tok::kw_class);2245        }2246 2247        Tok = Tok->MatchingParen;2248        if (!Tok)2249          return false;2250        Tok = Tok->getNextNonComment();2251        if (!Tok)2252          return false;2253 2254        if (Tok->isOneOf(tok::kw_class, tok::kw_enum, tok::kw_struct,2255                         tok::kw_using)) {2256          return false;2257        }2258 2259        return true;2260      }2261 2262      // Type aliases use `type X = ...;` in TypeScript and can be exported2263      // using `export type ...`.2264      if (Style.isJavaScript() &&2265          (Line.startsWith(Keywords.kw_type, tok::identifier) ||2266           Line.startsWith(tok::kw_export, Keywords.kw_type,2267                           tok::identifier))) {2268        return false;2269      }2270 2271      return !Current.Previous || Current.Previous->isNot(tok::kw_operator);2272    };2273 2274    if (AssignmentStartsExpression()) {2275      Contexts.back().IsExpression = true;2276      if (!Line.startsWith(TT_UnaryOperator)) {2277        for (FormatToken *Previous = Current.Previous;2278             Previous && Previous->Previous &&2279             Previous->Previous->isNoneOf(tok::comma, tok::semi);2280             Previous = Previous->Previous) {2281          if (Previous->isOneOf(tok::r_square, tok::r_paren, tok::greater)) {2282            Previous = Previous->MatchingParen;2283            if (!Previous)2284              break;2285          }2286          if (Previous->opensScope())2287            break;2288          if (Previous->isOneOf(TT_BinaryOperator, TT_UnaryOperator) &&2289              Previous->isPointerOrReference() && Previous->Previous &&2290              Previous->Previous->isNot(tok::equal)) {2291            Previous->setType(TT_PointerOrReference);2292          }2293        }2294      }2295    } else if (Current.is(tok::lessless) &&2296               (!Current.Previous ||2297                Current.Previous->isNot(tok::kw_operator))) {2298      Contexts.back().IsExpression = true;2299    } else if (Current.isOneOf(tok::kw_return, tok::kw_throw)) {2300      Contexts.back().IsExpression = true;2301    } else if (Current.is(TT_TrailingReturnArrow)) {2302      Contexts.back().IsExpression = false;2303    } else if (Current.isOneOf(TT_LambdaArrow, Keywords.kw_assert)) {2304      Contexts.back().IsExpression = Style.isJava();2305    } else if (Current.Previous &&2306               Current.Previous->is(TT_CtorInitializerColon)) {2307      Contexts.back().IsExpression = true;2308      Contexts.back().ContextType = Context::CtorInitializer;2309    } else if (Current.Previous && Current.Previous->is(TT_InheritanceColon)) {2310      Contexts.back().ContextType = Context::InheritanceList;2311    } else if (Current.isOneOf(tok::r_paren, tok::greater, tok::comma)) {2312      for (FormatToken *Previous = Current.Previous;2313           Previous && Previous->isOneOf(tok::star, tok::amp);2314           Previous = Previous->Previous) {2315        Previous->setType(TT_PointerOrReference);2316      }2317      if (Line.MustBeDeclaration &&2318          Contexts.front().ContextType != Context::CtorInitializer) {2319        Contexts.back().IsExpression = false;2320      }2321    } else if (Current.is(tok::kw_new)) {2322      Contexts.back().CanBeExpression = false;2323    } else if (Current.is(tok::semi) ||2324               (Current.is(tok::exclaim) && Current.Previous &&2325                Current.Previous->isNot(tok::kw_operator))) {2326      // This should be the condition or increment in a for-loop.2327      // But not operator !() (can't use TT_OverloadedOperator here as its not2328      // been annotated yet).2329      Contexts.back().IsExpression = true;2330    }2331  }2332 2333  static FormatToken *untilMatchingParen(FormatToken *Current) {2334    // Used when `MatchingParen` is not yet established.2335    int ParenLevel = 0;2336    while (Current) {2337      if (Current->is(tok::l_paren))2338        ++ParenLevel;2339      if (Current->is(tok::r_paren))2340        --ParenLevel;2341      if (ParenLevel < 1)2342        break;2343      Current = Current->Next;2344    }2345    return Current;2346  }2347 2348  static bool isDeductionGuide(FormatToken &Current) {2349    // Look for a deduction guide template<T> A(...) -> A<...>;2350    if (Current.Previous && Current.Previous->is(tok::r_paren) &&2351        Current.startsSequence(tok::arrow, tok::identifier, tok::less)) {2352      // Find the TemplateCloser.2353      FormatToken *TemplateCloser = Current.Next->Next;2354      int NestingLevel = 0;2355      while (TemplateCloser) {2356        // Skip over an expressions in parens  A<(3 < 2)>;2357        if (TemplateCloser->is(tok::l_paren)) {2358          // No Matching Paren yet so skip to matching paren2359          TemplateCloser = untilMatchingParen(TemplateCloser);2360          if (!TemplateCloser)2361            break;2362        }2363        if (TemplateCloser->is(tok::less))2364          ++NestingLevel;2365        if (TemplateCloser->is(tok::greater))2366          --NestingLevel;2367        if (NestingLevel < 1)2368          break;2369        TemplateCloser = TemplateCloser->Next;2370      }2371      // Assuming we have found the end of the template ensure its followed2372      // with a semi-colon.2373      if (TemplateCloser && TemplateCloser->Next &&2374          TemplateCloser->Next->is(tok::semi) &&2375          Current.Previous->MatchingParen) {2376        // Determine if the identifier `A` prior to the A<..>; is the same as2377        // prior to the A(..)2378        FormatToken *LeadingIdentifier =2379            Current.Previous->MatchingParen->Previous;2380 2381        return LeadingIdentifier &&2382               LeadingIdentifier->TokenText == Current.Next->TokenText;2383      }2384    }2385    return false;2386  }2387 2388  void determineTokenType(FormatToken &Current) {2389    if (Current.isNot(TT_Unknown)) {2390      // The token type is already known.2391      return;2392    }2393 2394    if ((Style.isJavaScript() || Style.isCSharp()) &&2395        Current.is(tok::exclaim)) {2396      if (Current.Previous) {2397        bool IsIdentifier =2398            Style.isJavaScript()2399                ? Keywords.isJavaScriptIdentifier(2400                      *Current.Previous, /* AcceptIdentifierName= */ true)2401                : Current.Previous->is(tok::identifier);2402        if (IsIdentifier ||2403            Current.Previous->isOneOf(2404                tok::kw_default, tok::kw_namespace, tok::r_paren, tok::r_square,2405                tok::r_brace, tok::kw_false, tok::kw_true, Keywords.kw_type,2406                Keywords.kw_get, Keywords.kw_init, Keywords.kw_set) ||2407            Current.Previous->Tok.isLiteral()) {2408          Current.setType(TT_NonNullAssertion);2409          return;2410        }2411      }2412      if (Current.Next &&2413          Current.Next->isOneOf(TT_BinaryOperator, Keywords.kw_as)) {2414        Current.setType(TT_NonNullAssertion);2415        return;2416      }2417    }2418 2419    // Line.MightBeFunctionDecl can only be true after the parentheses of a2420    // function declaration have been found. In this case, 'Current' is a2421    // trailing token of this declaration and thus cannot be a name.2422    if ((Style.isJavaScript() || Style.isJava()) &&2423        Current.is(Keywords.kw_instanceof)) {2424      Current.setType(TT_BinaryOperator);2425    } else if (isStartOfName(Current) &&2426               (!Line.MightBeFunctionDecl || Current.NestingLevel != 0)) {2427      Contexts.back().FirstStartOfName = &Current;2428      Current.setType(TT_StartOfName);2429    } else if (Current.is(tok::semi)) {2430      // Reset FirstStartOfName after finding a semicolon so that a for loop2431      // with multiple increment statements is not confused with a for loop2432      // having multiple variable declarations.2433      Contexts.back().FirstStartOfName = nullptr;2434    } else if (Current.isOneOf(tok::kw_auto, tok::kw___auto_type)) {2435      AutoFound = true;2436    } else if (Current.is(tok::arrow) && Style.isJava()) {2437      Current.setType(TT_LambdaArrow);2438    } else if (Current.is(tok::arrow) && Style.isVerilog()) {2439      // The implication operator.2440      Current.setType(TT_BinaryOperator);2441    } else if (Current.is(tok::arrow) && AutoFound &&2442               Line.MightBeFunctionDecl && Current.NestingLevel == 0 &&2443               Current.Previous->isNoneOf(tok::kw_operator, tok::identifier)) {2444      // not auto operator->() -> xxx;2445      Current.setType(TT_TrailingReturnArrow);2446    } else if (Current.is(tok::arrow) && Current.Previous &&2447               Current.Previous->is(tok::r_brace) &&2448               Current.Previous->is(BK_Block)) {2449      // Concept implicit conversion constraint needs to be treated like2450      // a trailing return type  ... } -> <type>.2451      Current.setType(TT_TrailingReturnArrow);2452    } else if (isDeductionGuide(Current)) {2453      // Deduction guides trailing arrow " A(...) -> A<T>;".2454      Current.setType(TT_TrailingReturnArrow);2455    } else if (Current.isPointerOrReference()) {2456      Current.setType(determineStarAmpUsage(2457          Current,2458          (Contexts.back().CanBeExpression && Contexts.back().IsExpression) ||2459              Contexts.back().InStaticAssertFirstArgument,2460          Contexts.back().ContextType == Context::TemplateArgument));2461    } else if (Current.isOneOf(tok::minus, tok::plus, tok::caret) ||2462               (Style.isVerilog() && Current.is(tok::pipe))) {2463      Current.setType(determinePlusMinusCaretUsage(Current));2464      if (Current.is(TT_UnaryOperator) && Current.is(tok::caret))2465        Contexts.back().CaretFound = true;2466    } else if (Current.isOneOf(tok::minusminus, tok::plusplus)) {2467      Current.setType(determineIncrementUsage(Current));2468    } else if (Current.isOneOf(tok::exclaim, tok::tilde)) {2469      Current.setType(TT_UnaryOperator);2470    } else if (Current.is(tok::question)) {2471      if (Style.isJavaScript() && Line.MustBeDeclaration &&2472          !Contexts.back().IsExpression) {2473        // In JavaScript, `interface X { foo?(): bar; }` is an optional method2474        // on the interface, not a ternary expression.2475        Current.setType(TT_JsTypeOptionalQuestion);2476      } else if (Style.isTableGen()) {2477        // In TableGen, '?' is just an identifier like token.2478        Current.setType(TT_Unknown);2479      } else {2480        Current.setType(TT_ConditionalExpr);2481      }2482    } else if (Current.isBinaryOperator() &&2483               (!Current.Previous || Current.Previous->isNot(tok::l_square)) &&2484               (Current.isNot(tok::greater) && !Style.isTextProto())) {2485      if (Style.isVerilog()) {2486        if (Current.is(tok::lessequal) && Contexts.size() == 1 &&2487            !Contexts.back().VerilogAssignmentFound) {2488          // In Verilog `<=` is assignment if in its own statement. It is a2489          // statement instead of an expression, that is it can not be chained.2490          Current.ForcedPrecedence = prec::Assignment;2491          Current.setFinalizedType(TT_BinaryOperator);2492        }2493        if (Current.getPrecedence() == prec::Assignment)2494          Contexts.back().VerilogAssignmentFound = true;2495      }2496      Current.setType(TT_BinaryOperator);2497    } else if (Current.is(tok::comment)) {2498      if (Current.TokenText.starts_with("/*")) {2499        if (Current.TokenText.ends_with("*/")) {2500          Current.setType(TT_BlockComment);2501        } else {2502          // The lexer has for some reason determined a comment here. But we2503          // cannot really handle it, if it isn't properly terminated.2504          Current.Tok.setKind(tok::unknown);2505        }2506      } else {2507        Current.setType(TT_LineComment);2508      }2509    } else if (Current.is(tok::string_literal)) {2510      if (Style.isVerilog() && Contexts.back().VerilogMayBeConcatenation &&2511          Current.getPreviousNonComment() &&2512          Current.getPreviousNonComment()->isOneOf(tok::comma, tok::l_brace) &&2513          Current.getNextNonComment() &&2514          Current.getNextNonComment()->isOneOf(tok::comma, tok::r_brace)) {2515        Current.setType(TT_StringInConcatenation);2516      }2517    } else if (Current.is(tok::l_paren)) {2518      if (lParenStartsCppCast(Current))2519        Current.setType(TT_CppCastLParen);2520    } else if (Current.is(tok::r_paren)) {2521      if (rParenEndsCast(Current))2522        Current.setType(TT_CastRParen);2523      if (Current.MatchingParen && Current.Next &&2524          !Current.Next->isBinaryOperator() &&2525          Current.Next->isNoneOf(2526              tok::semi, tok::colon, tok::l_brace, tok::l_paren, tok::comma,2527              tok::period, tok::arrow, tok::coloncolon, tok::kw_noexcept)) {2528        if (FormatToken *AfterParen = Current.MatchingParen->Next;2529            AfterParen && AfterParen->isNot(tok::caret)) {2530          // Make sure this isn't the return type of an Obj-C block declaration.2531          if (FormatToken *BeforeParen = Current.MatchingParen->Previous;2532              BeforeParen && BeforeParen->is(tok::identifier) &&2533              BeforeParen->isNot(TT_TypenameMacro) &&2534              BeforeParen->TokenText == BeforeParen->TokenText.upper() &&2535              (!BeforeParen->Previous ||2536               BeforeParen->Previous->ClosesTemplateDeclaration ||2537               BeforeParen->Previous->ClosesRequiresClause)) {2538            Current.setType(TT_FunctionAnnotationRParen);2539          }2540        }2541      }2542    } else if (Current.is(tok::at) && Current.Next && !Style.isJavaScript() &&2543               !Style.isJava()) {2544      // In Java & JavaScript, "@..." is a decorator or annotation. In ObjC, it2545      // marks declarations and properties that need special formatting.2546      switch (Current.Next->Tok.getObjCKeywordID()) {2547      case tok::objc_interface:2548      case tok::objc_implementation:2549      case tok::objc_protocol:2550        Current.setType(TT_ObjCDecl);2551        break;2552      case tok::objc_property:2553        Current.setType(TT_ObjCProperty);2554        break;2555      default:2556        break;2557      }2558    } else if (Current.is(tok::period)) {2559      FormatToken *PreviousNoComment = Current.getPreviousNonComment();2560      if (PreviousNoComment &&2561          PreviousNoComment->isOneOf(tok::comma, tok::l_brace)) {2562        Current.setType(TT_DesignatedInitializerPeriod);2563      } else if (Style.isJava() && Current.Previous &&2564                 Current.Previous->isOneOf(TT_JavaAnnotation,2565                                           TT_LeadingJavaAnnotation)) {2566        Current.setType(Current.Previous->getType());2567      }2568    } else if (canBeObjCSelectorComponent(Current) &&2569               // FIXME(bug 36976): ObjC return types shouldn't use2570               // TT_CastRParen.2571               Current.Previous && Current.Previous->is(TT_CastRParen) &&2572               Current.Previous->MatchingParen &&2573               Current.Previous->MatchingParen->Previous &&2574               Current.Previous->MatchingParen->Previous->is(2575                   TT_ObjCMethodSpecifier)) {2576      // This is the first part of an Objective-C selector name. (If there's no2577      // colon after this, this is the only place which annotates the identifier2578      // as a selector.)2579      Current.setType(TT_SelectorName);2580    } else if (Current.isOneOf(tok::identifier, tok::kw_const, tok::kw_noexcept,2581                               tok::kw_requires) &&2582               Current.Previous &&2583               Current.Previous->isNoneOf(tok::equal, tok::at,2584                                          TT_CtorInitializerComma,2585                                          TT_CtorInitializerColon) &&2586               Line.MightBeFunctionDecl && Contexts.size() == 1) {2587      // Line.MightBeFunctionDecl can only be true after the parentheses of a2588      // function declaration have been found.2589      Current.setType(TT_TrailingAnnotation);2590    } else if ((Style.isJava() || Style.isJavaScript()) && Current.Previous) {2591      if (Current.Previous->is(tok::at) &&2592          Current.isNot(Keywords.kw_interface)) {2593        const FormatToken &AtToken = *Current.Previous;2594        const FormatToken *Previous = AtToken.getPreviousNonComment();2595        if (!Previous || Previous->is(TT_LeadingJavaAnnotation))2596          Current.setType(TT_LeadingJavaAnnotation);2597        else2598          Current.setType(TT_JavaAnnotation);2599      } else if (Current.Previous->is(tok::period) &&2600                 Current.Previous->isOneOf(TT_JavaAnnotation,2601                                           TT_LeadingJavaAnnotation)) {2602        Current.setType(Current.Previous->getType());2603      }2604    }2605  }2606 2607  /// Take a guess at whether \p Tok starts a name of a function or2608  /// variable declaration.2609  ///2610  /// This is a heuristic based on whether \p Tok is an identifier following2611  /// something that is likely a type.2612  bool isStartOfName(const FormatToken &Tok) {2613    // Handled in ExpressionParser for Verilog.2614    if (Style.isVerilog())2615      return false;2616 2617    if (!Tok.Previous || Tok.isNot(tok::identifier) || Tok.is(TT_ClassHeadName))2618      return false;2619 2620    if (Tok.endsSequence(Keywords.kw_final, TT_ClassHeadName))2621      return false;2622 2623    if ((Style.isJavaScript() || Style.isJava()) && Tok.is(Keywords.kw_extends))2624      return false;2625 2626    if (const auto *NextNonComment = Tok.getNextNonComment();2627        (!NextNonComment && !Line.InMacroBody) ||2628        (NextNonComment &&2629         (NextNonComment->isPointerOrReference() ||2630          NextNonComment->isOneOf(TT_ClassHeadName, tok::string_literal) ||2631          (Line.InPragmaDirective && NextNonComment->is(tok::identifier))))) {2632      return false;2633    }2634 2635    if (Tok.Previous->isOneOf(TT_LeadingJavaAnnotation, Keywords.kw_instanceof,2636                              Keywords.kw_as)) {2637      return false;2638    }2639    if (Style.isJavaScript() && Tok.Previous->is(Keywords.kw_in))2640      return false;2641 2642    // Skip "const" as it does not have an influence on whether this is a name.2643    FormatToken *PreviousNotConst = Tok.getPreviousNonComment();2644 2645    // For javascript const can be like "let" or "var"2646    if (!Style.isJavaScript())2647      while (PreviousNotConst && PreviousNotConst->is(tok::kw_const))2648        PreviousNotConst = PreviousNotConst->getPreviousNonComment();2649 2650    if (!PreviousNotConst)2651      return false;2652 2653    if (PreviousNotConst->ClosesRequiresClause)2654      return false;2655 2656    if (Style.isTableGen()) {2657      // keywords such as let and def* defines names.2658      if (Keywords.isTableGenDefinition(*PreviousNotConst))2659        return true;2660      // Otherwise C++ style declarations is available only inside the brace.2661      if (Contexts.back().ContextKind != tok::l_brace)2662        return false;2663    }2664 2665    bool IsPPKeyword = PreviousNotConst->is(tok::identifier) &&2666                       PreviousNotConst->Previous &&2667                       PreviousNotConst->Previous->is(tok::hash);2668 2669    if (PreviousNotConst->is(TT_TemplateCloser)) {2670      return PreviousNotConst && PreviousNotConst->MatchingParen &&2671             PreviousNotConst->MatchingParen->Previous &&2672             PreviousNotConst->MatchingParen->Previous->isNoneOf(2673                 tok::period, tok::kw_template);2674    }2675 2676    if ((PreviousNotConst->is(tok::r_paren) &&2677         PreviousNotConst->is(TT_TypeDeclarationParen)) ||2678        PreviousNotConst->is(TT_AttributeRParen)) {2679      return true;2680    }2681 2682    // If is a preprocess keyword like #define.2683    if (IsPPKeyword)2684      return false;2685 2686    // int a or auto a.2687    if (PreviousNotConst->isOneOf(tok::identifier, tok::kw_auto) &&2688        PreviousNotConst->isNot(TT_StatementAttributeLikeMacro)) {2689      return true;2690    }2691 2692    // *a or &a or &&a.2693    if (PreviousNotConst->is(TT_PointerOrReference) ||2694        PreviousNotConst->endsSequence(tok::coloncolon,2695                                       TT_PointerOrReference)) {2696      return true;2697    }2698 2699    // MyClass a;2700    if (PreviousNotConst->isTypeName(LangOpts))2701      return true;2702 2703    // type[] a in Java2704    if (Style.isJava() && PreviousNotConst->is(tok::r_square))2705      return true;2706 2707    // const a = in JavaScript.2708    return Style.isJavaScript() && PreviousNotConst->is(tok::kw_const);2709  }2710 2711  /// Determine whether '(' is starting a C++ cast.2712  bool lParenStartsCppCast(const FormatToken &Tok) {2713    // C-style casts are only used in C++.2714    if (!IsCpp)2715      return false;2716 2717    FormatToken *LeftOfParens = Tok.getPreviousNonComment();2718    if (LeftOfParens && LeftOfParens->is(TT_TemplateCloser) &&2719        LeftOfParens->MatchingParen) {2720      auto *Prev = LeftOfParens->MatchingParen->getPreviousNonComment();2721      if (Prev &&2722          Prev->isOneOf(tok::kw_const_cast, tok::kw_dynamic_cast,2723                        tok::kw_reinterpret_cast, tok::kw_static_cast)) {2724        // FIXME: Maybe we should handle identifiers ending with "_cast",2725        // e.g. any_cast?2726        return true;2727      }2728    }2729    return false;2730  }2731 2732  /// Determine whether ')' is ending a cast.2733  bool rParenEndsCast(const FormatToken &Tok) {2734    assert(Tok.is(tok::r_paren));2735 2736    if (!Tok.MatchingParen || !Tok.Previous)2737      return false;2738 2739    // C-style casts are only used in C++, C# and Java.2740    if (!IsCpp && !Style.isCSharp() && !Style.isJava())2741      return false;2742 2743    const auto *LParen = Tok.MatchingParen;2744    const auto *BeforeRParen = Tok.Previous;2745    const auto *AfterRParen = Tok.Next;2746 2747    // Empty parens aren't casts and there are no casts at the end of the line.2748    if (BeforeRParen == LParen || !AfterRParen)2749      return false;2750 2751    if (LParen->is(TT_OverloadedOperatorLParen))2752      return false;2753 2754    auto *LeftOfParens = LParen->getPreviousNonComment();2755    if (LeftOfParens) {2756      // If there is a closing parenthesis left of the current2757      // parentheses, look past it as these might be chained casts.2758      if (LeftOfParens->is(tok::r_paren) &&2759          LeftOfParens->isNot(TT_CastRParen)) {2760        if (!LeftOfParens->MatchingParen ||2761            !LeftOfParens->MatchingParen->Previous) {2762          return false;2763        }2764        LeftOfParens = LeftOfParens->MatchingParen->Previous;2765      }2766 2767      if (LeftOfParens->is(tok::r_square)) {2768        //   delete[] (void *)ptr;2769        auto MayBeArrayDelete = [](FormatToken *Tok) -> FormatToken * {2770          if (Tok->isNot(tok::r_square))2771            return nullptr;2772 2773          Tok = Tok->getPreviousNonComment();2774          if (!Tok || Tok->isNot(tok::l_square))2775            return nullptr;2776 2777          Tok = Tok->getPreviousNonComment();2778          if (!Tok || Tok->isNot(tok::kw_delete))2779            return nullptr;2780          return Tok;2781        };2782        if (FormatToken *MaybeDelete = MayBeArrayDelete(LeftOfParens))2783          LeftOfParens = MaybeDelete;2784      }2785 2786      // The Condition directly below this one will see the operator arguments2787      // as a (void *foo) cast.2788      //   void operator delete(void *foo) ATTRIB;2789      if (LeftOfParens->Tok.getIdentifierInfo() && LeftOfParens->Previous &&2790          LeftOfParens->Previous->is(tok::kw_operator)) {2791        return false;2792      }2793 2794      // If there is an identifier (or with a few exceptions a keyword) right2795      // before the parentheses, this is unlikely to be a cast.2796      if (LeftOfParens->Tok.getIdentifierInfo() &&2797          LeftOfParens->isNoneOf(Keywords.kw_in, tok::kw_return, tok::kw_case,2798                                 tok::kw_delete, tok::kw_throw)) {2799        return false;2800      }2801 2802      // Certain other tokens right before the parentheses are also signals that2803      // this cannot be a cast.2804      if (LeftOfParens->isOneOf(tok::at, tok::r_square, TT_OverloadedOperator,2805                                TT_TemplateCloser, tok::ellipsis)) {2806        return false;2807      }2808    }2809 2810    if (AfterRParen->is(tok::question) ||2811        (AfterRParen->is(tok::ampamp) && !BeforeRParen->isTypeName(LangOpts))) {2812      return false;2813    }2814 2815    // `foreach((A a, B b) in someList)` should not be seen as a cast.2816    if (AfterRParen->is(Keywords.kw_in) && Style.isCSharp())2817      return false;2818 2819    // Functions which end with decorations like volatile, noexcept are unlikely2820    // to be casts.2821    if (AfterRParen->isOneOf(tok::kw_noexcept, tok::kw_volatile, tok::kw_const,2822                             tok::kw_requires, tok::kw_throw, tok::arrow,2823                             Keywords.kw_override, Keywords.kw_final) ||2824        isCppAttribute(IsCpp, *AfterRParen)) {2825      return false;2826    }2827 2828    // As Java has no function types, a "(" after the ")" likely means that this2829    // is a cast.2830    if (Style.isJava() && AfterRParen->is(tok::l_paren))2831      return true;2832 2833    // If a (non-string) literal follows, this is likely a cast.2834    if (AfterRParen->isOneOf(tok::kw_sizeof, tok::kw_alignof) ||2835        (AfterRParen->Tok.isLiteral() &&2836         AfterRParen->isNot(tok::string_literal))) {2837      return true;2838    }2839 2840    auto IsNonVariableTemplate = [](const FormatToken &Tok) {2841      if (Tok.isNot(TT_TemplateCloser))2842        return false;2843      const auto *Less = Tok.MatchingParen;2844      if (!Less)2845        return false;2846      const auto *BeforeLess = Less->getPreviousNonComment();2847      return BeforeLess && BeforeLess->isNot(TT_VariableTemplate);2848    };2849 2850    // Heuristically try to determine whether the parentheses contain a type.2851    auto IsQualifiedPointerOrReference = [](const FormatToken *T,2852                                            const LangOptions &LangOpts) {2853      // This is used to handle cases such as x = (foo *const)&y;2854      assert(!T->isTypeName(LangOpts) && "Should have already been checked");2855      // Strip trailing qualifiers such as const or volatile when checking2856      // whether the parens could be a cast to a pointer/reference type.2857      while (T) {2858        if (T->is(TT_AttributeRParen)) {2859          // Handle `x = (foo *__attribute__((foo)))&v;`:2860          assert(T->is(tok::r_paren));2861          assert(T->MatchingParen);2862          assert(T->MatchingParen->is(tok::l_paren));2863          assert(T->MatchingParen->is(TT_AttributeLParen));2864          if (const auto *Tok = T->MatchingParen->Previous;2865              Tok && Tok->isAttribute()) {2866            T = Tok->Previous;2867            continue;2868          }2869        } else if (T->is(TT_AttributeRSquare)) {2870          // Handle `x = (foo *[[clang::foo]])&v;`:2871          if (T->MatchingParen && T->MatchingParen->Previous) {2872            T = T->MatchingParen->Previous;2873            continue;2874          }2875        } else if (T->canBePointerOrReferenceQualifier()) {2876          T = T->Previous;2877          continue;2878        }2879        break;2880      }2881      return T && T->is(TT_PointerOrReference);2882    };2883 2884    bool ParensAreType = IsNonVariableTemplate(*BeforeRParen) ||2885                         BeforeRParen->is(TT_TypeDeclarationParen) ||2886                         BeforeRParen->isTypeName(LangOpts) ||2887                         IsQualifiedPointerOrReference(BeforeRParen, LangOpts);2888    bool ParensCouldEndDecl =2889        AfterRParen->isOneOf(tok::equal, tok::semi, tok::l_brace, tok::greater);2890    if (ParensAreType && !ParensCouldEndDecl)2891      return true;2892 2893    // At this point, we heuristically assume that there are no casts at the2894    // start of the line. We assume that we have found most cases where there2895    // are by the logic above, e.g. "(void)x;".2896    if (!LeftOfParens)2897      return false;2898 2899    // Certain token types inside the parentheses mean that this can't be a2900    // cast.2901    for (const auto *Token = LParen->Next; Token != &Tok; Token = Token->Next)2902      if (Token->is(TT_BinaryOperator))2903        return false;2904 2905    // If the following token is an identifier or 'this', this is a cast. All2906    // cases where this can be something else are handled above.2907    if (AfterRParen->isOneOf(tok::identifier, tok::kw_this))2908      return true;2909 2910    // Look for a cast `( x ) (`, where x may be a qualified identifier.2911    if (AfterRParen->is(tok::l_paren)) {2912      for (const auto *Prev = BeforeRParen; Prev->is(tok::identifier);) {2913        Prev = Prev->Previous;2914        if (Prev->is(tok::coloncolon))2915          Prev = Prev->Previous;2916        if (Prev == LParen)2917          return true;2918      }2919    }2920 2921    if (!AfterRParen->Next)2922      return false;2923 2924    if (AfterRParen->is(tok::l_brace) &&2925        AfterRParen->getBlockKind() == BK_BracedInit) {2926      return true;2927    }2928 2929    // If the next token after the parenthesis is a unary operator, assume2930    // that this is cast, unless there are unexpected tokens inside the2931    // parenthesis.2932    const bool NextIsAmpOrStar = AfterRParen->isOneOf(tok::amp, tok::star);2933    if (!(AfterRParen->isUnaryOperator() || NextIsAmpOrStar) ||2934        AfterRParen->is(tok::plus) ||2935        AfterRParen->Next->isNoneOf(tok::identifier, tok::numeric_constant)) {2936      return false;2937    }2938 2939    if (NextIsAmpOrStar &&2940        (AfterRParen->Next->is(tok::numeric_constant) || Line.InPPDirective)) {2941      return false;2942    }2943 2944    if (Line.InPPDirective && AfterRParen->is(tok::minus))2945      return false;2946 2947    const auto *Prev = BeforeRParen;2948 2949    // Look for a function pointer type, e.g. `(*)()`.2950    if (Prev->is(tok::r_paren)) {2951      if (Prev->is(TT_CastRParen))2952        return false;2953      Prev = Prev->MatchingParen;2954      if (!Prev)2955        return false;2956      Prev = Prev->Previous;2957      if (!Prev || Prev->isNot(tok::r_paren))2958        return false;2959      Prev = Prev->MatchingParen;2960      return Prev && Prev->is(TT_FunctionTypeLParen);2961    }2962 2963    // Search for unexpected tokens.2964    for (Prev = BeforeRParen; Prev != LParen; Prev = Prev->Previous)2965      if (Prev->isNoneOf(tok::kw_const, tok::identifier, tok::coloncolon))2966        return false;2967 2968    return true;2969  }2970 2971  /// Returns true if the token is used as a unary operator.2972  bool determineUnaryOperatorByUsage(const FormatToken &Tok) {2973    const FormatToken *PrevToken = Tok.getPreviousNonComment();2974    if (!PrevToken)2975      return true;2976 2977    // These keywords are deliberately not included here because they may2978    // precede only one of unary star/amp and plus/minus but not both.  They are2979    // either included in determineStarAmpUsage or determinePlusMinusCaretUsage.2980    //2981    // @ - It may be followed by a unary `-` in Objective-C literals. We don't2982    //   know how they can be followed by a star or amp.2983    if (PrevToken->isOneOf(2984            TT_ConditionalExpr, tok::l_paren, tok::comma, tok::colon, tok::semi,2985            tok::equal, tok::question, tok::l_square, tok::l_brace,2986            tok::kw_case, tok::kw_co_await, tok::kw_co_return, tok::kw_co_yield,2987            tok::kw_delete, tok::kw_return, tok::kw_throw)) {2988      return true;2989    }2990 2991    // We put sizeof here instead of only in determineStarAmpUsage. In the cases2992    // where the unary `+` operator is overloaded, it is reasonable to write2993    // things like `sizeof +x`. Like commit 446d6ec996c6c3.2994    if (PrevToken->is(tok::kw_sizeof))2995      return true;2996 2997    // A sequence of leading unary operators.2998    if (PrevToken->isOneOf(TT_CastRParen, TT_UnaryOperator))2999      return true;3000 3001    // There can't be two consecutive binary operators.3002    if (PrevToken->is(TT_BinaryOperator))3003      return true;3004 3005    return false;3006  }3007 3008  /// Return the type of the given token assuming it is * or &.3009  TokenType determineStarAmpUsage(const FormatToken &Tok, bool IsExpression,3010                                  bool InTemplateArgument) {3011    if (Style.isJavaScript())3012      return TT_BinaryOperator;3013 3014    // && in C# must be a binary operator.3015    if (Style.isCSharp() && Tok.is(tok::ampamp))3016      return TT_BinaryOperator;3017 3018    if (Style.isVerilog()) {3019      // In Verilog, `*` can only be a binary operator.  `&` can be either unary3020      // or binary.  `*` also includes `*>` in module path declarations in3021      // specify blocks because merged tokens take the type of the first one by3022      // default.3023      if (Tok.is(tok::star))3024        return TT_BinaryOperator;3025      return determineUnaryOperatorByUsage(Tok) ? TT_UnaryOperator3026                                                : TT_BinaryOperator;3027    }3028 3029    const FormatToken *PrevToken = Tok.getPreviousNonComment();3030    if (!PrevToken)3031      return TT_UnaryOperator;3032    if (PrevToken->isTypeName(LangOpts))3033      return TT_PointerOrReference;3034    if (PrevToken->isPlacementOperator() && Tok.is(tok::ampamp))3035      return TT_BinaryOperator;3036 3037    auto *NextToken = Tok.getNextNonComment();3038    if (!NextToken)3039      return TT_PointerOrReference;3040    if (NextToken->is(tok::greater)) {3041      NextToken->setFinalizedType(TT_TemplateCloser);3042      return TT_PointerOrReference;3043    }3044 3045    if (InTemplateArgument && NextToken->is(tok::kw_noexcept))3046      return TT_BinaryOperator;3047 3048    if (NextToken->isOneOf(tok::arrow, tok::equal, tok::comma, tok::r_paren,3049                           TT_RequiresClause) ||3050        (NextToken->is(tok::kw_noexcept) && !IsExpression) ||3051        NextToken->canBePointerOrReferenceQualifier() ||3052        (NextToken->is(tok::l_brace) && !NextToken->getNextNonComment())) {3053      return TT_PointerOrReference;3054    }3055 3056    if (PrevToken->is(tok::coloncolon))3057      return TT_PointerOrReference;3058 3059    if (PrevToken->is(tok::r_paren) && PrevToken->is(TT_TypeDeclarationParen))3060      return TT_PointerOrReference;3061 3062    if (determineUnaryOperatorByUsage(Tok))3063      return TT_UnaryOperator;3064 3065    if (NextToken->is(tok::l_square) && NextToken->isNot(TT_LambdaLSquare))3066      return TT_PointerOrReference;3067    if (NextToken->is(tok::kw_operator) && !IsExpression)3068      return TT_PointerOrReference;3069    if (NextToken->isOneOf(tok::comma, tok::semi))3070      return TT_PointerOrReference;3071 3072    // After right braces, star tokens are likely to be pointers to struct,3073    // union, or class.3074    //   struct {} *ptr;3075    // This by itself is not sufficient to distinguish from multiplication3076    // following a brace-initialized expression, as in:3077    // int i = int{42} * 2;3078    // In the struct case, the part of the struct declaration until the `{` and3079    // the `}` are put on separate unwrapped lines; in the brace-initialized3080    // case, the matching `{` is on the same unwrapped line, so check for the3081    // presence of the matching brace to distinguish between those.3082    if (PrevToken->is(tok::r_brace) && Tok.is(tok::star) &&3083        !PrevToken->MatchingParen) {3084      return TT_PointerOrReference;3085    }3086 3087    if (PrevToken->endsSequence(tok::r_square, tok::l_square, tok::kw_delete))3088      return TT_UnaryOperator;3089 3090    if (PrevToken->Tok.isLiteral() ||3091        PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::kw_true,3092                           tok::kw_false, tok::r_brace)) {3093      return TT_BinaryOperator;3094    }3095 3096    const FormatToken *NextNonParen = NextToken;3097    while (NextNonParen && NextNonParen->is(tok::l_paren))3098      NextNonParen = NextNonParen->getNextNonComment();3099    if (NextNonParen && (NextNonParen->Tok.isLiteral() ||3100                         NextNonParen->isOneOf(tok::kw_true, tok::kw_false) ||3101                         NextNonParen->isUnaryOperator())) {3102      return TT_BinaryOperator;3103    }3104 3105    // If we know we're in a template argument, there are no named declarations.3106    // Thus, having an identifier on the right-hand side indicates a binary3107    // operator.3108    if (InTemplateArgument && NextToken->Tok.isAnyIdentifier())3109      return TT_BinaryOperator;3110 3111    // "&&" followed by "(", "*", or "&" is quite unlikely to be two successive3112    // unary "&".3113    if (Tok.is(tok::ampamp) &&3114        NextToken->isOneOf(tok::l_paren, tok::star, tok::amp)) {3115      return TT_BinaryOperator;3116    }3117 3118    // This catches some cases where evaluation order is used as control flow:3119    //   aaa && aaa->f();3120    // Or expressions like:3121    //   width * height * length3122    if (NextToken->Tok.isAnyIdentifier()) {3123      auto *NextNextToken = NextToken->getNextNonComment();3124      if (NextNextToken) {3125        if (NextNextToken->is(tok::arrow))3126          return TT_BinaryOperator;3127        if (NextNextToken->isPointerOrReference() &&3128            !NextToken->isObjCLifetimeQualifier(Style)) {3129          NextNextToken->setFinalizedType(TT_BinaryOperator);3130          return TT_BinaryOperator;3131        }3132      }3133    }3134 3135    // It is very unlikely that we are going to find a pointer or reference type3136    // definition on the RHS of an assignment.3137    if (IsExpression && !Contexts.back().CaretFound &&3138        Line.getFirstNonComment()->isNot(3139            TT_RequiresClauseInARequiresExpression)) {3140      return TT_BinaryOperator;3141    }3142 3143    // Opeartors at class scope are likely pointer or reference members.3144    if (!Scopes.empty() && Scopes.back() == ST_Class)3145      return TT_PointerOrReference;3146 3147    // Tokens that indicate member access or chained operator& use.3148    auto IsChainedOperatorAmpOrMember = [](const FormatToken *token) {3149      return !token || token->isOneOf(tok::amp, tok::period, tok::arrow,3150                                      tok::arrowstar, tok::periodstar);3151    };3152 3153    // It's more likely that & represents operator& than an uninitialized3154    // reference.3155    if (Tok.is(tok::amp) && PrevToken->Tok.isAnyIdentifier() &&3156        IsChainedOperatorAmpOrMember(PrevToken->getPreviousNonComment()) &&3157        NextToken && NextToken->Tok.isAnyIdentifier()) {3158      if (auto NextNext = NextToken->getNextNonComment();3159          NextNext &&3160          (IsChainedOperatorAmpOrMember(NextNext) || NextNext->is(tok::semi))) {3161        return TT_BinaryOperator;3162      }3163    }3164 3165    if (Line.Type == LT_SimpleRequirement ||3166        (!Scopes.empty() && Scopes.back() == ST_CompoundRequirement)) {3167      return TT_BinaryOperator;3168    }3169 3170    return TT_PointerOrReference;3171  }3172 3173  TokenType determinePlusMinusCaretUsage(const FormatToken &Tok) {3174    if (determineUnaryOperatorByUsage(Tok))3175      return TT_UnaryOperator;3176 3177    const FormatToken *PrevToken = Tok.getPreviousNonComment();3178    if (!PrevToken)3179      return TT_UnaryOperator;3180 3181    if (PrevToken->is(tok::at))3182      return TT_UnaryOperator;3183 3184    // Fall back to marking the token as binary operator.3185    return TT_BinaryOperator;3186  }3187 3188  /// Determine whether ++/-- are pre- or post-increments/-decrements.3189  TokenType determineIncrementUsage(const FormatToken &Tok) {3190    const FormatToken *PrevToken = Tok.getPreviousNonComment();3191    if (!PrevToken || PrevToken->is(TT_CastRParen))3192      return TT_UnaryOperator;3193    if (PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::identifier))3194      return TT_TrailingUnaryOperator;3195 3196    return TT_UnaryOperator;3197  }3198 3199  SmallVector<Context, 8> Contexts;3200 3201  const FormatStyle &Style;3202  AnnotatedLine &Line;3203  FormatToken *CurrentToken;3204  bool AutoFound;3205  bool IsCpp;3206  LangOptions LangOpts;3207  const AdditionalKeywords &Keywords;3208 3209  SmallVector<ScopeType> &Scopes;3210 3211  // Set of "<" tokens that do not open a template parameter list. If parseAngle3212  // determines that a specific token can't be a template opener, it will make3213  // same decision irrespective of the decisions for tokens leading up to it.3214  // Store this information to prevent this from causing exponential runtime.3215  llvm::SmallPtrSet<FormatToken *, 16> NonTemplateLess;3216 3217  int TemplateDeclarationDepth;3218};3219 3220static const int PrecedenceUnaryOperator = prec::PointerToMember + 1;3221static const int PrecedenceArrowAndPeriod = prec::PointerToMember + 2;3222 3223/// Parses binary expressions by inserting fake parenthesis based on3224/// operator precedence.3225class ExpressionParser {3226public:3227  ExpressionParser(const FormatStyle &Style, const AdditionalKeywords &Keywords,3228                   AnnotatedLine &Line)3229      : Style(Style), Keywords(Keywords), Line(Line), Current(Line.First) {}3230 3231  /// Parse expressions with the given operator precedence.3232  void parse(int Precedence = 0) {3233    // Skip 'return' and ObjC selector colons as they are not part of a binary3234    // expression.3235    while (Current && (Current->is(tok::kw_return) ||3236                       (Current->is(tok::colon) &&3237                        Current->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)))) {3238      next();3239    }3240 3241    if (!Current || Precedence > PrecedenceArrowAndPeriod)3242      return;3243 3244    // Conditional expressions need to be parsed separately for proper nesting.3245    if (Precedence == prec::Conditional) {3246      parseConditionalExpr();3247      return;3248    }3249 3250    // Parse unary operators, which all have a higher precedence than binary3251    // operators.3252    if (Precedence == PrecedenceUnaryOperator) {3253      parseUnaryOperator();3254      return;3255    }3256 3257    FormatToken *Start = Current;3258    FormatToken *LatestOperator = nullptr;3259    unsigned OperatorIndex = 0;3260    // The first name of the current type in a port list.3261    FormatToken *VerilogFirstOfType = nullptr;3262 3263    while (Current) {3264      // In Verilog ports in a module header that don't have a type take the3265      // type of the previous one.  For example,3266      //   module a(output b,3267      //                   c,3268      //            output d);3269      // In this case there need to be fake parentheses around b and c.3270      if (Style.isVerilog() && Precedence == prec::Comma) {3271        VerilogFirstOfType =3272            verilogGroupDecl(VerilogFirstOfType, LatestOperator);3273      }3274 3275      // Consume operators with higher precedence.3276      parse(Precedence + 1);3277 3278      int CurrentPrecedence = getCurrentPrecedence();3279      if (Style.BreakBinaryOperations == FormatStyle::BBO_OnePerLine &&3280          CurrentPrecedence > prec::Conditional &&3281          CurrentPrecedence < prec::PointerToMember) {3282        // When BreakBinaryOperations is set to BreakAll,3283        // all operations will be on the same line or on individual lines.3284        // Override precedence to avoid adding fake parenthesis which could3285        // group operations of a different precedence level on the same line3286        CurrentPrecedence = prec::Additive;3287      }3288 3289      if (Precedence == CurrentPrecedence && Current &&3290          Current->is(TT_SelectorName)) {3291        if (LatestOperator)3292          addFakeParenthesis(Start, prec::Level(Precedence));3293        Start = Current;3294      }3295 3296      if ((Style.isCSharp() || Style.isJavaScript() || Style.isJava()) &&3297          Precedence == prec::Additive && Current) {3298        // A string can be broken without parentheses around it when it is3299        // already in a sequence of strings joined by `+` signs.3300        FormatToken *Prev = Current->getPreviousNonComment();3301        if (Prev && Prev->is(tok::string_literal) &&3302            (Prev == Start || Prev->endsSequence(tok::string_literal, tok::plus,3303                                                 TT_StringInConcatenation))) {3304          Prev->setType(TT_StringInConcatenation);3305        }3306      }3307 3308      // At the end of the line or when an operator with lower precedence is3309      // found, insert fake parenthesis and return.3310      if (!Current ||3311          (Current->closesScope() &&3312           (Current->MatchingParen || Current->is(TT_TemplateString))) ||3313          (CurrentPrecedence != -1 && CurrentPrecedence < Precedence) ||3314          (CurrentPrecedence == prec::Conditional &&3315           Precedence == prec::Assignment && Current->is(tok::colon))) {3316        break;3317      }3318 3319      // Consume scopes: (), [], <> and {}3320      // In addition to that we handle require clauses as scope, so that the3321      // constraints in that are correctly indented.3322      if (Current->opensScope() ||3323          Current->isOneOf(TT_RequiresClause,3324                           TT_RequiresClauseInARequiresExpression)) {3325        // In fragment of a JavaScript template string can look like '}..${' and3326        // thus close a scope and open a new one at the same time.3327        while (Current && (!Current->closesScope() || Current->opensScope())) {3328          next();3329          parse();3330        }3331        next();3332      } else {3333        // Operator found.3334        if (CurrentPrecedence == Precedence) {3335          if (LatestOperator)3336            LatestOperator->NextOperator = Current;3337          LatestOperator = Current;3338          Current->OperatorIndex = OperatorIndex;3339          ++OperatorIndex;3340        }3341        next(/*SkipPastLeadingComments=*/Precedence > 0);3342      }3343    }3344 3345    // Group variables of the same type.3346    if (Style.isVerilog() && Precedence == prec::Comma && VerilogFirstOfType)3347      addFakeParenthesis(VerilogFirstOfType, prec::Comma);3348 3349    if (LatestOperator && (Current || Precedence > 0)) {3350      // The requires clauses do not neccessarily end in a semicolon or a brace,3351      // but just go over to struct/class or a function declaration, we need to3352      // intervene so that the fake right paren is inserted correctly.3353      auto End =3354          (Start->Previous &&3355           Start->Previous->isOneOf(TT_RequiresClause,3356                                    TT_RequiresClauseInARequiresExpression))3357              ? [this]() {3358                  auto Ret = Current ? Current : Line.Last;3359                  while (!Ret->ClosesRequiresClause && Ret->Previous)3360                    Ret = Ret->Previous;3361                  return Ret;3362                }()3363              : nullptr;3364 3365      if (Precedence == PrecedenceArrowAndPeriod) {3366        // Call expressions don't have a binary operator precedence.3367        addFakeParenthesis(Start, prec::Unknown, End);3368      } else {3369        addFakeParenthesis(Start, prec::Level(Precedence), End);3370      }3371    }3372  }3373 3374private:3375  /// Gets the precedence (+1) of the given token for binary operators3376  /// and other tokens that we treat like binary operators.3377  int getCurrentPrecedence() {3378    if (Current) {3379      const FormatToken *NextNonComment = Current->getNextNonComment();3380      if (Current->is(TT_ConditionalExpr))3381        return prec::Conditional;3382      if (NextNonComment && Current->is(TT_SelectorName) &&3383          (NextNonComment->isOneOf(TT_DictLiteral, TT_JsTypeColon) ||3384           (Style.isProto() && NextNonComment->is(tok::less)))) {3385        return prec::Assignment;3386      }3387      if (Current->is(TT_JsComputedPropertyName))3388        return prec::Assignment;3389      if (Current->is(TT_LambdaArrow))3390        return prec::Comma;3391      if (Current->is(TT_FatArrow))3392        return prec::Assignment;3393      if (Current->isOneOf(tok::semi, TT_InlineASMColon, TT_SelectorName) ||3394          (Current->is(tok::comment) && NextNonComment &&3395           NextNonComment->is(TT_SelectorName))) {3396        return 0;3397      }3398      if (Current->is(TT_RangeBasedForLoopColon))3399        return prec::Comma;3400      if ((Style.isJava() || Style.isJavaScript()) &&3401          Current->is(Keywords.kw_instanceof)) {3402        return prec::Relational;3403      }3404      if (Style.isJavaScript() &&3405          Current->isOneOf(Keywords.kw_in, Keywords.kw_as)) {3406        return prec::Relational;3407      }3408      if (Current->isOneOf(TT_BinaryOperator, tok::comma))3409        return Current->getPrecedence();3410      if (Current->isOneOf(tok::period, tok::arrow) &&3411          Current->isNot(TT_TrailingReturnArrow)) {3412        return PrecedenceArrowAndPeriod;3413      }3414      if ((Style.isJava() || Style.isJavaScript()) &&3415          Current->isOneOf(Keywords.kw_extends, Keywords.kw_implements,3416                           Keywords.kw_throws)) {3417        return 0;3418      }3419      // In Verilog case labels are not on separate lines straight out of3420      // UnwrappedLineParser. The colon is not part of an expression.3421      if (Style.isVerilog() && Current->is(tok::colon))3422        return 0;3423    }3424    return -1;3425  }3426 3427  void addFakeParenthesis(FormatToken *Start, prec::Level Precedence,3428                          FormatToken *End = nullptr) {3429    // Do not assign fake parenthesis to tokens that are part of an3430    // unexpanded macro call. The line within the macro call contains3431    // the parenthesis and commas, and we will not find operators within3432    // that structure.3433    if (Start->MacroParent)3434      return;3435 3436    Start->FakeLParens.push_back(Precedence);3437    if (Precedence > prec::Unknown)3438      Start->StartsBinaryExpression = true;3439    if (!End && Current)3440      End = Current->getPreviousNonComment();3441    if (End) {3442      ++End->FakeRParens;3443      if (Precedence > prec::Unknown)3444        End->EndsBinaryExpression = true;3445    }3446  }3447 3448  /// Parse unary operator expressions and surround them with fake3449  /// parentheses if appropriate.3450  void parseUnaryOperator() {3451    SmallVector<FormatToken *, 2> Tokens;3452    while (Current && Current->is(TT_UnaryOperator)) {3453      Tokens.push_back(Current);3454      next();3455    }3456    parse(PrecedenceArrowAndPeriod);3457    for (FormatToken *Token : reverse(Tokens)) {3458      // The actual precedence doesn't matter.3459      addFakeParenthesis(Token, prec::Unknown);3460    }3461  }3462 3463  void parseConditionalExpr() {3464    while (Current && Current->isTrailingComment())3465      next();3466    FormatToken *Start = Current;3467    parse(prec::LogicalOr);3468    if (!Current || Current->isNot(tok::question))3469      return;3470    next();3471    parse(prec::Assignment);3472    if (!Current || Current->isNot(TT_ConditionalExpr))3473      return;3474    next();3475    parse(prec::Assignment);3476    addFakeParenthesis(Start, prec::Conditional);3477  }3478 3479  void next(bool SkipPastLeadingComments = true) {3480    if (Current)3481      Current = Current->Next;3482    while (Current &&3483           (Current->NewlinesBefore == 0 || SkipPastLeadingComments) &&3484           Current->isTrailingComment()) {3485      Current = Current->Next;3486    }3487  }3488 3489  // Add fake parenthesis around declarations of the same type for example in a3490  // module prototype. Return the first port / variable of the current type.3491  FormatToken *verilogGroupDecl(FormatToken *FirstOfType,3492                                FormatToken *PreviousComma) {3493    if (!Current)3494      return nullptr;3495 3496    FormatToken *Start = Current;3497 3498    // Skip attributes.3499    while (Start->startsSequence(tok::l_paren, tok::star)) {3500      if (!(Start = Start->MatchingParen) ||3501          !(Start = Start->getNextNonComment())) {3502        return nullptr;3503      }3504    }3505 3506    FormatToken *Tok = Start;3507 3508    if (Tok->is(Keywords.kw_assign))3509      Tok = Tok->getNextNonComment();3510 3511    // Skip any type qualifiers to find the first identifier. It may be either a3512    // new type name or a variable name. There can be several type qualifiers3513    // preceding a variable name, and we can not tell them apart by looking at3514    // the word alone since a macro can be defined as either a type qualifier or3515    // a variable name. Thus we use the last word before the dimensions instead3516    // of the first word as the candidate for the variable or type name.3517    FormatToken *First = nullptr;3518    while (Tok) {3519      FormatToken *Next = Tok->getNextNonComment();3520 3521      if (Tok->is(tok::hash)) {3522        // Start of a macro expansion.3523        First = Tok;3524        Tok = Next;3525        if (Tok)3526          Tok = Tok->getNextNonComment();3527      } else if (Tok->is(tok::hashhash)) {3528        // Concatenation. Skip.3529        Tok = Next;3530        if (Tok)3531          Tok = Tok->getNextNonComment();3532      } else if (Keywords.isVerilogQualifier(*Tok) ||3533                 Keywords.isVerilogIdentifier(*Tok)) {3534        First = Tok;3535        Tok = Next;3536        // The name may have dots like `interface_foo.modport_foo`.3537        while (Tok && Tok->isOneOf(tok::period, tok::coloncolon) &&3538               (Tok = Tok->getNextNonComment())) {3539          if (Keywords.isVerilogIdentifier(*Tok))3540            Tok = Tok->getNextNonComment();3541        }3542      } else if (!Next) {3543        Tok = nullptr;3544      } else if (Tok->is(tok::l_paren)) {3545        // Make sure the parenthesized list is a drive strength. Otherwise the3546        // statement may be a module instantiation in which case we have already3547        // found the instance name.3548        if (Next->isOneOf(3549                Keywords.kw_highz0, Keywords.kw_highz1, Keywords.kw_large,3550                Keywords.kw_medium, Keywords.kw_pull0, Keywords.kw_pull1,3551                Keywords.kw_small, Keywords.kw_strong0, Keywords.kw_strong1,3552                Keywords.kw_supply0, Keywords.kw_supply1, Keywords.kw_weak0,3553                Keywords.kw_weak1)) {3554          Tok->setType(TT_VerilogStrength);3555          Tok = Tok->MatchingParen;3556          if (Tok) {3557            Tok->setType(TT_VerilogStrength);3558            Tok = Tok->getNextNonComment();3559          }3560        } else {3561          break;3562        }3563      } else if (Tok->is(Keywords.kw_verilogHash)) {3564        // Delay control.3565        if (Next->is(tok::l_paren))3566          Next = Next->MatchingParen;3567        if (Next)3568          Tok = Next->getNextNonComment();3569      } else {3570        break;3571      }3572    }3573 3574    // Find the second identifier. If it exists it will be the name.3575    FormatToken *Second = nullptr;3576    // Dimensions.3577    while (Tok && Tok->is(tok::l_square) && (Tok = Tok->MatchingParen))3578      Tok = Tok->getNextNonComment();3579    if (Tok && (Tok->is(tok::hash) || Keywords.isVerilogIdentifier(*Tok)))3580      Second = Tok;3581 3582    // If the second identifier doesn't exist and there are qualifiers, the type3583    // is implied.3584    FormatToken *TypedName = nullptr;3585    if (Second) {3586      TypedName = Second;3587      if (First && First->is(TT_Unknown))3588        First->setType(TT_VerilogDimensionedTypeName);3589    } else if (First != Start) {3590      // If 'First' is null, then this isn't a declaration, 'TypedName' gets set3591      // to null as intended.3592      TypedName = First;3593    }3594 3595    if (TypedName) {3596      // This is a declaration with a new type.3597      if (TypedName->is(TT_Unknown))3598        TypedName->setType(TT_StartOfName);3599      // Group variables of the previous type.3600      if (FirstOfType && PreviousComma) {3601        PreviousComma->setType(TT_VerilogTypeComma);3602        addFakeParenthesis(FirstOfType, prec::Comma, PreviousComma->Previous);3603      }3604 3605      FirstOfType = TypedName;3606 3607      // Don't let higher precedence handle the qualifiers. For example if we3608      // have:3609      //    parameter x = 03610      // We skip `parameter` here. This way the fake parentheses for the3611      // assignment will be around `x = 0`.3612      while (Current && Current != FirstOfType) {3613        if (Current->opensScope()) {3614          next();3615          parse();3616        }3617        next();3618      }3619    }3620 3621    return FirstOfType;3622  }3623 3624  const FormatStyle &Style;3625  const AdditionalKeywords &Keywords;3626  const AnnotatedLine &Line;3627  FormatToken *Current;3628};3629 3630} // end anonymous namespace3631 3632void TokenAnnotator::setCommentLineLevels(3633    SmallVectorImpl<AnnotatedLine *> &Lines) const {3634  const AnnotatedLine *NextNonCommentLine = nullptr;3635  for (AnnotatedLine *Line : reverse(Lines)) {3636    assert(Line->First);3637 3638    // If the comment is currently aligned with the line immediately following3639    // it, that's probably intentional and we should keep it.3640    if (NextNonCommentLine && NextNonCommentLine->First->NewlinesBefore < 2 &&3641        Line->isComment() && !isClangFormatOff(Line->First->TokenText) &&3642        NextNonCommentLine->First->OriginalColumn ==3643            Line->First->OriginalColumn) {3644      const bool PPDirectiveOrImportStmt =3645          NextNonCommentLine->Type == LT_PreprocessorDirective ||3646          NextNonCommentLine->Type == LT_ImportStatement;3647      if (PPDirectiveOrImportStmt)3648        Line->Type = LT_CommentAbovePPDirective;3649      // Align comments for preprocessor lines with the # in column 0 if3650      // preprocessor lines are not indented. Otherwise, align with the next3651      // line.3652      Line->Level = Style.IndentPPDirectives < FormatStyle::PPDIS_BeforeHash &&3653                            PPDirectiveOrImportStmt3654                        ? 03655                        : NextNonCommentLine->Level;3656    } else {3657      NextNonCommentLine = Line->First->isNot(tok::r_brace) ? Line : nullptr;3658    }3659 3660    setCommentLineLevels(Line->Children);3661  }3662}3663 3664static unsigned maxNestingDepth(const AnnotatedLine &Line) {3665  unsigned Result = 0;3666  for (const auto *Tok = Line.First; Tok; Tok = Tok->Next)3667    Result = std::max(Result, Tok->NestingLevel);3668  return Result;3669}3670 3671// Returns the name of a function with no return type, e.g. a constructor or3672// destructor.3673static FormatToken *getFunctionName(const AnnotatedLine &Line,3674                                    FormatToken *&OpeningParen) {3675  for (FormatToken *Tok = Line.getFirstNonComment(), *Name = nullptr; Tok;3676       Tok = Tok->getNextNonComment()) {3677    // Skip C++11 attributes both before and after the function name.3678    if (Tok->is(TT_AttributeLSquare)) {3679      Tok = Tok->MatchingParen;3680      if (!Tok)3681        break;3682      continue;3683    }3684 3685    // Make sure the name is followed by a pair of parentheses.3686    if (Name) {3687      if (Tok->is(tok::l_paren) && Tok->is(TT_Unknown) && Tok->MatchingParen) {3688        OpeningParen = Tok;3689        return Name;3690      }3691      return nullptr;3692    }3693 3694    // Skip keywords that may precede the constructor/destructor name.3695    if (Tok->isOneOf(tok::kw_friend, tok::kw_inline, tok::kw_virtual,3696                     tok::kw_constexpr, tok::kw_consteval, tok::kw_explicit)) {3697      continue;3698    }3699 3700    // A qualified name may start from the global namespace.3701    if (Tok->is(tok::coloncolon)) {3702      Tok = Tok->Next;3703      if (!Tok)3704        break;3705    }3706 3707    // Skip to the unqualified part of the name.3708    while (Tok->startsSequence(tok::identifier, tok::coloncolon)) {3709      assert(Tok->Next);3710      Tok = Tok->Next->Next;3711      if (!Tok)3712        return nullptr;3713    }3714 3715    // Skip the `~` if a destructor name.3716    if (Tok->is(tok::tilde)) {3717      Tok = Tok->Next;3718      if (!Tok)3719        break;3720    }3721 3722    // Make sure the name is not already annotated, e.g. as NamespaceMacro.3723    if (Tok->isNot(tok::identifier) || Tok->isNot(TT_Unknown))3724      break;3725 3726    Name = Tok;3727  }3728 3729  return nullptr;3730}3731 3732// Checks if Tok is a constructor/destructor name qualified by its class name.3733static bool isCtorOrDtorName(const FormatToken *Tok) {3734  assert(Tok && Tok->is(tok::identifier));3735  const auto *Prev = Tok->Previous;3736 3737  if (Prev && Prev->is(tok::tilde))3738    Prev = Prev->Previous;3739 3740  if (!Prev || !Prev->endsSequence(tok::coloncolon, tok::identifier))3741    return false;3742 3743  assert(Prev->Previous);3744  return Prev->Previous->TokenText == Tok->TokenText;3745}3746 3747void TokenAnnotator::annotate(AnnotatedLine &Line) {3748  if (!Line.InMacroBody)3749    MacroBodyScopes.clear();3750 3751  auto &ScopeStack = Line.InMacroBody ? MacroBodyScopes : Scopes;3752  AnnotatingParser Parser(Style, Line, Keywords, ScopeStack);3753  Line.Type = Parser.parseLine();3754 3755  if (!Line.Children.empty()) {3756    ScopeStack.push_back(ST_Other);3757    const bool InRequiresExpression = Line.Type == LT_RequiresExpression;3758    for (auto &Child : Line.Children) {3759      if (InRequiresExpression &&3760          Child->First->isNoneOf(tok::kw_typename, tok::kw_requires,3761                                 TT_CompoundRequirementLBrace)) {3762        Child->Type = LT_SimpleRequirement;3763      }3764      annotate(*Child);3765    }3766    // ScopeStack can become empty if Child has an unmatched `}`.3767    if (!ScopeStack.empty())3768      ScopeStack.pop_back();3769  }3770 3771  // With very deep nesting, ExpressionParser uses lots of stack and the3772  // formatting algorithm is very slow. We're not going to do a good job here3773  // anyway - it's probably generated code being formatted by mistake.3774  // Just skip the whole line.3775  if (maxNestingDepth(Line) > 50)3776    Line.Type = LT_Invalid;3777 3778  if (Line.Type == LT_Invalid)3779    return;3780 3781  ExpressionParser ExprParser(Style, Keywords, Line);3782  ExprParser.parse();3783 3784  if (IsCpp) {3785    FormatToken *OpeningParen = nullptr;3786    auto *Tok = getFunctionName(Line, OpeningParen);3787    if (Tok && ((!ScopeStack.empty() && ScopeStack.back() == ST_Class) ||3788                Line.endsWith(TT_FunctionLBrace) || isCtorOrDtorName(Tok))) {3789      Tok->setFinalizedType(TT_CtorDtorDeclName);3790      assert(OpeningParen);3791      OpeningParen->setFinalizedType(TT_FunctionDeclarationLParen);3792    }3793  }3794 3795  if (Line.startsWith(TT_ObjCMethodSpecifier))3796    Line.Type = LT_ObjCMethodDecl;3797  else if (Line.startsWith(TT_ObjCDecl))3798    Line.Type = LT_ObjCDecl;3799  else if (Line.startsWith(TT_ObjCProperty))3800    Line.Type = LT_ObjCProperty;3801 3802  auto *First = Line.First;3803  First->SpacesRequiredBefore = 1;3804  First->CanBreakBefore = First->MustBreakBefore;3805}3806 3807// This function heuristically determines whether 'Current' starts the name of a3808// function declaration.3809static bool isFunctionDeclarationName(const LangOptions &LangOpts,3810                                      const FormatToken &Current,3811                                      const AnnotatedLine &Line,3812                                      FormatToken *&ClosingParen) {3813  if (Current.is(TT_FunctionDeclarationName))3814    return true;3815 3816  if (Current.isNoneOf(tok::identifier, tok::kw_operator))3817    return false;3818 3819  const auto *Prev = Current.getPreviousNonComment();3820  assert(Prev);3821 3822  const auto &Previous = *Prev;3823 3824  if (const auto *PrevPrev = Previous.getPreviousNonComment();3825      PrevPrev && PrevPrev->is(TT_ObjCDecl)) {3826    return false;3827  }3828 3829  auto skipOperatorName =3830      [&LangOpts](const FormatToken *Next) -> const FormatToken * {3831    for (; Next; Next = Next->Next) {3832      if (Next->is(TT_OverloadedOperatorLParen))3833        return Next;3834      if (Next->is(TT_OverloadedOperator))3835        continue;3836      if (Next->isPlacementOperator() || Next->is(tok::kw_co_await)) {3837        // For 'new[]' and 'delete[]'.3838        if (Next->Next &&3839            Next->Next->startsSequence(tok::l_square, tok::r_square)) {3840          Next = Next->Next->Next;3841        }3842        continue;3843      }3844      if (Next->startsSequence(tok::l_square, tok::r_square)) {3845        // For operator[]().3846        Next = Next->Next;3847        continue;3848      }3849      if ((Next->isTypeName(LangOpts) || Next->is(tok::identifier)) &&3850          Next->Next && Next->Next->isPointerOrReference()) {3851        // For operator void*(), operator char*(), operator Foo*().3852        Next = Next->Next;3853        continue;3854      }3855      if (Next->is(TT_TemplateOpener) && Next->MatchingParen) {3856        Next = Next->MatchingParen;3857        continue;3858      }3859 3860      break;3861    }3862    return nullptr;3863  };3864 3865  const auto *Next = Current.Next;3866  const bool IsCpp = LangOpts.CXXOperatorNames || LangOpts.C11;3867 3868  // Find parentheses of parameter list.3869  if (Current.is(tok::kw_operator)) {3870    if (Line.startsWith(tok::kw_friend))3871      return true;3872    if (Previous.Tok.getIdentifierInfo() &&3873        Previous.isNoneOf(tok::kw_return, tok::kw_co_return)) {3874      return true;3875    }3876    if (Previous.is(tok::r_paren) && Previous.is(TT_TypeDeclarationParen)) {3877      assert(Previous.MatchingParen);3878      assert(Previous.MatchingParen->is(tok::l_paren));3879      assert(Previous.MatchingParen->is(TT_TypeDeclarationParen));3880      return true;3881    }3882    if (!Previous.isPointerOrReference() && Previous.isNot(TT_TemplateCloser))3883      return false;3884    Next = skipOperatorName(Next);3885  } else {3886    if (Current.isNot(TT_StartOfName) || Current.NestingLevel != 0)3887      return false;3888    while (Next && Next->startsSequence(tok::hashhash, tok::identifier))3889      Next = Next->Next->Next;3890    for (; Next; Next = Next->Next) {3891      if (Next->is(TT_TemplateOpener) && Next->MatchingParen) {3892        Next = Next->MatchingParen;3893      } else if (Next->is(tok::coloncolon)) {3894        Next = Next->Next;3895        if (!Next)3896          return false;3897        if (Next->is(tok::kw_operator)) {3898          Next = skipOperatorName(Next->Next);3899          break;3900        }3901        if (Next->isNot(tok::identifier))3902          return false;3903      } else if (isCppAttribute(IsCpp, *Next)) {3904        Next = Next->MatchingParen;3905        if (!Next)3906          return false;3907      } else if (Next->is(tok::l_paren)) {3908        break;3909      } else {3910        return false;3911      }3912    }3913  }3914 3915  // Check whether parameter list can belong to a function declaration.3916  if (!Next || Next->isNot(tok::l_paren) || !Next->MatchingParen)3917    return false;3918  ClosingParen = Next->MatchingParen;3919  assert(ClosingParen->is(tok::r_paren));3920  // If the lines ends with "{", this is likely a function definition.3921  if (Line.Last->is(tok::l_brace))3922    return true;3923  if (Next->Next == ClosingParen)3924    return true; // Empty parentheses.3925  // If there is an &/&& after the r_paren, this is likely a function.3926  if (ClosingParen->Next && ClosingParen->Next->is(TT_PointerOrReference))3927    return true;3928 3929  // Check for K&R C function definitions (and C++ function definitions with3930  // unnamed parameters), e.g.:3931  //   int f(i)3932  //   {3933  //     return i + 1;3934  //   }3935  //   bool g(size_t = 0, bool b = false)3936  //   {3937  //     return !b;3938  //   }3939  if (IsCpp && Next->Next && Next->Next->is(tok::identifier) &&3940      !Line.endsWith(tok::semi)) {3941    return true;3942  }3943 3944  for (const FormatToken *Tok = Next->Next; Tok && Tok != ClosingParen;3945       Tok = Tok->Next) {3946    if (Tok->is(TT_TypeDeclarationParen))3947      return true;3948    if (Tok->isOneOf(tok::l_paren, TT_TemplateOpener) && Tok->MatchingParen) {3949      Tok = Tok->MatchingParen;3950      continue;3951    }3952    if (Tok->is(tok::kw_const) || Tok->isTypeName(LangOpts) ||3953        Tok->isOneOf(TT_PointerOrReference, TT_StartOfName, tok::ellipsis)) {3954      return true;3955    }3956    if (Tok->isOneOf(tok::l_brace, TT_ObjCMethodExpr) || Tok->Tok.isLiteral())3957      return false;3958  }3959  return false;3960}3961 3962bool TokenAnnotator::mustBreakForReturnType(const AnnotatedLine &Line) const {3963  assert(Line.MightBeFunctionDecl);3964 3965  if ((Style.BreakAfterReturnType == FormatStyle::RTBS_TopLevel ||3966       Style.BreakAfterReturnType == FormatStyle::RTBS_TopLevelDefinitions) &&3967      Line.Level > 0) {3968    return false;3969  }3970 3971  switch (Style.BreakAfterReturnType) {3972  case FormatStyle::RTBS_None:3973  case FormatStyle::RTBS_Automatic:3974  case FormatStyle::RTBS_ExceptShortType:3975    return false;3976  case FormatStyle::RTBS_All:3977  case FormatStyle::RTBS_TopLevel:3978    return true;3979  case FormatStyle::RTBS_AllDefinitions:3980  case FormatStyle::RTBS_TopLevelDefinitions:3981    return Line.mightBeFunctionDefinition();3982  }3983 3984  return false;3985}3986 3987void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) const {3988  if (Line.Computed)3989    return;3990 3991  Line.Computed = true;3992 3993  for (AnnotatedLine *ChildLine : Line.Children)3994    calculateFormattingInformation(*ChildLine);3995 3996  auto *First = Line.First;3997  First->TotalLength = First->IsMultiline3998                           ? Style.ColumnLimit3999                           : Line.FirstStartColumn + First->ColumnWidth;4000  bool AlignArrayOfStructures =4001      (Style.AlignArrayOfStructures != FormatStyle::AIAS_None &&4002       Line.Type == LT_ArrayOfStructInitializer);4003  if (AlignArrayOfStructures)4004    calculateArrayInitializerColumnList(Line);4005 4006  const auto *FirstNonComment = Line.getFirstNonComment();4007  bool SeenName = false;4008  bool LineIsFunctionDeclaration = false;4009  FormatToken *AfterLastAttribute = nullptr;4010  FormatToken *ClosingParen = nullptr;4011 4012  for (auto *Tok = FirstNonComment && FirstNonComment->isNot(tok::kw_using)4013                       ? FirstNonComment->Next4014                       : nullptr;4015       Tok && Tok->isNot(BK_BracedInit); Tok = Tok->Next) {4016    if (Tok->is(TT_StartOfName))4017      SeenName = true;4018    if (Tok->Previous->EndsCppAttributeGroup)4019      AfterLastAttribute = Tok;4020    if (const bool IsCtorOrDtor = Tok->is(TT_CtorDtorDeclName);4021        IsCtorOrDtor ||4022        isFunctionDeclarationName(LangOpts, *Tok, Line, ClosingParen)) {4023      if (!IsCtorOrDtor)4024        Tok->setFinalizedType(TT_FunctionDeclarationName);4025      LineIsFunctionDeclaration = true;4026      SeenName = true;4027      if (ClosingParen) {4028        auto *OpeningParen = ClosingParen->MatchingParen;4029        assert(OpeningParen);4030        if (OpeningParen->is(TT_Unknown))4031          OpeningParen->setType(TT_FunctionDeclarationLParen);4032      }4033      break;4034    }4035  }4036 4037  if (IsCpp) {4038    if ((LineIsFunctionDeclaration ||4039         (FirstNonComment && FirstNonComment->is(TT_CtorDtorDeclName))) &&4040        Line.endsWith(tok::semi, tok::r_brace)) {4041      auto *Tok = Line.Last->Previous;4042      while (Tok->isNot(tok::r_brace))4043        Tok = Tok->Previous;4044      if (auto *LBrace = Tok->MatchingParen; LBrace && LBrace->is(TT_Unknown)) {4045        assert(LBrace->is(tok::l_brace));4046        Tok->setBlockKind(BK_Block);4047        LBrace->setBlockKind(BK_Block);4048        LBrace->setFinalizedType(TT_FunctionLBrace);4049      }4050    }4051 4052    if (SeenName && AfterLastAttribute &&4053        mustBreakAfterAttributes(*AfterLastAttribute, Style)) {4054      AfterLastAttribute->MustBreakBefore = true;4055      if (LineIsFunctionDeclaration)4056        Line.ReturnTypeWrapped = true;4057    }4058 4059    if (!LineIsFunctionDeclaration) {4060      // Annotate */&/&& in `operator` function calls as binary operators.4061      for (const auto *Tok = FirstNonComment; Tok; Tok = Tok->Next) {4062        if (Tok->isNot(tok::kw_operator))4063          continue;4064        do {4065          Tok = Tok->Next;4066        } while (Tok && Tok->isNot(TT_OverloadedOperatorLParen));4067        if (!Tok || !Tok->MatchingParen)4068          break;4069        const auto *LeftParen = Tok;4070        for (Tok = Tok->Next; Tok && Tok != LeftParen->MatchingParen;4071             Tok = Tok->Next) {4072          if (Tok->isNot(tok::identifier))4073            continue;4074          auto *Next = Tok->Next;4075          const bool NextIsBinaryOperator =4076              Next && Next->isPointerOrReference() && Next->Next &&4077              Next->Next->is(tok::identifier);4078          if (!NextIsBinaryOperator)4079            continue;4080          Next->setType(TT_BinaryOperator);4081          Tok = Next;4082        }4083      }4084    } else if (ClosingParen) {4085      for (auto *Tok = ClosingParen->Next; Tok; Tok = Tok->Next) {4086        if (Tok->is(TT_CtorInitializerColon))4087          break;4088        if (Tok->is(tok::arrow)) {4089          Tok->setType(TT_TrailingReturnArrow);4090          break;4091        }4092        if (Tok->isNot(TT_TrailingAnnotation))4093          continue;4094        const auto *Next = Tok->Next;4095        if (!Next || Next->isNot(tok::l_paren))4096          continue;4097        Tok = Next->MatchingParen;4098        if (!Tok)4099          break;4100      }4101    }4102  }4103 4104  if (First->is(TT_ElseLBrace)) {4105    First->CanBreakBefore = true;4106    First->MustBreakBefore = true;4107  }4108 4109  bool InFunctionDecl = Line.MightBeFunctionDecl;4110  bool InParameterList = false;4111  for (auto *Current = First->Next; Current; Current = Current->Next) {4112    const FormatToken *Prev = Current->Previous;4113    if (Current->is(TT_LineComment)) {4114      if (Prev->is(BK_BracedInit) && Prev->opensScope()) {4115        Current->SpacesRequiredBefore =4116            (Style.Cpp11BracedListStyle == FormatStyle::BLS_AlignFirstComment &&4117             !Style.SpacesInParensOptions.Other)4118                ? 04119                : 1;4120      } else if (Prev->is(TT_VerilogMultiLineListLParen)) {4121        Current->SpacesRequiredBefore = 0;4122      } else {4123        Current->SpacesRequiredBefore = Style.SpacesBeforeTrailingComments;4124      }4125 4126      // If we find a trailing comment, iterate backwards to determine whether4127      // it seems to relate to a specific parameter. If so, break before that4128      // parameter to avoid changing the comment's meaning. E.g. don't move 'b'4129      // to the previous line in:4130      //   SomeFunction(a,4131      //                b, // comment4132      //                c);4133      if (!Current->HasUnescapedNewline) {4134        for (FormatToken *Parameter = Current->Previous; Parameter;4135             Parameter = Parameter->Previous) {4136          if (Parameter->isOneOf(tok::comment, tok::r_brace))4137            break;4138          if (Parameter->Previous && Parameter->Previous->is(tok::comma)) {4139            if (Parameter->Previous->isNot(TT_CtorInitializerComma) &&4140                Parameter->HasUnescapedNewline) {4141              Parameter->MustBreakBefore = true;4142            }4143            break;4144          }4145        }4146      }4147    } else if (!Current->Finalized && Current->SpacesRequiredBefore == 0 &&4148               spaceRequiredBefore(Line, *Current)) {4149      Current->SpacesRequiredBefore = 1;4150    }4151 4152    const auto &Children = Prev->Children;4153    if (!Children.empty() && Children.back()->Last->is(TT_LineComment)) {4154      Current->MustBreakBefore = true;4155    } else {4156      Current->MustBreakBefore =4157          Current->MustBreakBefore || mustBreakBefore(Line, *Current);4158      if (!Current->MustBreakBefore && InFunctionDecl &&4159          Current->is(TT_FunctionDeclarationName)) {4160        Current->MustBreakBefore = mustBreakForReturnType(Line);4161      }4162    }4163 4164    Current->CanBreakBefore =4165        Current->MustBreakBefore || canBreakBefore(Line, *Current);4166 4167    if (Current->is(TT_FunctionDeclarationLParen)) {4168      InParameterList = true;4169    } else if (Current->is(tok::r_paren)) {4170      const auto *LParen = Current->MatchingParen;4171      if (LParen && LParen->is(TT_FunctionDeclarationLParen))4172        InParameterList = false;4173    } else if (InParameterList &&4174               Current->endsSequence(TT_AttributeMacro,4175                                     TT_PointerOrReference)) {4176      Current->CanBreakBefore = false;4177    }4178 4179    unsigned ChildSize = 0;4180    if (Prev->Children.size() == 1) {4181      FormatToken &LastOfChild = *Prev->Children[0]->Last;4182      ChildSize = LastOfChild.isTrailingComment() ? Style.ColumnLimit4183                                                  : LastOfChild.TotalLength + 1;4184    }4185    if (Current->MustBreakBefore || Prev->Children.size() > 1 ||4186        (Prev->Children.size() == 1 &&4187         Prev->Children[0]->First->MustBreakBefore) ||4188        Current->IsMultiline) {4189      Current->TotalLength = Prev->TotalLength + Style.ColumnLimit;4190    } else {4191      Current->TotalLength = Prev->TotalLength + Current->ColumnWidth +4192                             ChildSize + Current->SpacesRequiredBefore;4193    }4194 4195    if (Current->is(TT_ControlStatementLBrace)) {4196      if (Style.ColumnLimit > 0 &&4197          Style.BraceWrapping.AfterControlStatement ==4198              FormatStyle::BWACS_MultiLine &&4199          Line.Level * Style.IndentWidth + Line.Last->TotalLength >4200              Style.ColumnLimit) {4201        Current->CanBreakBefore = true;4202        Current->MustBreakBefore = true;4203      }4204    } else if (Current->is(TT_CtorInitializerColon)) {4205      InFunctionDecl = false;4206    }4207 4208    // FIXME: Only calculate this if CanBreakBefore is true once static4209    // initializers etc. are sorted out.4210    // FIXME: Move magic numbers to a better place.4211 4212    // Reduce penalty for aligning ObjC method arguments using the colon4213    // alignment as this is the canonical way (still prefer fitting everything4214    // into one line if possible). Trying to fit a whole expression into one4215    // line should not force other line breaks (e.g. when ObjC method4216    // expression is a part of other expression).4217    Current->SplitPenalty = splitPenalty(Line, *Current, InFunctionDecl);4218    if (Style.Language == FormatStyle::LK_ObjC &&4219        Current->is(TT_SelectorName) && Current->ParameterIndex > 0) {4220      if (Current->ParameterIndex == 1)4221        Current->SplitPenalty += 5 * Current->BindingStrength;4222    } else {4223      Current->SplitPenalty += 20 * Current->BindingStrength;4224    }4225  }4226 4227  calculateUnbreakableTailLengths(Line);4228  unsigned IndentLevel = Line.Level;4229  for (auto *Current = First; Current; Current = Current->Next) {4230    if (Current->Role)4231      Current->Role->precomputeFormattingInfos(Current);4232    if (Current->MatchingParen &&4233        Current->MatchingParen->opensBlockOrBlockTypeList(Style) &&4234        IndentLevel > 0) {4235      --IndentLevel;4236    }4237    Current->IndentLevel = IndentLevel;4238    if (Current->opensBlockOrBlockTypeList(Style))4239      ++IndentLevel;4240  }4241 4242  LLVM_DEBUG({ printDebugInfo(Line); });4243}4244 4245void TokenAnnotator::calculateUnbreakableTailLengths(4246    AnnotatedLine &Line) const {4247  unsigned UnbreakableTailLength = 0;4248  FormatToken *Current = Line.Last;4249  while (Current) {4250    Current->UnbreakableTailLength = UnbreakableTailLength;4251    if (Current->CanBreakBefore ||4252        Current->isOneOf(tok::comment, tok::string_literal)) {4253      UnbreakableTailLength = 0;4254    } else {4255      UnbreakableTailLength +=4256          Current->ColumnWidth + Current->SpacesRequiredBefore;4257    }4258    Current = Current->Previous;4259  }4260}4261 4262void TokenAnnotator::calculateArrayInitializerColumnList(4263    AnnotatedLine &Line) const {4264  if (Line.First == Line.Last)4265    return;4266  auto *CurrentToken = Line.First;4267  CurrentToken->ArrayInitializerLineStart = true;4268  unsigned Depth = 0;4269  while (CurrentToken && CurrentToken != Line.Last) {4270    if (CurrentToken->is(tok::l_brace)) {4271      CurrentToken->IsArrayInitializer = true;4272      if (CurrentToken->Next)4273        CurrentToken->Next->MustBreakBefore = true;4274      CurrentToken =4275          calculateInitializerColumnList(Line, CurrentToken->Next, Depth + 1);4276    } else {4277      CurrentToken = CurrentToken->Next;4278    }4279  }4280}4281 4282FormatToken *TokenAnnotator::calculateInitializerColumnList(4283    AnnotatedLine &Line, FormatToken *CurrentToken, unsigned Depth) const {4284  while (CurrentToken && CurrentToken != Line.Last) {4285    if (CurrentToken->is(tok::l_brace))4286      ++Depth;4287    else if (CurrentToken->is(tok::r_brace))4288      --Depth;4289    if (Depth == 2 && CurrentToken->isOneOf(tok::l_brace, tok::comma)) {4290      CurrentToken = CurrentToken->Next;4291      if (!CurrentToken)4292        break;4293      CurrentToken->StartsColumn = true;4294      CurrentToken = CurrentToken->Previous;4295    }4296    CurrentToken = CurrentToken->Next;4297  }4298  return CurrentToken;4299}4300 4301unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line,4302                                      const FormatToken &Tok,4303                                      bool InFunctionDecl) const {4304  const FormatToken &Left = *Tok.Previous;4305  const FormatToken &Right = Tok;4306 4307  if (Left.is(tok::semi))4308    return 0;4309 4310  // Language specific handling.4311  if (Style.isJava()) {4312    if (Right.isOneOf(Keywords.kw_extends, Keywords.kw_throws))4313      return 1;4314    if (Right.is(Keywords.kw_implements))4315      return 2;4316    if (Left.is(tok::comma) && Left.NestingLevel == 0)4317      return 3;4318  } else if (Style.isJavaScript()) {4319    if (Right.is(Keywords.kw_function) && Left.isNot(tok::comma))4320      return 100;4321    if (Left.is(TT_JsTypeColon))4322      return 35;4323    if ((Left.is(TT_TemplateString) && Left.TokenText.ends_with("${")) ||4324        (Right.is(TT_TemplateString) && Right.TokenText.starts_with("}"))) {4325      return 100;4326    }4327    // Prefer breaking call chains (".foo") over empty "{}", "[]" or "()".4328    if (Left.opensScope() && Right.closesScope())4329      return 200;4330  } else if (Style.Language == FormatStyle::LK_Proto) {4331    if (Right.is(tok::l_square))4332      return 1;4333    if (Right.is(tok::period))4334      return 500;4335  }4336 4337  if (Right.is(tok::identifier) && Right.Next && Right.Next->is(TT_DictLiteral))4338    return 1;4339  if (Right.is(tok::l_square)) {4340    if (Left.is(tok::r_square))4341      return 200;4342    // Slightly prefer formatting local lambda definitions like functions.4343    if (Right.is(TT_LambdaLSquare) && Left.is(tok::equal))4344      return 35;4345    if (Right.isNoneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,4346                       TT_ArrayInitializerLSquare,4347                       TT_DesignatedInitializerLSquare, TT_AttributeLSquare)) {4348      return 500;4349    }4350  }4351 4352  if (Left.is(tok::coloncolon))4353    return Style.PenaltyBreakScopeResolution;4354  if (Right.isOneOf(TT_StartOfName, TT_FunctionDeclarationName,4355                    tok::kw_operator)) {4356    if (Line.startsWith(tok::kw_for) && Right.PartOfMultiVariableDeclStmt)4357      return 3;4358    if (Left.is(TT_StartOfName))4359      return 110;4360    if (InFunctionDecl && Right.NestingLevel == 0)4361      return Style.PenaltyReturnTypeOnItsOwnLine;4362    return 200;4363  }4364  if (Right.is(TT_PointerOrReference))4365    return 190;4366  if (Right.is(TT_LambdaArrow))4367    return 110;4368  if (Left.is(tok::equal) && Right.is(tok::l_brace))4369    return 160;4370  if (Left.is(TT_CastRParen))4371    return 100;4372  if (Left.isOneOf(tok::kw_class, tok::kw_struct, tok::kw_union))4373    return 5000;4374  if (Left.is(tok::comment))4375    return 1000;4376 4377  if (Left.isOneOf(TT_RangeBasedForLoopColon, TT_InheritanceColon,4378                   TT_CtorInitializerColon)) {4379    return 2;4380  }4381 4382  if (Right.isMemberAccess()) {4383    // Breaking before the "./->" of a chained call/member access is reasonably4384    // cheap, as formatting those with one call per line is generally4385    // desirable. In particular, it should be cheaper to break before the call4386    // than it is to break inside a call's parameters, which could lead to weird4387    // "hanging" indents. The exception is the very last "./->" to support this4388    // frequent pattern:4389    //4390    //   aaaaaaaa.aaaaaaaa.bbbbbbb().ccccccccccccccccccccc(4391    //       dddddddd);4392    //4393    // which might otherwise be blown up onto many lines. Here, clang-format4394    // won't produce "hanging" indents anyway as there is no other trailing4395    // call.4396    //4397    // Also apply higher penalty is not a call as that might lead to a wrapping4398    // like:4399    //4400    //   aaaaaaa4401    //       .aaaaaaaaa.bbbbbbbb(cccccccc);4402    const auto *NextOperator = Right.NextOperator;4403    const auto Penalty = Style.PenaltyBreakBeforeMemberAccess;4404    return NextOperator && NextOperator->Previous->closesScope()4405               ? std::min(Penalty, 35u)4406               : Penalty;4407  }4408 4409  if (Right.is(TT_TrailingAnnotation) &&4410      (!Right.Next || Right.Next->isNot(tok::l_paren))) {4411    // Moving trailing annotations to the next line is fine for ObjC method4412    // declarations.4413    if (Line.startsWith(TT_ObjCMethodSpecifier))4414      return 10;4415    // Generally, breaking before a trailing annotation is bad unless it is4416    // function-like. It seems to be especially preferable to keep standard4417    // annotations (i.e. "const", "final" and "override") on the same line.4418    // Use a slightly higher penalty after ")" so that annotations like4419    // "const override" are kept together.4420    bool is_short_annotation = Right.TokenText.size() < 10;4421    return (Left.is(tok::r_paren) ? 100 : 120) + (is_short_annotation ? 50 : 0);4422  }4423 4424  // In for-loops, prefer breaking at ',' and ';'.4425  if (Line.startsWith(tok::kw_for) && Left.is(tok::equal))4426    return 4;4427 4428  // In Objective-C method expressions, prefer breaking before "param:" over4429  // breaking after it.4430  if (Right.is(TT_SelectorName))4431    return 0;4432  if (Left.is(tok::colon)) {4433    if (Left.is(TT_ObjCMethodExpr))4434      return Line.MightBeFunctionDecl ? 50 : 500;4435    if (Left.is(TT_ObjCSelector))4436      return 500;4437  }4438 4439  // In Objective-C type declarations, avoid breaking after the category's4440  // open paren (we'll prefer breaking after the protocol list's opening4441  // angle bracket, if present).4442  if (Line.Type == LT_ObjCDecl && Left.is(tok::l_paren) && Left.Previous &&4443      Left.Previous->isOneOf(tok::identifier, tok::greater)) {4444    return 500;4445  }4446 4447  if (Left.is(tok::l_paren) && Style.PenaltyBreakOpenParenthesis != 0)4448    return Style.PenaltyBreakOpenParenthesis;4449  if (Left.is(tok::l_paren) && InFunctionDecl && Style.AlignAfterOpenBracket)4450    return 100;4451  if (Left.is(tok::l_paren) && Left.Previous &&4452      (Left.Previous->isOneOf(tok::kw_for, tok::kw__Generic) ||4453       Left.Previous->isIf())) {4454    return 1000;4455  }4456  if (Left.is(tok::equal) && InFunctionDecl)4457    return 110;4458  if (Right.is(tok::r_brace))4459    return 1;4460  if (Left.is(TT_TemplateOpener))4461    return 100;4462  if (Left.opensScope()) {4463    // If we aren't aligning after opening parens/braces we can always break4464    // here unless the style does not want us to place all arguments on the4465    // next line.4466    if (!Style.AlignAfterOpenBracket &&4467        (Left.ParameterCount <= 1 || Style.AllowAllArgumentsOnNextLine)) {4468      return 0;4469    }4470    if (Left.is(tok::l_brace) &&4471        Style.Cpp11BracedListStyle == FormatStyle::BLS_Block) {4472      return 19;4473    }4474    return Left.ParameterCount > 1 ? Style.PenaltyBreakBeforeFirstCallParameter4475                                   : 19;4476  }4477  if (Left.is(TT_JavaAnnotation))4478    return 50;4479 4480  if (Left.is(TT_UnaryOperator))4481    return 60;4482  if (Left.isOneOf(tok::plus, tok::comma) && Left.Previous &&4483      Left.Previous->isLabelString() &&4484      (Left.NextOperator || Left.OperatorIndex != 0)) {4485    return 50;4486  }4487  if (Right.is(tok::plus) && Left.isLabelString() &&4488      (Right.NextOperator || Right.OperatorIndex != 0)) {4489    return 25;4490  }4491  if (Left.is(tok::comma))4492    return 1;4493  if (Right.is(tok::lessless) && Left.isLabelString() &&4494      (Right.NextOperator || Right.OperatorIndex != 1)) {4495    return 25;4496  }4497  if (Right.is(tok::lessless)) {4498    // Breaking at a << is really cheap.4499    if (Left.isNot(tok::r_paren) || Right.OperatorIndex > 0) {4500      // Slightly prefer to break before the first one in log-like statements.4501      return 2;4502    }4503    return 1;4504  }4505  if (Left.ClosesTemplateDeclaration)4506    return Style.PenaltyBreakTemplateDeclaration;4507  if (Left.ClosesRequiresClause)4508    return 0;4509  if (Left.is(TT_ConditionalExpr))4510    return prec::Conditional;4511  prec::Level Level = Left.getPrecedence();4512  if (Level == prec::Unknown)4513    Level = Right.getPrecedence();4514  if (Level == prec::Assignment)4515    return Style.PenaltyBreakAssignment;4516  if (Level != prec::Unknown)4517    return Level;4518 4519  return 3;4520}4521 4522bool TokenAnnotator::spaceRequiredBeforeParens(const FormatToken &Right) const {4523  if (Style.SpaceBeforeParens == FormatStyle::SBPO_Always)4524    return true;4525  if (Right.is(TT_OverloadedOperatorLParen) &&4526      Style.SpaceBeforeParensOptions.AfterOverloadedOperator) {4527    return true;4528  }4529  if (Style.SpaceBeforeParensOptions.BeforeNonEmptyParentheses &&4530      Right.ParameterCount > 0) {4531    return true;4532  }4533  return false;4534}4535 4536bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,4537                                          const FormatToken &Left,4538                                          const FormatToken &Right) const {4539  if (Left.is(tok::kw_return) &&4540      Right.isNoneOf(tok::semi, tok::r_paren, tok::hashhash)) {4541    return true;4542  }4543  if (Left.is(tok::kw_throw) && Right.is(tok::l_paren) && Right.MatchingParen &&4544      Right.MatchingParen->is(TT_CastRParen)) {4545    return true;4546  }4547  if (Left.is(Keywords.kw_assert) && Style.isJava())4548    return true;4549  if (Style.ObjCSpaceAfterProperty && Line.Type == LT_ObjCProperty &&4550      Left.is(tok::objc_property)) {4551    return true;4552  }4553  if (Right.is(tok::hashhash))4554    return Left.is(tok::hash);4555  if (Left.isOneOf(tok::hashhash, tok::hash))4556    return Right.is(tok::hash);4557  if (Style.SpacesInParens == FormatStyle::SIPO_Custom) {4558    if (Left.is(tok::l_paren) && Right.is(tok::r_paren))4559      return Style.SpacesInParensOptions.InEmptyParentheses;4560    if (Style.SpacesInParensOptions.ExceptDoubleParentheses &&4561        Left.is(tok::r_paren) && Right.is(tok::r_paren)) {4562      auto *InnerLParen = Left.MatchingParen;4563      if (InnerLParen && InnerLParen->Previous == Right.MatchingParen) {4564        InnerLParen->SpacesRequiredBefore = 0;4565        return false;4566      }4567    }4568    const FormatToken *LeftParen = nullptr;4569    if (Left.is(tok::l_paren))4570      LeftParen = &Left;4571    else if (Right.is(tok::r_paren) && Right.MatchingParen)4572      LeftParen = Right.MatchingParen;4573    if (LeftParen && (LeftParen->is(TT_ConditionLParen) ||4574                      (LeftParen->Previous &&4575                       isKeywordWithCondition(*LeftParen->Previous)))) {4576      return Style.SpacesInParensOptions.InConditionalStatements;4577    }4578  }4579 4580  // trailing return type 'auto': []() -> auto {}, auto foo() -> auto {}4581  if (Left.is(tok::kw_auto) && Right.isOneOf(TT_LambdaLBrace, TT_FunctionLBrace,4582                                             // function return type 'auto'4583                                             TT_FunctionTypeLParen)) {4584    return true;4585  }4586 4587  // auto{x} auto(x)4588  if (Left.is(tok::kw_auto) && Right.isOneOf(tok::l_paren, tok::l_brace))4589    return false;4590 4591  const auto *BeforeLeft = Left.Previous;4592 4593  // operator co_await(x)4594  if (Right.is(tok::l_paren) && Left.is(tok::kw_co_await) && BeforeLeft &&4595      BeforeLeft->is(tok::kw_operator)) {4596    return false;4597  }4598  // co_await (x), co_yield (x), co_return (x)4599  if (Left.isOneOf(tok::kw_co_await, tok::kw_co_yield, tok::kw_co_return) &&4600      Right.isNoneOf(tok::semi, tok::r_paren)) {4601    return true;4602  }4603 4604  if (Left.is(tok::l_paren) || Right.is(tok::r_paren)) {4605    return (Right.is(TT_CastRParen) ||4606            (Left.MatchingParen && Left.MatchingParen->is(TT_CastRParen)))4607               ? Style.SpacesInParensOptions.InCStyleCasts4608               : Style.SpacesInParensOptions.Other;4609  }4610  if (Right.isOneOf(tok::semi, tok::comma))4611    return false;4612  if (Right.is(tok::less) && Line.Type == LT_ObjCDecl) {4613    bool IsLightweightGeneric = Right.MatchingParen &&4614                                Right.MatchingParen->Next &&4615                                Right.MatchingParen->Next->is(tok::colon);4616    return !IsLightweightGeneric && Style.ObjCSpaceBeforeProtocolList;4617  }4618  if (Right.is(tok::less) && Left.is(tok::kw_template))4619    return Style.SpaceAfterTemplateKeyword;4620  if (Left.isOneOf(tok::exclaim, tok::tilde))4621    return false;4622  if (Left.is(tok::at) &&4623      Right.isOneOf(tok::identifier, tok::string_literal, tok::char_constant,4624                    tok::numeric_constant, tok::l_paren, tok::l_brace,4625                    tok::kw_true, tok::kw_false)) {4626    return false;4627  }4628  if (Left.is(tok::colon))4629    return Left.isNoneOf(TT_ObjCSelector, TT_ObjCMethodExpr);4630  if (Left.is(tok::coloncolon))4631    return false;4632  if (Left.is(tok::less) || Right.isOneOf(tok::greater, tok::less)) {4633    if (Style.isTextProto() ||4634        (Style.Language == FormatStyle::LK_Proto &&4635         (Left.is(TT_DictLiteral) || Right.is(TT_DictLiteral)))) {4636      // Format empty list as `<>`.4637      if (Left.is(tok::less) && Right.is(tok::greater))4638        return false;4639      return Style.Cpp11BracedListStyle == FormatStyle::BLS_Block;4640    }4641    // Don't attempt to format operator<(), as it is handled later.4642    if (Right.isNot(TT_OverloadedOperatorLParen))4643      return false;4644  }4645  if (Right.is(tok::ellipsis)) {4646    return Left.Tok.isLiteral() || (Left.is(tok::identifier) && BeforeLeft &&4647                                    BeforeLeft->is(tok::kw_case));4648  }4649  if (Left.is(tok::l_square) && Right.is(tok::amp))4650    return Style.SpacesInSquareBrackets;4651  if (Right.is(TT_PointerOrReference)) {4652    if (Left.is(tok::r_paren) && Line.MightBeFunctionDecl) {4653      if (!Left.MatchingParen)4654        return true;4655      FormatToken *TokenBeforeMatchingParen =4656          Left.MatchingParen->getPreviousNonComment();4657      if (!TokenBeforeMatchingParen || Left.isNot(TT_TypeDeclarationParen))4658        return true;4659    }4660    // Add a space if the previous token is a pointer qualifier or the closing4661    // parenthesis of __attribute__(()) expression and the style requires spaces4662    // after pointer qualifiers.4663    if ((Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_After ||4664         Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_Both) &&4665        (Left.is(TT_AttributeRParen) ||4666         Left.canBePointerOrReferenceQualifier())) {4667      return true;4668    }4669    if (Left.Tok.isLiteral())4670      return true;4671    // for (auto a = 0, b = 0; const auto & c : {1, 2, 3})4672    if (Left.isTypeOrIdentifier(LangOpts) && Right.Next && Right.Next->Next &&4673        Right.Next->Next->is(TT_RangeBasedForLoopColon)) {4674      return getTokenPointerOrReferenceAlignment(Right) !=4675             FormatStyle::PAS_Left;4676    }4677    return Left.isNoneOf(TT_PointerOrReference, tok::l_paren) &&4678           (getTokenPointerOrReferenceAlignment(Right) !=4679                FormatStyle::PAS_Left ||4680            (Line.IsMultiVariableDeclStmt &&4681             (Left.NestingLevel == 0 ||4682              (Left.NestingLevel == 1 && startsWithInitStatement(Line)))));4683  }4684  if (Right.is(TT_FunctionTypeLParen) && Left.isNot(tok::l_paren) &&4685      (Left.isNot(TT_PointerOrReference) ||4686       (getTokenPointerOrReferenceAlignment(Left) != FormatStyle::PAS_Right &&4687        !Line.IsMultiVariableDeclStmt))) {4688    return true;4689  }4690  if (Left.is(TT_PointerOrReference)) {4691    // Add a space if the next token is a pointer qualifier and the style4692    // requires spaces before pointer qualifiers.4693    if ((Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_Before ||4694         Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_Both) &&4695        Right.canBePointerOrReferenceQualifier()) {4696      return true;4697    }4698    // & 14699    if (Right.Tok.isLiteral())4700      return true;4701    // & /* comment4702    if (Right.is(TT_BlockComment))4703      return true;4704    // foo() -> const Bar * override/final4705    // S::foo() & noexcept/requires4706    if (Right.isOneOf(Keywords.kw_override, Keywords.kw_final, tok::kw_noexcept,4707                      TT_RequiresClause) &&4708        Right.isNot(TT_StartOfName)) {4709      return true;4710    }4711    // & {4712    if (Right.is(tok::l_brace) && Right.is(BK_Block))4713      return true;4714    // for (auto a = 0, b = 0; const auto& c : {1, 2, 3})4715    if (BeforeLeft && BeforeLeft->isTypeOrIdentifier(LangOpts) && Right.Next &&4716        Right.Next->is(TT_RangeBasedForLoopColon)) {4717      return getTokenPointerOrReferenceAlignment(Left) !=4718             FormatStyle::PAS_Right;4719    }4720    if (Right.isOneOf(TT_PointerOrReference, TT_ArraySubscriptLSquare,4721                      tok::l_paren)) {4722      return false;4723    }4724    if (getTokenPointerOrReferenceAlignment(Left) == FormatStyle::PAS_Right)4725      return false;4726    // FIXME: Setting IsMultiVariableDeclStmt for the whole line is error-prone,4727    // because it does not take into account nested scopes like lambdas.4728    // In multi-variable declaration statements, attach */& to the variable4729    // independently of the style. However, avoid doing it if we are in a nested4730    // scope, e.g. lambda. We still need to special-case statements with4731    // initializers.4732    if (Line.IsMultiVariableDeclStmt &&4733        (Left.NestingLevel == Line.First->NestingLevel ||4734         ((Left.NestingLevel == Line.First->NestingLevel + 1) &&4735          startsWithInitStatement(Line)))) {4736      return false;4737    }4738    if (!BeforeLeft)4739      return false;4740    if (BeforeLeft->is(tok::coloncolon)) {4741      if (Left.isNot(tok::star))4742        return false;4743      assert(Style.PointerAlignment != FormatStyle::PAS_Right);4744      if (!Right.startsSequence(tok::identifier, tok::r_paren))4745        return true;4746      assert(Right.Next);4747      const auto *LParen = Right.Next->MatchingParen;4748      return !LParen || LParen->isNot(TT_FunctionTypeLParen);4749    }4750    return BeforeLeft->isNoneOf(tok::l_paren, tok::l_square);4751  }4752  // Ensure right pointer alignment with ellipsis e.g. int *...P4753  if (Left.is(tok::ellipsis) && BeforeLeft &&4754      BeforeLeft->isPointerOrReference()) {4755    return Style.PointerAlignment != FormatStyle::PAS_Right;4756  }4757 4758  if (Right.is(tok::star) && Left.is(tok::l_paren))4759    return false;4760  if (Left.is(tok::star) && Right.isPointerOrReference())4761    return false;4762  if (Right.isPointerOrReference()) {4763    const FormatToken *Previous = &Left;4764    while (Previous && Previous->isNot(tok::kw_operator)) {4765      if (Previous->is(tok::identifier) || Previous->isTypeName(LangOpts)) {4766        Previous = Previous->getPreviousNonComment();4767        continue;4768      }4769      if (Previous->is(TT_TemplateCloser) && Previous->MatchingParen) {4770        Previous = Previous->MatchingParen->getPreviousNonComment();4771        continue;4772      }4773      if (Previous->is(tok::coloncolon)) {4774        Previous = Previous->getPreviousNonComment();4775        continue;4776      }4777      break;4778    }4779    // Space between the type and the * in:4780    //   operator void*()4781    //   operator char*()4782    //   operator void const*()4783    //   operator void volatile*()4784    //   operator /*comment*/ const char*()4785    //   operator volatile /*comment*/ char*()4786    //   operator Foo*()4787    //   operator C<T>*()4788    //   operator std::Foo*()4789    //   operator C<T>::D<U>*()4790    // dependent on PointerAlignment style.4791    if (Previous) {4792      if (Previous->endsSequence(tok::kw_operator))4793        return Style.PointerAlignment != FormatStyle::PAS_Left;4794      if (Previous->isOneOf(tok::kw_const, tok::kw_volatile)) {4795        return (Style.PointerAlignment != FormatStyle::PAS_Left) ||4796               (Style.SpaceAroundPointerQualifiers ==4797                FormatStyle::SAPQ_After) ||4798               (Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_Both);4799      }4800    }4801  }4802  if (Style.isCSharp() && Left.is(Keywords.kw_is) && Right.is(tok::l_square))4803    return true;4804  const auto SpaceRequiredForArrayInitializerLSquare =4805      [](const FormatToken &LSquareTok, const FormatStyle &Style) {4806        return Style.SpacesInContainerLiterals ||4807               (Style.isProto() &&4808                Style.Cpp11BracedListStyle == FormatStyle::BLS_Block &&4809                LSquareTok.endsSequence(tok::l_square, tok::colon,4810                                        TT_SelectorName));4811      };4812  if (Left.is(tok::l_square)) {4813    return (Left.is(TT_ArrayInitializerLSquare) && Right.isNot(tok::r_square) &&4814            SpaceRequiredForArrayInitializerLSquare(Left, Style)) ||4815           (Left.isOneOf(TT_ArraySubscriptLSquare, TT_StructuredBindingLSquare,4816                         TT_LambdaLSquare) &&4817            Style.SpacesInSquareBrackets && Right.isNot(tok::r_square));4818  }4819  if (Right.is(tok::r_square)) {4820    return Right.MatchingParen &&4821           ((Right.MatchingParen->is(TT_ArrayInitializerLSquare) &&4822             SpaceRequiredForArrayInitializerLSquare(*Right.MatchingParen,4823                                                     Style)) ||4824            (Style.SpacesInSquareBrackets &&4825             Right.MatchingParen->isOneOf(TT_ArraySubscriptLSquare,4826                                          TT_StructuredBindingLSquare,4827                                          TT_LambdaLSquare)));4828  }4829  if (Right.is(tok::l_square) &&4830      Right.isNoneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,4831                     TT_DesignatedInitializerLSquare,4832                     TT_StructuredBindingLSquare, TT_AttributeLSquare) &&4833      Left.isNoneOf(tok::numeric_constant, TT_DictLiteral) &&4834      !(Left.isNot(tok::r_square) && Style.SpaceBeforeSquareBrackets &&4835        Right.is(TT_ArraySubscriptLSquare))) {4836    return false;4837  }4838  if ((Left.is(tok::l_brace) && Left.isNot(BK_Block)) ||4839      (Right.is(tok::r_brace) && Right.MatchingParen &&4840       Right.MatchingParen->isNot(BK_Block))) {4841    return Style.Cpp11BracedListStyle == FormatStyle::BLS_Block ||4842           Style.SpacesInParensOptions.Other;4843  }4844  if (Left.is(TT_BlockComment)) {4845    // No whitespace in x(/*foo=*/1), except for JavaScript.4846    return Style.isJavaScript() || !Left.TokenText.ends_with("=*/");4847  }4848 4849  // Space between template and attribute.4850  // e.g. template <typename T> [[nodiscard]] ...4851  if (Left.is(TT_TemplateCloser) && Right.is(TT_AttributeLSquare))4852    return true;4853  // Space before parentheses common for all languages4854  if (Right.is(tok::l_paren)) {4855    if (Left.is(TT_TemplateCloser) && Right.isNot(TT_FunctionTypeLParen))4856      return spaceRequiredBeforeParens(Right);4857    if (Left.isOneOf(TT_RequiresClause,4858                     TT_RequiresClauseInARequiresExpression)) {4859      return Style.SpaceBeforeParensOptions.AfterRequiresInClause ||4860             spaceRequiredBeforeParens(Right);4861    }4862    if (Left.is(TT_RequiresExpression)) {4863      return Style.SpaceBeforeParensOptions.AfterRequiresInExpression ||4864             spaceRequiredBeforeParens(Right);4865    }4866    if (Left.isOneOf(TT_AttributeRParen, TT_AttributeRSquare))4867      return true;4868    if (Left.is(TT_ForEachMacro)) {4869      return Style.SpaceBeforeParensOptions.AfterForeachMacros ||4870             spaceRequiredBeforeParens(Right);4871    }4872    if (Left.is(TT_IfMacro)) {4873      return Style.SpaceBeforeParensOptions.AfterIfMacros ||4874             spaceRequiredBeforeParens(Right);4875    }4876    if (Style.SpaceBeforeParens == FormatStyle::SBPO_Custom &&4877        Left.isPlacementOperator() &&4878        Right.isNot(TT_OverloadedOperatorLParen) &&4879        !(Line.MightBeFunctionDecl && Left.is(TT_FunctionDeclarationName))) {4880      const auto *RParen = Right.MatchingParen;4881      return Style.SpaceBeforeParensOptions.AfterPlacementOperator ||4882             (RParen && RParen->is(TT_CastRParen));4883    }4884    if (Line.Type == LT_ObjCDecl)4885      return true;4886    if (Left.is(tok::semi))4887      return true;4888    if (Left.isOneOf(tok::pp_elif, tok::kw_for, tok::kw_while, tok::kw_switch,4889                     tok::kw_case, TT_ForEachMacro, TT_ObjCForIn) ||4890        Left.isIf(Line.Type != LT_PreprocessorDirective) ||4891        Right.is(TT_ConditionLParen)) {4892      return Style.SpaceBeforeParensOptions.AfterControlStatements ||4893             spaceRequiredBeforeParens(Right);4894    }4895 4896    // TODO add Operator overloading specific Options to4897    // SpaceBeforeParensOptions4898    if (Right.is(TT_OverloadedOperatorLParen))4899      return spaceRequiredBeforeParens(Right);4900    // Function declaration or definition4901    if (Line.MightBeFunctionDecl && Right.is(TT_FunctionDeclarationLParen)) {4902      if (spaceRequiredBeforeParens(Right))4903        return true;4904      const auto &Options = Style.SpaceBeforeParensOptions;4905      return Line.mightBeFunctionDefinition()4906                 ? Options.AfterFunctionDefinitionName4907                 : Options.AfterFunctionDeclarationName;4908    }4909    // Lambda4910    if (Line.Type != LT_PreprocessorDirective && Left.is(tok::r_square) &&4911        Left.MatchingParen && Left.MatchingParen->is(TT_LambdaLSquare)) {4912      return Style.SpaceBeforeParensOptions.AfterFunctionDefinitionName ||4913             spaceRequiredBeforeParens(Right);4914    }4915    if (!BeforeLeft || BeforeLeft->isNoneOf(tok::period, tok::arrow)) {4916      if (Left.isOneOf(tok::kw_try, Keywords.kw___except, tok::kw_catch)) {4917        return Style.SpaceBeforeParensOptions.AfterControlStatements ||4918               spaceRequiredBeforeParens(Right);4919      }4920      if (Left.isPlacementOperator() ||4921          (Left.is(tok::r_square) && Left.MatchingParen &&4922           Left.MatchingParen->Previous &&4923           Left.MatchingParen->Previous->is(tok::kw_delete))) {4924        return Style.SpaceBeforeParens != FormatStyle::SBPO_Never ||4925               spaceRequiredBeforeParens(Right);4926      }4927    }4928    // Handle builtins like identifiers.4929    if (Line.Type != LT_PreprocessorDirective &&4930        (Left.Tok.getIdentifierInfo() || Left.is(tok::r_paren))) {4931      return spaceRequiredBeforeParens(Right);4932    }4933    return false;4934  }4935  if (Left.is(tok::at) && Right.isNot(tok::objc_not_keyword))4936    return false;4937  if (Right.is(TT_UnaryOperator)) {4938    return Left.isNoneOf(tok::l_paren, tok::l_square, tok::at) &&4939           (Left.isNot(tok::colon) || Left.isNot(TT_ObjCMethodExpr));4940  }4941  // No space between the variable name and the initializer list.4942  // A a1{1};4943  // Verilog doesn't have such syntax, but it has word operators that are C++4944  // identifiers like `a inside {b, c}`. So the rule is not applicable.4945  if (!Style.isVerilog() &&4946      (Left.isOneOf(tok::identifier, tok::greater, tok::r_square,4947                    tok::r_paren) ||4948       Left.isTypeName(LangOpts)) &&4949      Right.is(tok::l_brace) && Right.getNextNonComment() &&4950      Right.isNot(BK_Block)) {4951    return false;4952  }4953  if (Left.is(tok::period) || Right.is(tok::period))4954    return false;4955  // u#str, U#str, L#str, u8#str4956  // uR#str, UR#str, LR#str, u8R#str4957  if (Right.is(tok::hash) && Left.is(tok::identifier) &&4958      (Left.TokenText == "L" || Left.TokenText == "u" ||4959       Left.TokenText == "U" || Left.TokenText == "u8" ||4960       Left.TokenText == "LR" || Left.TokenText == "uR" ||4961       Left.TokenText == "UR" || Left.TokenText == "u8R")) {4962    return false;4963  }4964  if (Left.is(TT_TemplateCloser) && Left.MatchingParen &&4965      Left.MatchingParen->Previous &&4966      Left.MatchingParen->Previous->isOneOf(tok::period, tok::coloncolon)) {4967    // Java call to generic function with explicit type:4968    // A.<B<C<...>>>DoSomething();4969    // A::<B<C<...>>>DoSomething();  // With a Java 8 method reference.4970    return false;4971  }4972  if (Left.is(TT_TemplateCloser) && Right.is(tok::l_square))4973    return false;4974  if (Left.is(tok::l_brace) && Left.endsSequence(TT_DictLiteral, tok::at)) {4975    // Objective-C dictionary literal -> no space after opening brace.4976    return false;4977  }4978  if (Right.is(tok::r_brace) && Right.MatchingParen &&4979      Right.MatchingParen->endsSequence(TT_DictLiteral, tok::at)) {4980    // Objective-C dictionary literal -> no space before closing brace.4981    return false;4982  }4983  if (Right.is(TT_TrailingAnnotation) && Right.isOneOf(tok::amp, tok::ampamp) &&4984      Left.isOneOf(tok::kw_const, tok::kw_volatile) &&4985      (!Right.Next || Right.Next->is(tok::semi))) {4986    // Match const and volatile ref-qualifiers without any additional4987    // qualifiers such as4988    // void Fn() const &;4989    return getTokenReferenceAlignment(Right) != FormatStyle::PAS_Left;4990  }4991 4992  return true;4993}4994 4995bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,4996                                         const FormatToken &Right) const {4997  const FormatToken &Left = *Right.Previous;4998 4999  // If the token is finalized don't touch it (as it could be in a5000  // clang-format-off section).5001  if (Left.Finalized)5002    return Right.hasWhitespaceBefore();5003 5004  const bool IsVerilog = Style.isVerilog();5005  assert(!IsVerilog || !IsCpp);5006 5007  // Never ever merge two words.5008  if (Keywords.isWordLike(Right, IsVerilog) &&5009      Keywords.isWordLike(Left, IsVerilog)) {5010    return true;5011  }5012 5013  // Leave a space between * and /* to avoid C4138 `comment end` found outside5014  // of comment.5015  if (Left.is(tok::star) && Right.is(tok::comment))5016    return true;5017 5018  if (Left.is(tok::l_brace) && Right.is(tok::r_brace) &&5019      Left.Children.empty()) {5020    if (Left.is(BK_Block))5021      return Style.SpaceInEmptyBraces != FormatStyle::SIEB_Never;5022    if (Style.Cpp11BracedListStyle != FormatStyle::BLS_Block) {5023      return Style.SpacesInParens == FormatStyle::SIPO_Custom &&5024             Style.SpacesInParensOptions.InEmptyParentheses;5025    }5026    return Style.SpaceInEmptyBraces == FormatStyle::SIEB_Always;5027  }5028 5029  const auto *BeforeLeft = Left.Previous;5030 5031  if (IsCpp) {5032    if (Left.is(TT_OverloadedOperator) &&5033        Right.isOneOf(TT_TemplateOpener, TT_TemplateCloser)) {5034      return true;5035    }5036    // Space between UDL and dot: auto b = 4s .count();5037    if (Right.is(tok::period) && Left.is(tok::numeric_constant))5038      return true;5039    // Space between import <iostream>.5040    // or import .....;5041    if (Left.is(Keywords.kw_import) &&5042        Right.isOneOf(tok::less, tok::ellipsis) &&5043        (!BeforeLeft || BeforeLeft->is(tok::kw_export))) {5044      return true;5045    }5046    // Space between `module :` and `import :`.5047    if (Left.isOneOf(Keywords.kw_module, Keywords.kw_import) &&5048        Right.is(TT_ModulePartitionColon)) {5049      return true;5050    }5051 5052    if (Right.is(TT_AfterPPDirective))5053      return true;5054 5055    // No space between import foo:bar but keep a space between import :bar;5056    if (Left.is(tok::identifier) && Right.is(TT_ModulePartitionColon))5057      return false;5058    // No space between :bar;5059    if (Left.is(TT_ModulePartitionColon) &&5060        Right.isOneOf(tok::identifier, tok::kw_private)) {5061      return false;5062    }5063    if (Left.is(tok::ellipsis) && Right.is(tok::identifier) &&5064        Line.First->is(Keywords.kw_import)) {5065      return false;5066    }5067    // Space in __attribute__((attr)) ::type.5068    if (Left.isOneOf(TT_AttributeRParen, TT_AttributeMacro) &&5069        Right.is(tok::coloncolon)) {5070      return true;5071    }5072 5073    if (Left.is(tok::kw_operator))5074      return Right.is(tok::coloncolon) || Style.SpaceAfterOperatorKeyword;5075    if (Right.is(tok::l_brace) && Right.is(BK_BracedInit) &&5076        !Left.opensScope() && Style.SpaceBeforeCpp11BracedList) {5077      return true;5078    }5079    if (Left.is(tok::less) && Left.is(TT_OverloadedOperator) &&5080        Right.is(TT_TemplateOpener)) {5081      return true;5082    }5083    // C++ Core Guidelines suppression tag, e.g. `[[suppress(type.5)]]`.5084    if (Left.is(tok::identifier) && Right.is(tok::numeric_constant))5085      return Right.TokenText[0] != '.';5086    // `Left` is a keyword (including C++ alternative operator) or identifier.5087    if (Left.Tok.getIdentifierInfo() && Right.Tok.isLiteral())5088      return true;5089  } else if (Style.isProto()) {5090    if (Right.is(tok::period) && !(BeforeLeft && BeforeLeft->is(tok::period)) &&5091        Left.isOneOf(Keywords.kw_optional, Keywords.kw_required,5092                     Keywords.kw_repeated, Keywords.kw_extend)) {5093      return true;5094    }5095    if (Right.is(tok::l_paren) &&5096        Left.isOneOf(Keywords.kw_returns, Keywords.kw_option)) {5097      return true;5098    }5099    if (Right.isOneOf(tok::l_brace, tok::less) && Left.is(TT_SelectorName))5100      return true;5101    // Slashes occur in text protocol extension syntax: [type/type] { ... }.5102    if (Left.is(tok::slash) || Right.is(tok::slash))5103      return false;5104    if (Left.MatchingParen &&5105        Left.MatchingParen->is(TT_ProtoExtensionLSquare) &&5106        Right.isOneOf(tok::l_brace, tok::less)) {5107      return Style.Cpp11BracedListStyle == FormatStyle::BLS_Block;5108    }5109    // A percent is probably part of a formatting specification, such as %lld.5110    if (Left.is(tok::percent))5111      return false;5112    // Preserve the existence of a space before a percent for cases like 0x%04x5113    // and "%d %d"5114    if (Left.is(tok::numeric_constant) && Right.is(tok::percent))5115      return Right.hasWhitespaceBefore();5116  } else if (Style.isJson()) {5117    if (Right.is(tok::colon) && Left.is(tok::string_literal))5118      return Style.SpaceBeforeJsonColon;5119  } else if (Style.isCSharp()) {5120    // Require spaces around '{' and  before '}' unless they appear in5121    // interpolated strings. Interpolated strings are merged into a single token5122    // so cannot have spaces inserted by this function.5123 5124    // No space between 'this' and '['5125    if (Left.is(tok::kw_this) && Right.is(tok::l_square))5126      return false;5127 5128    // No space between 'new' and '('5129    if (Left.is(tok::kw_new) && Right.is(tok::l_paren))5130      return false;5131 5132    // Space before { (including space within '{ {').5133    if (Right.is(tok::l_brace))5134      return true;5135 5136    // Spaces inside braces.5137    if (Left.is(tok::l_brace) && Right.isNot(tok::r_brace))5138      return true;5139 5140    if (Left.isNot(tok::l_brace) && Right.is(tok::r_brace))5141      return true;5142 5143    // Spaces around '=>'.5144    if (Left.is(TT_FatArrow) || Right.is(TT_FatArrow))5145      return true;5146 5147    // No spaces around attribute target colons5148    if (Left.is(TT_AttributeColon) || Right.is(TT_AttributeColon))5149      return false;5150 5151    // space between type and variable e.g. Dictionary<string,string> foo;5152    if (Left.is(TT_TemplateCloser) && Right.is(TT_StartOfName))5153      return true;5154 5155    // spaces inside square brackets.5156    if (Left.is(tok::l_square) || Right.is(tok::r_square))5157      return Style.SpacesInSquareBrackets;5158 5159    // No space before ? in nullable types.5160    if (Right.is(TT_CSharpNullable))5161      return false;5162 5163    // No space before null forgiving '!'.5164    if (Right.is(TT_NonNullAssertion))5165      return false;5166 5167    // No space between consecutive commas '[,,]'.5168    if (Left.is(tok::comma) && Right.is(tok::comma))5169      return false;5170 5171    // space after var in `var (key, value)`5172    if (Left.is(Keywords.kw_var) && Right.is(tok::l_paren))5173      return true;5174 5175    // space between keywords and paren e.g. "using ("5176    if (Right.is(tok::l_paren)) {5177      if (Left.isOneOf(tok::kw_using, Keywords.kw_async, Keywords.kw_when,5178                       Keywords.kw_lock)) {5179        return Style.SpaceBeforeParensOptions.AfterControlStatements ||5180               spaceRequiredBeforeParens(Right);5181      }5182    }5183 5184    // space between method modifier and opening parenthesis of a tuple return5185    // type5186    if ((Left.isAccessSpecifierKeyword() ||5187         Left.isOneOf(tok::kw_virtual, tok::kw_extern, tok::kw_static,5188                      Keywords.kw_internal, Keywords.kw_abstract,5189                      Keywords.kw_sealed, Keywords.kw_override,5190                      Keywords.kw_async, Keywords.kw_unsafe)) &&5191        Right.is(tok::l_paren)) {5192      return true;5193    }5194  } else if (Style.isJavaScript()) {5195    if (Left.is(TT_FatArrow))5196      return true;5197    // for await ( ...5198    if (Right.is(tok::l_paren) && Left.is(Keywords.kw_await) && BeforeLeft &&5199        BeforeLeft->is(tok::kw_for)) {5200      return true;5201    }5202    if (Left.is(Keywords.kw_async) && Right.is(tok::l_paren) &&5203        Right.MatchingParen) {5204      const FormatToken *Next = Right.MatchingParen->getNextNonComment();5205      // An async arrow function, for example: `x = async () => foo();`,5206      // as opposed to calling a function called async: `x = async();`5207      if (Next && Next->is(TT_FatArrow))5208        return true;5209    }5210    if ((Left.is(TT_TemplateString) && Left.TokenText.ends_with("${")) ||5211        (Right.is(TT_TemplateString) && Right.TokenText.starts_with("}"))) {5212      return false;5213    }5214    // In tagged template literals ("html`bar baz`"), there is no space between5215    // the tag identifier and the template string.5216    if (Keywords.isJavaScriptIdentifier(Left,5217                                        /* AcceptIdentifierName= */ false) &&5218        Right.is(TT_TemplateString)) {5219      return false;5220    }5221    if (Right.is(tok::star) &&5222        Left.isOneOf(Keywords.kw_function, Keywords.kw_yield)) {5223      return false;5224    }5225    if (Right.isOneOf(tok::l_brace, tok::l_square) &&5226        Left.isOneOf(Keywords.kw_function, Keywords.kw_yield,5227                     Keywords.kw_extends, Keywords.kw_implements)) {5228      return true;5229    }5230    if (Right.is(tok::l_paren)) {5231      // JS methods can use some keywords as names (e.g. `delete()`).5232      if (Line.MustBeDeclaration && Left.Tok.getIdentifierInfo())5233        return false;5234      // Valid JS method names can include keywords, e.g. `foo.delete()` or5235      // `bar.instanceof()`. Recognize call positions by preceding period.5236      if (BeforeLeft && BeforeLeft->is(tok::period) &&5237          Left.Tok.getIdentifierInfo()) {5238        return false;5239      }5240      // Additional unary JavaScript operators that need a space after.5241      if (Left.isOneOf(tok::kw_throw, Keywords.kw_await, Keywords.kw_typeof,5242                       tok::kw_void)) {5243        return true;5244      }5245    }5246    // `foo as const;` casts into a const type.5247    if (Left.endsSequence(tok::kw_const, Keywords.kw_as))5248      return false;5249    if ((Left.isOneOf(Keywords.kw_let, Keywords.kw_var, Keywords.kw_in,5250                      tok::kw_const) ||5251         // "of" is only a keyword if it appears after another identifier5252         // (e.g. as "const x of y" in a for loop), or after a destructuring5253         // operation (const [x, y] of z, const {a, b} of c).5254         (Left.is(Keywords.kw_of) && BeforeLeft &&5255          BeforeLeft->isOneOf(tok::identifier, tok::r_square, tok::r_brace))) &&5256        (!BeforeLeft || BeforeLeft->isNot(tok::period))) {5257      return true;5258    }5259    if (Left.isOneOf(tok::kw_for, Keywords.kw_as) && BeforeLeft &&5260        BeforeLeft->is(tok::period) && Right.is(tok::l_paren)) {5261      return false;5262    }5263    if (Left.is(Keywords.kw_as) &&5264        Right.isOneOf(tok::l_square, tok::l_brace, tok::l_paren)) {5265      return true;5266    }5267    if (Left.is(tok::kw_default) && BeforeLeft &&5268        BeforeLeft->is(tok::kw_export)) {5269      return true;5270    }5271    if (Left.is(Keywords.kw_is) && Right.is(tok::l_brace))5272      return true;5273    if (Right.isOneOf(TT_JsTypeColon, TT_JsTypeOptionalQuestion))5274      return false;5275    if (Left.is(TT_JsTypeOperator) || Right.is(TT_JsTypeOperator))5276      return false;5277    if ((Left.is(tok::l_brace) || Right.is(tok::r_brace)) &&5278        Line.First->isOneOf(Keywords.kw_import, tok::kw_export)) {5279      return false;5280    }5281    if (Left.is(tok::ellipsis))5282      return false;5283    if (Left.is(TT_TemplateCloser) &&5284        Right.isNoneOf(tok::equal, tok::l_brace, tok::comma, tok::l_square,5285                       Keywords.kw_implements, Keywords.kw_extends)) {5286      // Type assertions ('<type>expr') are not followed by whitespace. Other5287      // locations that should have whitespace following are identified by the5288      // above set of follower tokens.5289      return false;5290    }5291    if (Right.is(TT_NonNullAssertion))5292      return false;5293    if (Left.is(TT_NonNullAssertion) &&5294        Right.isOneOf(Keywords.kw_as, Keywords.kw_in)) {5295      return true; // "x! as string", "x! in y"5296    }5297  } else if (Style.isJava()) {5298    if (Left.is(TT_CaseLabelArrow) || Right.is(TT_CaseLabelArrow))5299      return true;5300    if (Left.is(tok::r_square) && Right.is(tok::l_brace))5301      return true;5302    // spaces inside square brackets.5303    if (Left.is(tok::l_square) || Right.is(tok::r_square))5304      return Style.SpacesInSquareBrackets;5305 5306    if (Left.is(Keywords.kw_synchronized) && Right.is(tok::l_paren)) {5307      return Style.SpaceBeforeParensOptions.AfterControlStatements ||5308             spaceRequiredBeforeParens(Right);5309    }5310    if ((Left.isAccessSpecifierKeyword() ||5311         Left.isOneOf(tok::kw_static, Keywords.kw_final, Keywords.kw_abstract,5312                      Keywords.kw_native)) &&5313        Right.is(TT_TemplateOpener)) {5314      return true;5315    }5316  } else if (IsVerilog) {5317    // An escaped identifier ends with whitespace.5318    if (Left.is(tok::identifier) && Left.TokenText[0] == '\\')5319      return true;5320    // Add space between things in a primitive's state table unless in a5321    // transition like `(0?)`.5322    if ((Left.is(TT_VerilogTableItem) &&5323         Right.isNoneOf(tok::r_paren, tok::semi)) ||5324        (Right.is(TT_VerilogTableItem) && Left.isNot(tok::l_paren))) {5325      const FormatToken *Next = Right.getNextNonComment();5326      return !(Next && Next->is(tok::r_paren));5327    }5328    // Don't add space within a delay like `#0`.5329    if (Left.isNot(TT_BinaryOperator) &&5330        Left.isOneOf(Keywords.kw_verilogHash, Keywords.kw_verilogHashHash)) {5331      return false;5332    }5333    // Add space after a delay.5334    if (Right.isNot(tok::semi) &&5335        (Left.endsSequence(tok::numeric_constant, Keywords.kw_verilogHash) ||5336         Left.endsSequence(tok::numeric_constant,5337                           Keywords.kw_verilogHashHash) ||5338         (Left.is(tok::r_paren) && Left.MatchingParen &&5339          Left.MatchingParen->endsSequence(tok::l_paren, tok::at)))) {5340      return true;5341    }5342    // Don't add embedded spaces in a number literal like `16'h1?ax` or an array5343    // literal like `'{}`.5344    if (Left.is(Keywords.kw_apostrophe) ||5345        (Left.is(TT_VerilogNumberBase) && Right.is(tok::numeric_constant))) {5346      return false;5347    }5348    // Add spaces around the implication operator `->`.5349    if (Left.is(tok::arrow) || Right.is(tok::arrow))5350      return true;5351    // Don't add spaces between two at signs. Like in a coverage event.5352    // Don't add spaces between at and a sensitivity list like5353    // `@(posedge clk)`.5354    if (Left.is(tok::at) && Right.isOneOf(tok::l_paren, tok::star, tok::at))5355      return false;5356    // Add space between the type name and dimension like `logic [1:0]`.5357    if (Right.is(tok::l_square) &&5358        Left.isOneOf(TT_VerilogDimensionedTypeName, Keywords.kw_function)) {5359      return true;5360    }5361    // In a tagged union expression, there should be a space after the tag.5362    if (Right.isOneOf(tok::period, Keywords.kw_apostrophe) &&5363        Keywords.isVerilogIdentifier(Left) && Left.getPreviousNonComment() &&5364        Left.getPreviousNonComment()->is(Keywords.kw_tagged)) {5365      return true;5366    }5367    // Don't add spaces between a casting type and the quote or repetition count5368    // and the brace. The case of tagged union expressions is handled by the5369    // previous rule.5370    if ((Right.is(Keywords.kw_apostrophe) ||5371         (Right.is(BK_BracedInit) && Right.is(tok::l_brace))) &&5372        Left.isNoneOf(Keywords.kw_assign, Keywords.kw_unique) &&5373        !Keywords.isVerilogWordOperator(Left) &&5374        (Left.isOneOf(tok::r_square, tok::r_paren, tok::r_brace,5375                      tok::numeric_constant) ||5376         Keywords.isWordLike(Left))) {5377      return false;5378    }5379    // Don't add spaces in imports like `import foo::*;`.5380    if ((Right.is(tok::star) && Left.is(tok::coloncolon)) ||5381        (Left.is(tok::star) && Right.is(tok::semi))) {5382      return false;5383    }5384    // Add space in attribute like `(* ASYNC_REG = "TRUE" *)`.5385    if (Left.endsSequence(tok::star, tok::l_paren) && Right.is(tok::identifier))5386      return true;5387    // Add space before drive strength like in `wire (strong1, pull0)`.5388    if (Right.is(tok::l_paren) && Right.is(TT_VerilogStrength))5389      return true;5390    // Don't add space in a streaming concatenation like `{>>{j}}`.5391    if ((Left.is(tok::l_brace) &&5392         Right.isOneOf(tok::lessless, tok::greatergreater)) ||5393        (Left.endsSequence(tok::lessless, tok::l_brace) ||5394         Left.endsSequence(tok::greatergreater, tok::l_brace))) {5395      return false;5396    }5397  } else if (Style.isTableGen()) {5398    // Avoid to connect [ and {. [{ is start token of multiline string.5399    if (Left.is(tok::l_square) && Right.is(tok::l_brace))5400      return true;5401    if (Left.is(tok::r_brace) && Right.is(tok::r_square))5402      return true;5403    // Do not insert around colon in DAGArg and cond operator.5404    if (Right.isOneOf(TT_TableGenDAGArgListColon,5405                      TT_TableGenDAGArgListColonToAlign) ||5406        Left.isOneOf(TT_TableGenDAGArgListColon,5407                     TT_TableGenDAGArgListColonToAlign)) {5408      return false;5409    }5410    if (Right.is(TT_TableGenCondOperatorColon))5411      return false;5412    if (Left.isOneOf(TT_TableGenDAGArgOperatorID,5413                     TT_TableGenDAGArgOperatorToBreak) &&5414        Right.isNot(TT_TableGenDAGArgCloser)) {5415      return true;5416    }5417    // Do not insert bang operators and consequent openers.5418    if (Right.isOneOf(tok::l_paren, tok::less) &&5419        Left.isOneOf(TT_TableGenBangOperator, TT_TableGenCondOperator)) {5420      return false;5421    }5422    // Trailing paste requires space before '{' or ':', the case in name values.5423    // Not before ';', the case in normal values.5424    if (Left.is(TT_TableGenTrailingPasteOperator) &&5425        Right.isOneOf(tok::l_brace, tok::colon)) {5426      return true;5427    }5428    // Otherwise paste operator does not prefer space around.5429    if (Left.is(tok::hash) || Right.is(tok::hash))5430      return false;5431    // Sure not to connect after defining keywords.5432    if (Keywords.isTableGenDefinition(Left))5433      return true;5434  }5435 5436  if (Left.is(TT_ImplicitStringLiteral))5437    return Right.hasWhitespaceBefore();5438  if (Line.Type == LT_ObjCMethodDecl) {5439    if (Left.is(TT_ObjCMethodSpecifier))5440      return true;5441    if (Left.is(tok::r_paren) && Left.isNot(TT_AttributeRParen) &&5442        canBeObjCSelectorComponent(Right)) {5443      // Don't space between ')' and <id> or ')' and 'new'. 'new' is not a5444      // keyword in Objective-C, and '+ (instancetype)new;' is a standard class5445      // method declaration.5446      return false;5447    }5448  }5449  if (Line.Type == LT_ObjCProperty &&5450      (Right.is(tok::equal) || Left.is(tok::equal))) {5451    return false;5452  }5453 5454  if (Right.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow) ||5455      Left.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow)) {5456    return true;5457  }5458  if (Left.is(tok::comma) && Right.isNot(TT_OverloadedOperatorLParen) &&5459      // In an unexpanded macro call we only find the parentheses and commas5460      // in a line; the commas and closing parenthesis do not require a space.5461      (Left.Children.empty() || !Left.MacroParent)) {5462    return true;5463  }5464  if (Right.is(tok::comma))5465    return false;5466  if (Right.is(TT_ObjCBlockLParen))5467    return true;5468  if (Right.is(TT_CtorInitializerColon))5469    return Style.SpaceBeforeCtorInitializerColon;5470  if (Right.is(TT_InheritanceColon) && !Style.SpaceBeforeInheritanceColon)5471    return false;5472  if (Right.is(TT_RangeBasedForLoopColon) &&5473      !Style.SpaceBeforeRangeBasedForLoopColon) {5474    return false;5475  }5476  if (Left.is(TT_BitFieldColon)) {5477    return Style.BitFieldColonSpacing == FormatStyle::BFCS_Both ||5478           Style.BitFieldColonSpacing == FormatStyle::BFCS_After;5479  }5480  if (Right.is(tok::colon)) {5481    if (Right.is(TT_CaseLabelColon))5482      return Style.SpaceBeforeCaseColon;5483    if (Right.is(TT_GotoLabelColon))5484      return false;5485    // `private:` and `public:`.5486    if (!Right.getNextNonComment())5487      return false;5488    if (Right.isOneOf(TT_ObjCSelector, TT_ObjCMethodExpr))5489      return false;5490    if (Left.is(tok::question))5491      return false;5492    if (Right.is(TT_InlineASMColon) && Left.is(tok::coloncolon))5493      return false;5494    if (Right.is(TT_DictLiteral))5495      return Style.SpacesInContainerLiterals;5496    if (Right.is(TT_AttributeColon))5497      return false;5498    if (Right.is(TT_CSharpNamedArgumentColon))5499      return false;5500    if (Right.is(TT_GenericSelectionColon))5501      return false;5502    if (Right.is(TT_BitFieldColon)) {5503      return Style.BitFieldColonSpacing == FormatStyle::BFCS_Both ||5504             Style.BitFieldColonSpacing == FormatStyle::BFCS_Before;5505    }5506    return true;5507  }5508  // Do not merge "- -" into "--".5509  if ((Left.isOneOf(tok::minus, tok::minusminus) &&5510       Right.isOneOf(tok::minus, tok::minusminus)) ||5511      (Left.isOneOf(tok::plus, tok::plusplus) &&5512       Right.isOneOf(tok::plus, tok::plusplus))) {5513    return true;5514  }5515  if (Left.is(TT_UnaryOperator)) {5516    // Lambda captures allow for a lone &, so "&]" needs to be properly5517    // handled.5518    if (Left.is(tok::amp) && Right.is(tok::r_square))5519      return Style.SpacesInSquareBrackets;5520    if (Left.isNot(tok::exclaim))5521      return false;5522    if (Left.TokenText == "!")5523      return Style.SpaceAfterLogicalNot;5524    assert(Left.TokenText == "not");5525    return Right.isOneOf(tok::coloncolon, TT_UnaryOperator) ||5526           (Right.is(tok::l_paren) && Style.SpaceBeforeParensOptions.AfterNot);5527  }5528 5529  // If the next token is a binary operator or a selector name, we have5530  // incorrectly classified the parenthesis as a cast. FIXME: Detect correctly.5531  if (Left.is(TT_CastRParen)) {5532    return Style.SpaceAfterCStyleCast ||5533           Right.isOneOf(TT_BinaryOperator, TT_SelectorName);5534  }5535 5536  auto ShouldAddSpacesInAngles = [this, &Right]() {5537    if (this->Style.SpacesInAngles == FormatStyle::SIAS_Always)5538      return true;5539    if (this->Style.SpacesInAngles == FormatStyle::SIAS_Leave)5540      return Right.hasWhitespaceBefore();5541    return false;5542  };5543 5544  if (Left.is(tok::greater) && Right.is(tok::greater)) {5545    if (Style.isTextProto() ||5546        (Style.Language == FormatStyle::LK_Proto && Left.is(TT_DictLiteral))) {5547      return Style.Cpp11BracedListStyle == FormatStyle::BLS_Block;5548    }5549    return Right.is(TT_TemplateCloser) && Left.is(TT_TemplateCloser) &&5550           ((Style.Standard < FormatStyle::LS_Cpp11) ||5551            ShouldAddSpacesInAngles());5552  }5553  if (Right.isOneOf(tok::arrow, tok::arrowstar, tok::periodstar) ||5554      Left.isOneOf(tok::arrow, tok::period, tok::arrowstar, tok::periodstar) ||5555      (Right.is(tok::period) && Right.isNot(TT_DesignatedInitializerPeriod))) {5556    return false;5557  }5558  if (!Style.SpaceBeforeAssignmentOperators && Left.isNot(TT_TemplateCloser) &&5559      Right.getPrecedence() == prec::Assignment) {5560    return false;5561  }5562  if (Style.isJava() && Right.is(tok::coloncolon) &&5563      Left.isOneOf(tok::identifier, tok::kw_this)) {5564    return false;5565  }5566  if (Right.is(tok::coloncolon) && Left.is(tok::identifier)) {5567    // Generally don't remove existing spaces between an identifier and "::".5568    // The identifier might actually be a macro name such as ALWAYS_INLINE. If5569    // this turns out to be too lenient, add analysis of the identifier itself.5570    return Right.hasWhitespaceBefore();5571  }5572  if (Right.is(tok::coloncolon) &&5573      Left.isNoneOf(tok::l_brace, tok::comment, tok::l_paren)) {5574    // Put a space between < and :: in vector< ::std::string >5575    return (Left.is(TT_TemplateOpener) &&5576            ((Style.Standard < FormatStyle::LS_Cpp11) ||5577             ShouldAddSpacesInAngles())) ||5578           Left.isNoneOf(tok::l_paren, tok::r_paren, tok::l_square,5579                         tok::kw___super, TT_TemplateOpener,5580                         TT_TemplateCloser) ||5581           (Left.is(tok::l_paren) && Style.SpacesInParensOptions.Other);5582  }5583  if ((Left.is(TT_TemplateOpener)) != (Right.is(TT_TemplateCloser)))5584    return ShouldAddSpacesInAngles();5585  if (Left.is(tok::r_paren) && Left.isNot(TT_TypeDeclarationParen) &&5586      Right.is(TT_PointerOrReference) && Right.isOneOf(tok::amp, tok::ampamp)) {5587    return true;5588  }5589  // Space before TT_StructuredBindingLSquare.5590  if (Right.is(TT_StructuredBindingLSquare)) {5591    return Left.isNoneOf(tok::amp, tok::ampamp) ||5592           getTokenReferenceAlignment(Left) != FormatStyle::PAS_Right;5593  }5594  // Space before & or && following a TT_StructuredBindingLSquare.5595  if (Right.Next && Right.Next->is(TT_StructuredBindingLSquare) &&5596      Right.isOneOf(tok::amp, tok::ampamp)) {5597    return getTokenReferenceAlignment(Right) != FormatStyle::PAS_Left;5598  }5599  if ((Right.is(TT_BinaryOperator) && Left.isNot(tok::l_paren)) ||5600      (Left.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) &&5601       Right.isNot(tok::r_paren))) {5602    return true;5603  }5604  if (Right.is(TT_TemplateOpener) && Left.is(tok::r_paren) &&5605      Left.MatchingParen &&5606      Left.MatchingParen->is(TT_OverloadedOperatorLParen)) {5607    return false;5608  }5609  if (Right.is(tok::less) && Left.isNot(tok::l_paren) &&5610      Line.Type == LT_ImportStatement) {5611    return true;5612  }5613  if (Right.is(TT_TrailingUnaryOperator))5614    return false;5615  if (Left.is(TT_RegexLiteral))5616    return false;5617  return spaceRequiredBetween(Line, Left, Right);5618}5619 5620// Returns 'true' if 'Tok' is a brace we'd want to break before in Allman style.5621static bool isAllmanBrace(const FormatToken &Tok) {5622  return Tok.is(tok::l_brace) && Tok.is(BK_Block) &&5623         Tok.isNoneOf(TT_ObjCBlockLBrace, TT_LambdaLBrace, TT_DictLiteral);5624}5625 5626// Returns 'true' if 'Tok' is a function argument.5627static bool IsFunctionArgument(const FormatToken &Tok) {5628  return Tok.MatchingParen && Tok.MatchingParen->Next &&5629         Tok.MatchingParen->Next->isOneOf(tok::comma, tok::r_paren,5630                                          tok::r_brace);5631}5632 5633static bool5634isEmptyLambdaAllowed(const FormatToken &Tok,5635                     FormatStyle::ShortLambdaStyle ShortLambdaOption) {5636  return Tok.Children.empty() && ShortLambdaOption != FormatStyle::SLS_None;5637}5638 5639static bool isAllmanLambdaBrace(const FormatToken &Tok) {5640  return Tok.is(tok::l_brace) && Tok.is(BK_Block) &&5641         Tok.isNoneOf(TT_ObjCBlockLBrace, TT_DictLiteral);5642}5643 5644bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,5645                                     const FormatToken &Right) const {5646  if (Right.NewlinesBefore > 1 && Style.MaxEmptyLinesToKeep > 0 &&5647      (!Style.RemoveEmptyLinesInUnwrappedLines || &Right == Line.First)) {5648    return true;5649  }5650 5651  const FormatToken &Left = *Right.Previous;5652 5653  if (Style.BreakFunctionDefinitionParameters && Line.MightBeFunctionDecl &&5654      Line.mightBeFunctionDefinition() && Left.MightBeFunctionDeclParen &&5655      Left.ParameterCount > 0) {5656    return true;5657  }5658 5659  // Ignores the first parameter as this will be handled separately by5660  // BreakFunctionDefinitionParameters or AlignAfterOpenBracket.5661  if (Style.BinPackParameters == FormatStyle::BPPS_AlwaysOnePerLine &&5662      Line.MightBeFunctionDecl && !Left.opensScope() &&5663      startsNextParameter(Right, Style)) {5664    return true;5665  }5666 5667  const auto *BeforeLeft = Left.Previous;5668  const auto *AfterRight = Right.Next;5669 5670  if (Style.isCSharp()) {5671    if (Left.is(TT_FatArrow) && Right.is(tok::l_brace) &&5672        Style.BraceWrapping.AfterFunction) {5673      return true;5674    }5675    if (Right.is(TT_CSharpNamedArgumentColon) ||5676        Left.is(TT_CSharpNamedArgumentColon)) {5677      return false;5678    }5679    if (Right.is(TT_CSharpGenericTypeConstraint))5680      return true;5681    if (AfterRight && AfterRight->is(TT_FatArrow) &&5682        (Right.is(tok::numeric_constant) ||5683         (Right.is(tok::identifier) && Right.TokenText == "_"))) {5684      return true;5685    }5686 5687    // Break after C# [...] and before public/protected/private/internal.5688    if (Left.is(TT_AttributeRSquare) &&5689        (Right.isAccessSpecifier(/*ColonRequired=*/false) ||5690         Right.is(Keywords.kw_internal))) {5691      return true;5692    }5693    // Break between ] and [ but only when there are really 2 attributes.5694    if (Left.is(TT_AttributeRSquare) && Right.is(TT_AttributeLSquare))5695      return true;5696  } else if (Style.isJavaScript()) {5697    // FIXME: This might apply to other languages and token kinds.5698    if (Right.is(tok::string_literal) && Left.is(tok::plus) && BeforeLeft &&5699        BeforeLeft->is(tok::string_literal)) {5700      return true;5701    }5702    if (Left.is(TT_DictLiteral) && Left.is(tok::l_brace) && Line.Level == 0 &&5703        BeforeLeft && BeforeLeft->is(tok::equal) &&5704        Line.First->isOneOf(tok::identifier, Keywords.kw_import, tok::kw_export,5705                            tok::kw_const) &&5706        // kw_var/kw_let are pseudo-tokens that are tok::identifier, so match5707        // above.5708        Line.First->isNoneOf(Keywords.kw_var, Keywords.kw_let)) {5709      // Object literals on the top level of a file are treated as "enum-style".5710      // Each key/value pair is put on a separate line, instead of bin-packing.5711      return true;5712    }5713    if (Left.is(tok::l_brace) && Line.Level == 0 &&5714        (Line.startsWith(tok::kw_enum) ||5715         Line.startsWith(tok::kw_const, tok::kw_enum) ||5716         Line.startsWith(tok::kw_export, tok::kw_enum) ||5717         Line.startsWith(tok::kw_export, tok::kw_const, tok::kw_enum))) {5718      // JavaScript top-level enum key/value pairs are put on separate lines5719      // instead of bin-packing.5720      return true;5721    }5722    if (Right.is(tok::r_brace) && Left.is(tok::l_brace) && BeforeLeft &&5723        BeforeLeft->is(TT_FatArrow)) {5724      // JS arrow function (=> {...}).5725      switch (Style.AllowShortLambdasOnASingleLine) {5726      case FormatStyle::SLS_All:5727        return false;5728      case FormatStyle::SLS_None:5729        return true;5730      case FormatStyle::SLS_Empty:5731        return !Left.Children.empty();5732      case FormatStyle::SLS_Inline:5733        // allow one-lining inline (e.g. in function call args) and empty arrow5734        // functions.5735        return (Left.NestingLevel == 0 && Line.Level == 0) &&5736               !Left.Children.empty();5737      }5738      llvm_unreachable("Unknown FormatStyle::ShortLambdaStyle enum");5739    }5740 5741    if (Right.is(tok::r_brace) && Left.is(tok::l_brace) &&5742        !Left.Children.empty()) {5743      // Support AllowShortFunctionsOnASingleLine for JavaScript.5744      return Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_None ||5745             Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Empty ||5746             (Left.NestingLevel == 0 && Line.Level == 0 &&5747              Style.AllowShortFunctionsOnASingleLine &5748                  FormatStyle::SFS_InlineOnly);5749    }5750  } else if (Style.isJava()) {5751    if (Right.is(tok::plus) && Left.is(tok::string_literal) && AfterRight &&5752        AfterRight->is(tok::string_literal)) {5753      return true;5754    }5755  } else if (Style.isVerilog()) {5756    // Break between assignments.5757    if (Left.is(TT_VerilogAssignComma))5758      return true;5759    // Break between ports of different types.5760    if (Left.is(TT_VerilogTypeComma))5761      return true;5762    // Break between ports in a module instantiation and after the parameter5763    // list.5764    if (Style.VerilogBreakBetweenInstancePorts &&5765        (Left.is(TT_VerilogInstancePortComma) ||5766         (Left.is(tok::r_paren) && Keywords.isVerilogIdentifier(Right) &&5767          Left.MatchingParen &&5768          Left.MatchingParen->is(TT_VerilogInstancePortLParen)))) {5769      return true;5770    }5771    // Break after labels. In Verilog labels don't have the 'case' keyword, so5772    // it is hard to identify them in UnwrappedLineParser.5773    if (!Keywords.isVerilogBegin(Right) && Keywords.isVerilogEndOfLabel(Left))5774      return true;5775  } else if (Style.BreakAdjacentStringLiterals &&5776             (IsCpp || Style.isProto() || Style.isTableGen())) {5777    if (Left.isStringLiteral() && Right.isStringLiteral())5778      return true;5779  }5780 5781  // Basic JSON newline processing.5782  if (Style.isJson()) {5783    // Always break after a JSON record opener.5784    // {5785    // }5786    if (Left.is(TT_DictLiteral) && Left.is(tok::l_brace))5787      return true;5788    // Always break after a JSON array opener based on BreakArrays.5789    if ((Left.is(TT_ArrayInitializerLSquare) && Left.is(tok::l_square) &&5790         Right.isNot(tok::r_square)) ||5791        Left.is(tok::comma)) {5792      if (Right.is(tok::l_brace))5793        return true;5794      // scan to the right if an we see an object or an array inside5795      // then break.5796      for (const auto *Tok = &Right; Tok; Tok = Tok->Next) {5797        if (Tok->isOneOf(tok::l_brace, tok::l_square))5798          return true;5799        if (Tok->isOneOf(tok::r_brace, tok::r_square))5800          break;5801      }5802      return Style.BreakArrays;5803    }5804  } else if (Style.isTableGen()) {5805    // Break the comma in side cond operators.5806    // !cond(case1:1,5807    //       case2:0);5808    if (Left.is(TT_TableGenCondOperatorComma))5809      return true;5810    if (Left.is(TT_TableGenDAGArgOperatorToBreak) &&5811        Right.isNot(TT_TableGenDAGArgCloser)) {5812      return true;5813    }5814    if (Left.is(TT_TableGenDAGArgListCommaToBreak))5815      return true;5816    if (Right.is(TT_TableGenDAGArgCloser) && Right.MatchingParen &&5817        Right.MatchingParen->is(TT_TableGenDAGArgOpenerToBreak) &&5818        &Left != Right.MatchingParen->Next) {5819      // Check to avoid empty DAGArg such as (ins).5820      return Style.TableGenBreakInsideDAGArg == FormatStyle::DAS_BreakAll;5821    }5822  }5823 5824  if (Line.startsWith(tok::kw_asm) && Right.is(TT_InlineASMColon) &&5825      Style.BreakBeforeInlineASMColon == FormatStyle::BBIAS_Always) {5826    return true;5827  }5828 5829  // If the last token before a '}', ']', or ')' is a comma or a trailing5830  // comment, the intention is to insert a line break after it in order to make5831  // shuffling around entries easier. Import statements, especially in5832  // JavaScript, can be an exception to this rule.5833  if (Style.JavaScriptWrapImports || Line.Type != LT_ImportStatement) {5834    const FormatToken *BeforeClosingBrace = nullptr;5835    if ((Left.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||5836         (Style.isJavaScript() && Left.is(tok::l_paren))) &&5837        Left.isNot(BK_Block) && Left.MatchingParen) {5838      BeforeClosingBrace = Left.MatchingParen->Previous;5839    } else if (Right.MatchingParen &&5840               (Right.MatchingParen->isOneOf(tok::l_brace,5841                                             TT_ArrayInitializerLSquare) ||5842                (Style.isJavaScript() &&5843                 Right.MatchingParen->is(tok::l_paren)))) {5844      BeforeClosingBrace = &Left;5845    }5846    if (BeforeClosingBrace && (BeforeClosingBrace->is(tok::comma) ||5847                               BeforeClosingBrace->isTrailingComment())) {5848      return true;5849    }5850  }5851 5852  if (Right.is(tok::comment)) {5853    return Left.isNoneOf(BK_BracedInit, TT_CtorInitializerColon) &&5854           Right.NewlinesBefore > 0 && Right.HasUnescapedNewline;5855  }5856  if (Left.isTrailingComment())5857    return true;5858  if (Left.IsUnterminatedLiteral)5859    return true;5860 5861  if (BeforeLeft && BeforeLeft->is(tok::lessless) &&5862      Left.is(tok::string_literal) && Right.is(tok::lessless) && AfterRight &&5863      AfterRight->is(tok::string_literal)) {5864    return Right.NewlinesBefore > 0;5865  }5866 5867  if (Right.is(TT_RequiresClause)) {5868    switch (Style.RequiresClausePosition) {5869    case FormatStyle::RCPS_OwnLine:5870    case FormatStyle::RCPS_OwnLineWithBrace:5871    case FormatStyle::RCPS_WithFollowing:5872      return true;5873    default:5874      break;5875    }5876  }5877  // Can break after template<> declaration5878  if (Left.ClosesTemplateDeclaration && Left.MatchingParen &&5879      Left.MatchingParen->NestingLevel == 0) {5880    // Put concepts on the next line e.g.5881    // template<typename T>5882    // concept ...5883    if (Right.is(tok::kw_concept))5884      return Style.BreakBeforeConceptDeclarations == FormatStyle::BBCDS_Always;5885    return Style.BreakTemplateDeclarations == FormatStyle::BTDS_Yes ||5886           (Style.BreakTemplateDeclarations == FormatStyle::BTDS_Leave &&5887            Right.NewlinesBefore > 0);5888  }5889  if (Left.ClosesRequiresClause) {5890    switch (Style.RequiresClausePosition) {5891    case FormatStyle::RCPS_OwnLine:5892    case FormatStyle::RCPS_WithPreceding:5893      return Right.isNot(tok::semi);5894    case FormatStyle::RCPS_OwnLineWithBrace:5895      return Right.isNoneOf(tok::semi, tok::l_brace);5896    default:5897      break;5898    }5899  }5900  if (Style.PackConstructorInitializers == FormatStyle::PCIS_Never) {5901    if (Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeColon &&5902        (Left.is(TT_CtorInitializerComma) ||5903         Right.is(TT_CtorInitializerColon))) {5904      return true;5905    }5906 5907    if (Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon &&5908        Left.isOneOf(TT_CtorInitializerColon, TT_CtorInitializerComma)) {5909      return true;5910    }5911  }5912  if (Style.PackConstructorInitializers < FormatStyle::PCIS_CurrentLine &&5913      Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma &&5914      Right.isOneOf(TT_CtorInitializerComma, TT_CtorInitializerColon)) {5915    return true;5916  }5917  if (Style.PackConstructorInitializers == FormatStyle::PCIS_NextLineOnly) {5918    if ((Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeColon ||5919         Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma) &&5920        Right.is(TT_CtorInitializerColon)) {5921      return true;5922    }5923 5924    if (Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon &&5925        Left.is(TT_CtorInitializerColon)) {5926      return true;5927    }5928  }5929  // Break only if we have multiple inheritance.5930  if (Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma &&5931      Right.is(TT_InheritanceComma)) {5932    return true;5933  }5934  if (Style.BreakInheritanceList == FormatStyle::BILS_AfterComma &&5935      Left.is(TT_InheritanceComma)) {5936    return true;5937  }5938  if (Right.is(tok::string_literal) && Right.TokenText.starts_with("R\"")) {5939    // Multiline raw string literals are special wrt. line breaks. The author5940    // has made a deliberate choice and might have aligned the contents of the5941    // string literal accordingly. Thus, we try keep existing line breaks.5942    return Right.IsMultiline && Right.NewlinesBefore > 0;5943  }5944  if ((Left.is(tok::l_brace) ||5945       (Left.is(tok::less) && BeforeLeft && BeforeLeft->is(tok::equal))) &&5946      Right.NestingLevel == 1 && Style.Language == FormatStyle::LK_Proto) {5947    // Don't put enums or option definitions onto single lines in protocol5948    // buffers.5949    return true;5950  }5951  if (Right.is(TT_InlineASMBrace))5952    return Right.HasUnescapedNewline;5953 5954  if (isAllmanBrace(Left) || isAllmanBrace(Right)) {5955    auto *FirstNonComment = Line.getFirstNonComment();5956    bool AccessSpecifier =5957        FirstNonComment && (FirstNonComment->is(Keywords.kw_internal) ||5958                            FirstNonComment->isAccessSpecifierKeyword());5959 5960    if (Style.BraceWrapping.AfterEnum) {5961      if (Line.startsWith(tok::kw_enum) ||5962          Line.startsWith(tok::kw_typedef, tok::kw_enum)) {5963        return true;5964      }5965      // Ensure BraceWrapping for `public enum A {`.5966      if (AccessSpecifier && FirstNonComment->Next &&5967          FirstNonComment->Next->is(tok::kw_enum)) {5968        return true;5969      }5970    }5971 5972    // Ensure BraceWrapping for `public interface A {`.5973    if (Style.BraceWrapping.AfterClass &&5974        ((AccessSpecifier && FirstNonComment->Next &&5975          FirstNonComment->Next->is(Keywords.kw_interface)) ||5976         Line.startsWith(Keywords.kw_interface))) {5977      return true;5978    }5979 5980    // Don't attempt to interpret struct return types as structs.5981    if (Right.isNot(TT_FunctionLBrace)) {5982      return (Line.startsWith(tok::kw_class) &&5983              Style.BraceWrapping.AfterClass) ||5984             (Line.startsWith(tok::kw_struct) &&5985              Style.BraceWrapping.AfterStruct);5986    }5987  }5988 5989  if (Left.is(TT_ObjCBlockLBrace) &&5990      Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Never) {5991    return true;5992  }5993 5994  // Ensure wrapping after __attribute__((XX)) and @interface etc.5995  if (Left.isOneOf(TT_AttributeRParen, TT_AttributeMacro) &&5996      Right.is(TT_ObjCDecl)) {5997    return true;5998  }5999 6000  if (Left.is(TT_LambdaLBrace)) {6001    if (IsFunctionArgument(Left) &&6002        Style.AllowShortLambdasOnASingleLine == FormatStyle::SLS_Inline) {6003      return false;6004    }6005 6006    if (Style.AllowShortLambdasOnASingleLine == FormatStyle::SLS_None ||6007        Style.AllowShortLambdasOnASingleLine == FormatStyle::SLS_Inline ||6008        (!Left.Children.empty() &&6009         Style.AllowShortLambdasOnASingleLine == FormatStyle::SLS_Empty)) {6010      return true;6011    }6012  }6013 6014  if (Style.BraceWrapping.BeforeLambdaBody && Right.is(TT_LambdaLBrace) &&6015      (Left.isPointerOrReference() || Left.is(TT_TemplateCloser))) {6016    return true;6017  }6018 6019  // Put multiple Java annotation on a new line.6020  if ((Style.isJava() || Style.isJavaScript()) &&6021      Left.is(TT_LeadingJavaAnnotation) &&6022      Right.isNoneOf(TT_LeadingJavaAnnotation, tok::l_paren) &&6023      (Line.Last->is(tok::l_brace) || Style.BreakAfterJavaFieldAnnotations)) {6024    return true;6025  }6026 6027  if (Right.is(TT_ProtoExtensionLSquare))6028    return true;6029 6030  // In text proto instances if a submessage contains at least 2 entries and at6031  // least one of them is a submessage, like A { ... B { ... } ... },6032  // put all of the entries of A on separate lines by forcing the selector of6033  // the submessage B to be put on a newline.6034  //6035  // Example: these can stay on one line:6036  // a { scalar_1: 1 scalar_2: 2 }6037  // a { b { key: value } }6038  //6039  // and these entries need to be on a new line even if putting them all in one6040  // line is under the column limit:6041  // a {6042  //   scalar: 16043  //   b { key: value }6044  // }6045  //6046  // We enforce this by breaking before a submessage field that has previous6047  // siblings, *and* breaking before a field that follows a submessage field.6048  //6049  // Be careful to exclude the case  [proto.ext] { ... } since the `]` is6050  // the TT_SelectorName there, but we don't want to break inside the brackets.6051  //6052  // Another edge case is @submessage { key: value }, which is a common6053  // substitution placeholder. In this case we want to keep `@` and `submessage`6054  // together.6055  //6056  // We ensure elsewhere that extensions are always on their own line.6057  if (Style.isProto() && Right.is(TT_SelectorName) &&6058      Right.isNot(tok::r_square) && AfterRight) {6059    // Keep `@submessage` together in:6060    // @submessage { key: value }6061    if (Left.is(tok::at))6062      return false;6063    // Look for the scope opener after selector in cases like:6064    // selector { ...6065    // selector: { ...6066    // selector: @base { ...6067    const auto *LBrace = AfterRight;6068    if (LBrace && LBrace->is(tok::colon)) {6069      LBrace = LBrace->Next;6070      if (LBrace && LBrace->is(tok::at)) {6071        LBrace = LBrace->Next;6072        if (LBrace)6073          LBrace = LBrace->Next;6074      }6075    }6076    if (LBrace &&6077        // The scope opener is one of {, [, <:6078        // selector { ... }6079        // selector [ ... ]6080        // selector < ... >6081        //6082        // In case of selector { ... }, the l_brace is TT_DictLiteral.6083        // In case of an empty selector {}, the l_brace is not TT_DictLiteral,6084        // so we check for immediately following r_brace.6085        ((LBrace->is(tok::l_brace) &&6086          (LBrace->is(TT_DictLiteral) ||6087           (LBrace->Next && LBrace->Next->is(tok::r_brace)))) ||6088         LBrace->isOneOf(TT_ArrayInitializerLSquare, tok::less))) {6089      // If Left.ParameterCount is 0, then this submessage entry is not the6090      // first in its parent submessage, and we want to break before this entry.6091      // If Left.ParameterCount is greater than 0, then its parent submessage6092      // might contain 1 or more entries and we want to break before this entry6093      // if it contains at least 2 entries. We deal with this case later by6094      // detecting and breaking before the next entry in the parent submessage.6095      if (Left.ParameterCount == 0)6096        return true;6097      // However, if this submessage is the first entry in its parent6098      // submessage, Left.ParameterCount might be 1 in some cases.6099      // We deal with this case later by detecting an entry6100      // following a closing paren of this submessage.6101    }6102 6103    // If this is an entry immediately following a submessage, it will be6104    // preceded by a closing paren of that submessage, like in:6105    //     left---.  .---right6106    //            v  v6107    // sub: { ... } key: value6108    // If there was a comment between `}` an `key` above, then `key` would be6109    // put on a new line anyways.6110    if (Left.isOneOf(tok::r_brace, tok::greater, tok::r_square))6111      return true;6112  }6113 6114  return false;6115}6116 6117bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,6118                                    const FormatToken &Right) const {6119  const FormatToken &Left = *Right.Previous;6120  // Language-specific stuff.6121  if (Style.isCSharp()) {6122    if (Left.isOneOf(TT_CSharpNamedArgumentColon, TT_AttributeColon) ||6123        Right.isOneOf(TT_CSharpNamedArgumentColon, TT_AttributeColon)) {6124      return false;6125    }6126    // Only break after commas for generic type constraints.6127    if (Line.First->is(TT_CSharpGenericTypeConstraint))6128      return Left.is(TT_CSharpGenericTypeConstraintComma);6129    // Keep nullable operators attached to their identifiers.6130    if (Right.is(TT_CSharpNullable))6131      return false;6132  } else if (Style.isJava()) {6133    if (Left.isOneOf(Keywords.kw_throws, Keywords.kw_extends,6134                     Keywords.kw_implements)) {6135      return false;6136    }6137    if (Right.isOneOf(Keywords.kw_throws, Keywords.kw_extends,6138                      Keywords.kw_implements)) {6139      return true;6140    }6141  } else if (Style.isJavaScript()) {6142    const FormatToken *NonComment = Right.getPreviousNonComment();6143    if (NonComment &&6144        (NonComment->isAccessSpecifierKeyword() ||6145         NonComment->isOneOf(6146             tok::kw_return, Keywords.kw_yield, tok::kw_continue, tok::kw_break,6147             tok::kw_throw, Keywords.kw_interface, Keywords.kw_type,6148             tok::kw_static, Keywords.kw_readonly, Keywords.kw_override,6149             Keywords.kw_abstract, Keywords.kw_get, Keywords.kw_set,6150             Keywords.kw_async, Keywords.kw_await))) {6151      return false; // Otherwise automatic semicolon insertion would trigger.6152    }6153    if (Right.NestingLevel == 0 &&6154        (Left.Tok.getIdentifierInfo() ||6155         Left.isOneOf(tok::r_square, tok::r_paren)) &&6156        Right.isOneOf(tok::l_square, tok::l_paren)) {6157      return false; // Otherwise automatic semicolon insertion would trigger.6158    }6159    if (NonComment && NonComment->is(tok::identifier) &&6160        NonComment->TokenText == "asserts") {6161      return false;6162    }6163    if (Left.is(TT_FatArrow) && Right.is(tok::l_brace))6164      return false;6165    if (Left.is(TT_JsTypeColon))6166      return true;6167    // Don't wrap between ":" and "!" of a strict prop init ("field!: type;").6168    if (Left.is(tok::exclaim) && Right.is(tok::colon))6169      return false;6170    // Look for is type annotations like:6171    // function f(): a is B { ... }6172    // Do not break before is in these cases.6173    if (Right.is(Keywords.kw_is)) {6174      const FormatToken *Next = Right.getNextNonComment();6175      // If `is` is followed by a colon, it's likely that it's a dict key, so6176      // ignore it for this check.6177      // For example this is common in Polymer:6178      // Polymer({6179      //   is: 'name',6180      //   ...6181      // });6182      if (!Next || Next->isNot(tok::colon))6183        return false;6184    }6185    if (Left.is(Keywords.kw_in))6186      return Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None;6187    if (Right.is(Keywords.kw_in))6188      return Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None;6189    if (Right.is(Keywords.kw_as))6190      return false; // must not break before as in 'x as type' casts6191    if (Right.isOneOf(Keywords.kw_extends, Keywords.kw_infer)) {6192      // extends and infer can appear as keywords in conditional types:6193      //   https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#conditional-types6194      // do not break before them, as the expressions are subject to ASI.6195      return false;6196    }6197    if (Left.is(Keywords.kw_as))6198      return true;6199    if (Left.is(TT_NonNullAssertion))6200      return true;6201    if (Left.is(Keywords.kw_declare) &&6202        Right.isOneOf(Keywords.kw_module, tok::kw_namespace,6203                      Keywords.kw_function, tok::kw_class, tok::kw_enum,6204                      Keywords.kw_interface, Keywords.kw_type, Keywords.kw_var,6205                      Keywords.kw_let, tok::kw_const)) {6206      // See grammar for 'declare' statements at:6207      // https://github.com/Microsoft/TypeScript/blob/main/doc/spec-ARCHIVED.md#A.106208      return false;6209    }6210    if (Left.isOneOf(Keywords.kw_module, tok::kw_namespace) &&6211        Right.isOneOf(tok::identifier, tok::string_literal)) {6212      return false; // must not break in "module foo { ...}"6213    }6214    if (Right.is(TT_TemplateString) && Right.closesScope())6215      return false;6216    // Don't split tagged template literal so there is a break between the tag6217    // identifier and template string.6218    if (Left.is(tok::identifier) && Right.is(TT_TemplateString))6219      return false;6220    if (Left.is(TT_TemplateString) && Left.opensScope())6221      return true;6222  } else if (Style.isTableGen()) {6223    // Avoid to break after "def", "class", "let" and so on.6224    if (Keywords.isTableGenDefinition(Left))6225      return false;6226    // Avoid to break after '(' in the cases that is in bang operators.6227    if (Right.is(tok::l_paren)) {6228      return Left.isNoneOf(TT_TableGenBangOperator, TT_TableGenCondOperator,6229                           TT_TemplateCloser);6230    }6231    // Avoid to break between the value and its suffix part.6232    if (Left.is(TT_TableGenValueSuffix))6233      return false;6234    // Avoid to break around paste operator.6235    if (Left.is(tok::hash) || Right.is(tok::hash))6236      return false;6237    if (Left.isOneOf(TT_TableGenBangOperator, TT_TableGenCondOperator))6238      return false;6239  }6240 6241  // We can break before an r_brace if there was a break after the matching6242  // l_brace, which is tracked by BreakBeforeClosingBrace, or if we are in a6243  // block-indented initialization list.6244  if (Right.is(tok::r_brace)) {6245    return Right.MatchingParen && (Right.MatchingParen->is(BK_Block) ||6246                                   (Right.isBlockIndentedInitRBrace(Style)));6247  }6248 6249  // We can break before r_paren if we're in a block indented context or6250  // a control statement with an explicit style option.6251  if (Right.is(tok::r_paren)) {6252    if (!Right.MatchingParen)6253      return false;6254    auto Next = Right.Next;6255    if (Next && Next->is(tok::r_paren))6256      Next = Next->Next;6257    if (Next && Next->is(tok::l_paren))6258      return false;6259    const FormatToken *Previous = Right.MatchingParen->Previous;6260    if (!Previous)6261      return false;6262    if (Previous->isIf())6263      return Style.BreakBeforeCloseBracketIf;6264    if (Previous->isLoop(Style))6265      return Style.BreakBeforeCloseBracketLoop;6266    if (Previous->is(tok::kw_switch))6267      return Style.BreakBeforeCloseBracketSwitch;6268    return Style.BreakBeforeCloseBracketFunction;6269  }6270 6271  if (Left.isOneOf(tok::r_paren, TT_TrailingAnnotation) &&6272      Right.is(TT_TrailingAnnotation) &&6273      Style.BreakBeforeCloseBracketFunction) {6274    return false;6275  }6276 6277  if (Right.is(TT_TemplateCloser))6278    return Style.BreakBeforeTemplateCloser;6279 6280  if (Left.isOneOf(tok::at, tok::objc_interface))6281    return false;6282  if (Left.isOneOf(TT_JavaAnnotation, TT_LeadingJavaAnnotation))6283    return Right.isNot(tok::l_paren);6284  if (Right.is(TT_PointerOrReference)) {6285    return Line.IsMultiVariableDeclStmt ||6286           (getTokenPointerOrReferenceAlignment(Right) ==6287                FormatStyle::PAS_Right &&6288            !(Right.Next &&6289              Right.Next->isOneOf(TT_FunctionDeclarationName, tok::kw_const)));6290  }6291  if (Right.isOneOf(TT_StartOfName, TT_FunctionDeclarationName,6292                    TT_ClassHeadName, TT_QtProperty, tok::kw_operator)) {6293    return true;6294  }6295  if (Left.is(TT_PointerOrReference))6296    return false;6297  if (Right.isTrailingComment()) {6298    // We rely on MustBreakBefore being set correctly here as we should not6299    // change the "binding" behavior of a comment.6300    // The first comment in a braced lists is always interpreted as belonging to6301    // the first list element. Otherwise, it should be placed outside of the6302    // list.6303    return Left.is(BK_BracedInit) ||6304           (Left.is(TT_CtorInitializerColon) && Right.NewlinesBefore > 0 &&6305            Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon);6306  }6307  if (Left.is(tok::question) && Right.is(tok::colon))6308    return false;6309  if (Right.isOneOf(TT_ConditionalExpr, tok::question))6310    return Style.BreakBeforeTernaryOperators;6311  if (Left.isOneOf(TT_ConditionalExpr, tok::question))6312    return !Style.BreakBeforeTernaryOperators;6313  if (Left.is(TT_InheritanceColon))6314    return Style.BreakInheritanceList == FormatStyle::BILS_AfterColon;6315  if (Right.is(TT_InheritanceColon))6316    return Style.BreakInheritanceList != FormatStyle::BILS_AfterColon;6317  // When the method parameter has no name, allow breaking before the colon.6318  if (Right.is(TT_ObjCMethodExpr) && Right.isNot(tok::r_square) &&6319      Left.isNot(TT_SelectorName)) {6320    return true;6321  }6322 6323  if (Right.is(tok::colon) &&6324      Right.isNoneOf(TT_CtorInitializerColon, TT_InlineASMColon,6325                     TT_BitFieldColon)) {6326    return false;6327  }6328  if (Left.is(tok::colon) && Left.isOneOf(TT_ObjCSelector, TT_ObjCMethodExpr))6329    return true;6330  if (Left.is(tok::colon) && Left.is(TT_DictLiteral)) {6331    if (Style.isProto()) {6332      if (!Style.AlwaysBreakBeforeMultilineStrings && Right.isStringLiteral())6333        return false;6334      // Prevent cases like:6335      //6336      // submessage:6337      //     { key: valueeeeeeeeeeee }6338      //6339      // when the snippet does not fit into one line.6340      // Prefer:6341      //6342      // submessage: {6343      //   key: valueeeeeeeeeeee6344      // }6345      //6346      // instead, even if it is longer by one line.6347      //6348      // Note that this allows the "{" to go over the column limit6349      // when the column limit is just between ":" and "{", but that does6350      // not happen too often and alternative formattings in this case are6351      // not much better.6352      //6353      // The code covers the cases:6354      //6355      // submessage: { ... }6356      // submessage: < ... >6357      // repeated: [ ... ]6358      if ((Right.isOneOf(tok::l_brace, tok::less) &&6359           Right.is(TT_DictLiteral)) ||6360          Right.is(TT_ArrayInitializerLSquare)) {6361        return false;6362      }6363    }6364    return true;6365  }6366  if (Right.is(tok::r_square) && Right.MatchingParen &&6367      Right.MatchingParen->is(TT_ProtoExtensionLSquare)) {6368    return false;6369  }6370  if (Right.is(TT_SelectorName) || (Right.is(tok::identifier) && Right.Next &&6371                                    Right.Next->is(TT_ObjCMethodExpr))) {6372    return Left.isNot(tok::period); // FIXME: Properly parse ObjC calls.6373  }6374  if (Left.is(tok::r_paren) && Line.Type == LT_ObjCProperty)6375    return true;6376  if (Right.is(tok::kw_concept))6377    return Style.BreakBeforeConceptDeclarations != FormatStyle::BBCDS_Never;6378  if (Right.is(TT_RequiresClause))6379    return true;6380  if (Left.ClosesTemplateDeclaration) {6381    return Style.BreakTemplateDeclarations != FormatStyle::BTDS_Leave ||6382           Right.NewlinesBefore > 0;6383  }6384  if (Left.is(TT_FunctionAnnotationRParen))6385    return true;6386  if (Left.ClosesRequiresClause)6387    return true;6388  if (Right.isOneOf(TT_RangeBasedForLoopColon, TT_OverloadedOperatorLParen,6389                    TT_OverloadedOperator)) {6390    return false;6391  }6392  if (Left.is(TT_RangeBasedForLoopColon))6393    return true;6394  if (Right.is(TT_RangeBasedForLoopColon))6395    return false;6396  if (Left.is(TT_TemplateCloser) && Right.is(TT_TemplateOpener))6397    return true;6398  if ((Left.is(tok::greater) && Right.is(tok::greater)) ||6399      (Left.is(tok::less) && Right.is(tok::less))) {6400    return false;6401  }6402  if (Right.is(TT_BinaryOperator) &&6403      Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None &&6404      (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_All ||6405       Right.getPrecedence() != prec::Assignment)) {6406    return true;6407  }6408  if (Left.isOneOf(TT_TemplateCloser, TT_UnaryOperator, tok::kw_operator))6409    return false;6410  if (Left.is(tok::equal) && Right.isNoneOf(tok::kw_default, tok::kw_delete) &&6411      Line.Type == LT_VirtualFunctionDecl && Left.NestingLevel == 0) {6412    return false;6413  }6414  if (Left.is(tok::equal) && Right.is(tok::l_brace) &&6415      Style.Cpp11BracedListStyle == FormatStyle::BLS_Block) {6416    return false;6417  }6418  if (Left.is(TT_AttributeLParen) ||6419      (Left.is(tok::l_paren) && Left.is(TT_TypeDeclarationParen))) {6420    return false;6421  }6422  if (Left.is(tok::l_paren) && Left.Previous &&6423      (Left.Previous->isOneOf(TT_BinaryOperator, TT_CastRParen))) {6424    return false;6425  }6426  if (Right.is(TT_ImplicitStringLiteral))6427    return false;6428 6429  if (Right.is(tok::r_square) && Right.MatchingParen &&6430      Right.MatchingParen->is(TT_LambdaLSquare)) {6431    return false;6432  }6433 6434  // Allow breaking after a trailing annotation, e.g. after a method6435  // declaration.6436  if (Left.is(TT_TrailingAnnotation)) {6437    return Right.isNoneOf(tok::l_brace, tok::semi, tok::equal, tok::l_paren,6438                          tok::less, tok::coloncolon);6439  }6440 6441  if (Right.isAttribute())6442    return true;6443 6444  if (Right.is(TT_AttributeLSquare)) {6445    assert(Left.isNot(tok::l_square));6446    return true;6447  }6448 6449  if (Left.is(tok::identifier) && Right.is(tok::string_literal))6450    return true;6451 6452  if (Right.is(tok::identifier) && Right.Next && Right.Next->is(TT_DictLiteral))6453    return true;6454 6455  if (Left.is(TT_CtorInitializerColon)) {6456    return Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon &&6457           (!Right.isTrailingComment() || Right.NewlinesBefore > 0);6458  }6459  if (Right.is(TT_CtorInitializerColon))6460    return Style.BreakConstructorInitializers != FormatStyle::BCIS_AfterColon;6461  if (Left.is(TT_CtorInitializerComma) &&6462      Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma) {6463    return false;6464  }6465  if (Right.is(TT_CtorInitializerComma) &&6466      Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma) {6467    return true;6468  }6469  if (Left.is(TT_InheritanceComma) &&6470      Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma) {6471    return false;6472  }6473  if (Right.is(TT_InheritanceComma) &&6474      Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma) {6475    return true;6476  }6477  if (Left.is(TT_ArrayInitializerLSquare))6478    return true;6479  if (Right.is(tok::kw_typename) && Left.isNot(tok::kw_const))6480    return true;6481  if ((Left.isBinaryOperator() || Left.is(TT_BinaryOperator)) &&6482      Left.isNoneOf(tok::arrowstar, tok::lessless) &&6483      Style.BreakBeforeBinaryOperators != FormatStyle::BOS_All &&6484      (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None ||6485       Left.getPrecedence() == prec::Assignment)) {6486    return true;6487  }6488  if (Left.is(TT_AttributeLSquare) && Right.is(tok::l_square)) {6489    assert(Right.isNot(TT_AttributeLSquare));6490    return false;6491  }6492  if (Left.is(tok::r_square) && Right.is(TT_AttributeRSquare)) {6493    assert(Left.isNot(TT_AttributeRSquare));6494    return false;6495  }6496 6497  auto ShortLambdaOption = Style.AllowShortLambdasOnASingleLine;6498  if (Style.BraceWrapping.BeforeLambdaBody && Right.is(TT_LambdaLBrace)) {6499    if (isAllmanLambdaBrace(Left))6500      return !isEmptyLambdaAllowed(Left, ShortLambdaOption);6501    if (isAllmanLambdaBrace(Right))6502      return !isEmptyLambdaAllowed(Right, ShortLambdaOption);6503  }6504 6505  if (Right.is(tok::kw_noexcept) && Right.is(TT_TrailingAnnotation)) {6506    switch (Style.AllowBreakBeforeNoexceptSpecifier) {6507    case FormatStyle::BBNSS_Never:6508      return false;6509    case FormatStyle::BBNSS_Always:6510      return true;6511    case FormatStyle::BBNSS_OnlyWithParen:6512      return Right.Next && Right.Next->is(tok::l_paren);6513    }6514  }6515 6516  return Left.isOneOf(tok::comma, tok::coloncolon, tok::semi, tok::l_brace,6517                      tok::kw_class, tok::kw_struct, tok::comment) ||6518         Right.isMemberAccess() ||6519         Right.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow, tok::lessless,6520                       tok::colon, tok::l_square, tok::at) ||6521         (Left.is(tok::r_paren) &&6522          Right.isOneOf(tok::identifier, tok::kw_const)) ||6523         (Left.is(tok::l_paren) && Right.isNot(tok::r_paren)) ||6524         (Left.is(TT_TemplateOpener) && Right.isNot(TT_TemplateCloser));6525}6526 6527void TokenAnnotator::printDebugInfo(const AnnotatedLine &Line) const {6528  llvm::errs() << "AnnotatedTokens(L=" << Line.Level << ", P=" << Line.PPLevel6529               << ", T=" << Line.Type << ", C=" << Line.IsContinuation6530               << "):\n";6531  const FormatToken *Tok = Line.First;6532  while (Tok) {6533    llvm::errs() << " I=" << Tok->IndentLevel << " M=" << Tok->MustBreakBefore6534                 << " C=" << Tok->CanBreakBefore6535                 << " T=" << getTokenTypeName(Tok->getType())6536                 << " S=" << Tok->SpacesRequiredBefore6537                 << " F=" << Tok->Finalized << " B=" << Tok->BlockParameterCount6538                 << " BK=" << Tok->getBlockKind() << " P=" << Tok->SplitPenalty6539                 << " Name=" << Tok->Tok.getName() << " N=" << Tok->NestingLevel6540                 << " L=" << Tok->TotalLength6541                 << " PPK=" << Tok->getPackingKind() << " FakeLParens=";6542    for (prec::Level LParen : Tok->FakeLParens)6543      llvm::errs() << LParen << "/";6544    llvm::errs() << " FakeRParens=" << Tok->FakeRParens;6545    llvm::errs() << " II=" << Tok->Tok.getIdentifierInfo();6546    llvm::errs() << " Text='" << Tok->TokenText << "'\n";6547    if (!Tok->Next)6548      assert(Tok == Line.Last);6549    Tok = Tok->Next;6550  }6551  llvm::errs() << "----\n";6552}6553 6554FormatStyle::PointerAlignmentStyle6555TokenAnnotator::getTokenReferenceAlignment(const FormatToken &Reference) const {6556  assert(Reference.isOneOf(tok::amp, tok::ampamp));6557  switch (Style.ReferenceAlignment) {6558  case FormatStyle::RAS_Pointer:6559    return Style.PointerAlignment;6560  case FormatStyle::RAS_Left:6561    return FormatStyle::PAS_Left;6562  case FormatStyle::RAS_Right:6563    return FormatStyle::PAS_Right;6564  case FormatStyle::RAS_Middle:6565    return FormatStyle::PAS_Middle;6566  }6567  assert(0); //"Unhandled value of ReferenceAlignment"6568  return Style.PointerAlignment;6569}6570 6571FormatStyle::PointerAlignmentStyle6572TokenAnnotator::getTokenPointerOrReferenceAlignment(6573    const FormatToken &PointerOrReference) const {6574  if (PointerOrReference.isOneOf(tok::amp, tok::ampamp))6575    return getTokenReferenceAlignment(PointerOrReference);6576  assert(PointerOrReference.is(tok::star));6577  return Style.PointerAlignment;6578}6579 6580} // namespace format6581} // namespace clang6582