xref: /freebsd-src/contrib/llvm-project/clang/lib/Format/TokenAnnotator.cpp (revision 5deeebd8c6ca991269e72902a7a62cada57947f6)
10b57cec5SDimitry Andric //===--- TokenAnnotator.cpp - Format C++ code -----------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric ///
90b57cec5SDimitry Andric /// \file
100b57cec5SDimitry Andric /// This file implements a token annotator, i.e. creates
110b57cec5SDimitry Andric /// \c AnnotatedTokens out of \c FormatTokens with required extra information.
120b57cec5SDimitry Andric ///
130b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
140b57cec5SDimitry Andric 
150b57cec5SDimitry Andric #include "TokenAnnotator.h"
160b57cec5SDimitry Andric #include "FormatToken.h"
170b57cec5SDimitry Andric #include "clang/Basic/SourceManager.h"
18a7dea167SDimitry Andric #include "clang/Basic/TokenKinds.h"
190b57cec5SDimitry Andric #include "llvm/ADT/SmallPtrSet.h"
200b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
210b57cec5SDimitry Andric 
220b57cec5SDimitry Andric #define DEBUG_TYPE "format-token-annotator"
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric namespace clang {
250b57cec5SDimitry Andric namespace format {
260b57cec5SDimitry Andric 
275f757f3fSDimitry Andric static bool mustBreakAfterAttributes(const FormatToken &Tok,
285f757f3fSDimitry Andric                                      const FormatStyle &Style) {
295f757f3fSDimitry Andric   switch (Style.BreakAfterAttributes) {
305f757f3fSDimitry Andric   case FormatStyle::ABS_Always:
315f757f3fSDimitry Andric     return true;
325f757f3fSDimitry Andric   case FormatStyle::ABS_Leave:
335f757f3fSDimitry Andric     return Tok.NewlinesBefore > 0;
345f757f3fSDimitry Andric   default:
355f757f3fSDimitry Andric     return false;
365f757f3fSDimitry Andric   }
375f757f3fSDimitry Andric }
385f757f3fSDimitry Andric 
390b57cec5SDimitry Andric namespace {
400b57cec5SDimitry Andric 
4181ad6265SDimitry Andric /// Returns \c true if the line starts with a token that can start a statement
4281ad6265SDimitry Andric /// with an initializer.
4381ad6265SDimitry Andric static bool startsWithInitStatement(const AnnotatedLine &Line) {
4481ad6265SDimitry Andric   return Line.startsWith(tok::kw_for) || Line.startsWith(tok::kw_if) ||
4581ad6265SDimitry Andric          Line.startsWith(tok::kw_switch);
4681ad6265SDimitry Andric }
4781ad6265SDimitry Andric 
480b57cec5SDimitry Andric /// Returns \c true if the token can be used as an identifier in
49e8d8bef9SDimitry Andric /// an Objective-C \c \@selector, \c false otherwise.
500b57cec5SDimitry Andric ///
510b57cec5SDimitry Andric /// Because getFormattingLangOpts() always lexes source code as
520b57cec5SDimitry Andric /// Objective-C++, C++ keywords like \c new and \c delete are
530b57cec5SDimitry Andric /// lexed as tok::kw_*, not tok::identifier, even for Objective-C.
540b57cec5SDimitry Andric ///
550b57cec5SDimitry Andric /// For Objective-C and Objective-C++, both identifiers and keywords
560b57cec5SDimitry Andric /// are valid inside @selector(...) (or a macro which
570b57cec5SDimitry Andric /// invokes @selector(...)). So, we allow treat any identifier or
580b57cec5SDimitry Andric /// keyword as a potential Objective-C selector component.
590b57cec5SDimitry Andric static bool canBeObjCSelectorComponent(const FormatToken &Tok) {
6006c3fb27SDimitry Andric   return Tok.Tok.getIdentifierInfo();
610b57cec5SDimitry Andric }
620b57cec5SDimitry Andric 
63a7dea167SDimitry Andric /// With `Left` being '(', check if we're at either `[...](` or
64a7dea167SDimitry Andric /// `[...]<...>(`, where the [ opens a lambda capture list.
65a7dea167SDimitry Andric static bool isLambdaParameterList(const FormatToken *Left) {
66a7dea167SDimitry Andric   // Skip <...> if present.
67a7dea167SDimitry Andric   if (Left->Previous && Left->Previous->is(tok::greater) &&
68a7dea167SDimitry Andric       Left->Previous->MatchingParen &&
6981ad6265SDimitry Andric       Left->Previous->MatchingParen->is(TT_TemplateOpener)) {
70a7dea167SDimitry Andric     Left = Left->Previous->MatchingParen;
7181ad6265SDimitry Andric   }
72a7dea167SDimitry Andric 
73a7dea167SDimitry Andric   // Check for `[...]`.
74a7dea167SDimitry Andric   return Left->Previous && Left->Previous->is(tok::r_square) &&
75a7dea167SDimitry Andric          Left->Previous->MatchingParen &&
76a7dea167SDimitry Andric          Left->Previous->MatchingParen->is(TT_LambdaLSquare);
77a7dea167SDimitry Andric }
78a7dea167SDimitry Andric 
7916d6b3b3SDimitry Andric /// Returns \c true if the token is followed by a boolean condition, \c false
8016d6b3b3SDimitry Andric /// otherwise.
8116d6b3b3SDimitry Andric static bool isKeywordWithCondition(const FormatToken &Tok) {
8216d6b3b3SDimitry Andric   return Tok.isOneOf(tok::kw_if, tok::kw_for, tok::kw_while, tok::kw_switch,
8316d6b3b3SDimitry Andric                      tok::kw_constexpr, tok::kw_catch);
8416d6b3b3SDimitry Andric }
8516d6b3b3SDimitry Andric 
86bdd1243dSDimitry Andric /// Returns \c true if the token starts a C++ attribute, \c false otherwise.
87bdd1243dSDimitry Andric static bool isCppAttribute(bool IsCpp, const FormatToken &Tok) {
88bdd1243dSDimitry Andric   if (!IsCpp || !Tok.startsSequence(tok::l_square, tok::l_square))
89bdd1243dSDimitry Andric     return false;
90bdd1243dSDimitry Andric   // The first square bracket is part of an ObjC array literal
91bdd1243dSDimitry Andric   if (Tok.Previous && Tok.Previous->is(tok::at))
92bdd1243dSDimitry Andric     return false;
93bdd1243dSDimitry Andric   const FormatToken *AttrTok = Tok.Next->Next;
94bdd1243dSDimitry Andric   if (!AttrTok)
95bdd1243dSDimitry Andric     return false;
96bdd1243dSDimitry Andric   // C++17 '[[using ns: foo, bar(baz, blech)]]'
97bdd1243dSDimitry Andric   // We assume nobody will name an ObjC variable 'using'.
98bdd1243dSDimitry Andric   if (AttrTok->startsSequence(tok::kw_using, tok::identifier, tok::colon))
99bdd1243dSDimitry Andric     return true;
100bdd1243dSDimitry Andric   if (AttrTok->isNot(tok::identifier))
101bdd1243dSDimitry Andric     return false;
102bdd1243dSDimitry Andric   while (AttrTok && !AttrTok->startsSequence(tok::r_square, tok::r_square)) {
103bdd1243dSDimitry Andric     // ObjC message send. We assume nobody will use : in a C++11 attribute
104bdd1243dSDimitry Andric     // specifier parameter, although this is technically valid:
105bdd1243dSDimitry Andric     // [[foo(:)]].
106bdd1243dSDimitry Andric     if (AttrTok->is(tok::colon) ||
107bdd1243dSDimitry Andric         AttrTok->startsSequence(tok::identifier, tok::identifier) ||
108bdd1243dSDimitry Andric         AttrTok->startsSequence(tok::r_paren, tok::identifier)) {
109bdd1243dSDimitry Andric       return false;
110bdd1243dSDimitry Andric     }
111bdd1243dSDimitry Andric     if (AttrTok->is(tok::ellipsis))
112bdd1243dSDimitry Andric       return true;
113bdd1243dSDimitry Andric     AttrTok = AttrTok->Next;
114bdd1243dSDimitry Andric   }
115bdd1243dSDimitry Andric   return AttrTok && AttrTok->startsSequence(tok::r_square, tok::r_square);
116bdd1243dSDimitry Andric }
117bdd1243dSDimitry Andric 
1180b57cec5SDimitry Andric /// A parser that gathers additional information about tokens.
1190b57cec5SDimitry Andric ///
1200b57cec5SDimitry Andric /// The \c TokenAnnotator tries to match parenthesis and square brakets and
1210b57cec5SDimitry Andric /// store a parenthesis levels. It also tries to resolve matching "<" and ">"
1220b57cec5SDimitry Andric /// into template parameter lists.
1230b57cec5SDimitry Andric class AnnotatingParser {
1240b57cec5SDimitry Andric public:
1250b57cec5SDimitry Andric   AnnotatingParser(const FormatStyle &Style, AnnotatedLine &Line,
12606c3fb27SDimitry Andric                    const AdditionalKeywords &Keywords,
12706c3fb27SDimitry Andric                    SmallVector<ScopeType> &Scopes)
1280b57cec5SDimitry Andric       : Style(Style), Line(Line), CurrentToken(Line.First), AutoFound(false),
1290fca6ea1SDimitry Andric         IsCpp(Style.isCpp()), LangOpts(getFormattingLangOpts(Style)),
1300fca6ea1SDimitry Andric         Keywords(Keywords), Scopes(Scopes), TemplateDeclarationDepth(0) {
1310fca6ea1SDimitry Andric     assert(IsCpp == LangOpts.CXXOperatorNames);
1320b57cec5SDimitry Andric     Contexts.push_back(Context(tok::unknown, 1, /*IsExpression=*/false));
13304eeddc0SDimitry Andric     resetTokenMetadata();
1340b57cec5SDimitry Andric   }
1350b57cec5SDimitry Andric 
1360b57cec5SDimitry Andric private:
13706c3fb27SDimitry Andric   ScopeType getScopeType(const FormatToken &Token) const {
13806c3fb27SDimitry Andric     switch (Token.getType()) {
13906c3fb27SDimitry Andric     case TT_FunctionLBrace:
14006c3fb27SDimitry Andric     case TT_LambdaLBrace:
14106c3fb27SDimitry Andric       return ST_Function;
14206c3fb27SDimitry Andric     case TT_ClassLBrace:
14306c3fb27SDimitry Andric     case TT_StructLBrace:
14406c3fb27SDimitry Andric     case TT_UnionLBrace:
14506c3fb27SDimitry Andric       return ST_Class;
14606c3fb27SDimitry Andric     default:
14706c3fb27SDimitry Andric       return ST_Other;
14806c3fb27SDimitry Andric     }
14906c3fb27SDimitry Andric   }
15006c3fb27SDimitry Andric 
1510b57cec5SDimitry Andric   bool parseAngle() {
1520b57cec5SDimitry Andric     if (!CurrentToken || !CurrentToken->Previous)
1530b57cec5SDimitry Andric       return false;
1545f757f3fSDimitry Andric     if (NonTemplateLess.count(CurrentToken->Previous) > 0)
1550b57cec5SDimitry Andric       return false;
1560b57cec5SDimitry Andric 
15752418fc2SDimitry Andric     if (const auto &Previous = *CurrentToken->Previous; // The '<'.
15852418fc2SDimitry Andric         Previous.Previous) {
1590b57cec5SDimitry Andric       if (Previous.Previous->Tok.isLiteral())
1600b57cec5SDimitry Andric         return false;
16106c3fb27SDimitry Andric       if (Previous.Previous->is(tok::r_brace))
16206c3fb27SDimitry Andric         return false;
1630b57cec5SDimitry Andric       if (Previous.Previous->is(tok::r_paren) && Contexts.size() > 1 &&
1640b57cec5SDimitry Andric           (!Previous.Previous->MatchingParen ||
1655f757f3fSDimitry Andric            Previous.Previous->MatchingParen->isNot(
16681ad6265SDimitry Andric                TT_OverloadedOperatorLParen))) {
1670b57cec5SDimitry Andric         return false;
1680b57cec5SDimitry Andric       }
1695f757f3fSDimitry Andric       if (Previous.Previous->is(tok::kw_operator) &&
1705f757f3fSDimitry Andric           CurrentToken->is(tok::l_paren)) {
1715f757f3fSDimitry Andric         return false;
1725f757f3fSDimitry Andric       }
17381ad6265SDimitry Andric     }
1740b57cec5SDimitry Andric 
1750b57cec5SDimitry Andric     FormatToken *Left = CurrentToken->Previous;
1760b57cec5SDimitry Andric     Left->ParentBracket = Contexts.back().ContextKind;
1770b57cec5SDimitry Andric     ScopedContextCreator ContextCreator(*this, tok::less, 12);
1780b57cec5SDimitry Andric     Contexts.back().IsExpression = false;
17952418fc2SDimitry Andric 
18052418fc2SDimitry Andric     const auto *BeforeLess = Left->Previous;
18152418fc2SDimitry Andric 
1820b57cec5SDimitry Andric     // If there's a template keyword before the opening angle bracket, this is a
1830b57cec5SDimitry Andric     // template parameter, not an argument.
18452418fc2SDimitry Andric     if (BeforeLess && BeforeLess->isNot(tok::kw_template))
18581ad6265SDimitry Andric       Contexts.back().ContextType = Context::TemplateArgument;
1860b57cec5SDimitry Andric 
1870b57cec5SDimitry Andric     if (Style.Language == FormatStyle::LK_Java &&
18881ad6265SDimitry Andric         CurrentToken->is(tok::question)) {
1890b57cec5SDimitry Andric       next();
19081ad6265SDimitry Andric     }
1910b57cec5SDimitry Andric 
192*5deeebd8SDimitry Andric     for (bool SeenTernaryOperator = false, MaybeAngles = true; CurrentToken;) {
19352418fc2SDimitry Andric       const bool InExpr = Contexts[Contexts.size() - 2].IsExpression;
1940b57cec5SDimitry Andric       if (CurrentToken->is(tok::greater)) {
19552418fc2SDimitry Andric         const auto *Next = CurrentToken->Next;
196*5deeebd8SDimitry Andric         if (CurrentToken->isNot(TT_TemplateCloser)) {
19716d6b3b3SDimitry Andric           // Try to do a better job at looking for ">>" within the condition of
198fe6060f1SDimitry Andric           // a statement. Conservatively insert spaces between consecutive ">"
199*5deeebd8SDimitry Andric           // tokens to prevent splitting right shift operators and potentially
200fe6060f1SDimitry Andric           // altering program semantics. This check is overly conservative and
201fe6060f1SDimitry Andric           // will prevent spaces from being inserted in select nested template
202fe6060f1SDimitry Andric           // parameter cases, but should not alter program semantics.
20352418fc2SDimitry Andric           if (Next && Next->is(tok::greater) &&
20416d6b3b3SDimitry Andric               Left->ParentBracket != tok::less &&
205fe6060f1SDimitry Andric               CurrentToken->getStartOfNonWhitespace() ==
20652418fc2SDimitry Andric                   Next->getStartOfNonWhitespace().getLocWithOffset(-1)) {
20752418fc2SDimitry Andric             return false;
20852418fc2SDimitry Andric           }
20952418fc2SDimitry Andric           if (InExpr && SeenTernaryOperator &&
21052418fc2SDimitry Andric               (!Next || !Next->isOneOf(tok::l_paren, tok::l_brace))) {
21116d6b3b3SDimitry Andric             return false;
21281ad6265SDimitry Andric           }
213*5deeebd8SDimitry Andric           if (!MaybeAngles)
214*5deeebd8SDimitry Andric             return false;
215*5deeebd8SDimitry Andric         }
2160b57cec5SDimitry Andric         Left->MatchingParen = CurrentToken;
2170b57cec5SDimitry Andric         CurrentToken->MatchingParen = Left;
2180b57cec5SDimitry Andric         // In TT_Proto, we must distignuish between:
2190b57cec5SDimitry Andric         //   map<key, value>
2200b57cec5SDimitry Andric         //   msg < item: data >
2210b57cec5SDimitry Andric         //   msg: < item: data >
2220b57cec5SDimitry Andric         // In TT_TextProto, map<key, value> does not occur.
2230b57cec5SDimitry Andric         if (Style.Language == FormatStyle::LK_TextProto ||
22452418fc2SDimitry Andric             (Style.Language == FormatStyle::LK_Proto && BeforeLess &&
22552418fc2SDimitry Andric              BeforeLess->isOneOf(TT_SelectorName, TT_DictLiteral))) {
2265ffd83dbSDimitry Andric           CurrentToken->setType(TT_DictLiteral);
22781ad6265SDimitry Andric         } else {
2285ffd83dbSDimitry Andric           CurrentToken->setType(TT_TemplateCloser);
22906c3fb27SDimitry Andric           CurrentToken->Tok.setLength(1);
23081ad6265SDimitry Andric         }
23152418fc2SDimitry Andric         if (Next && Next->Tok.isLiteral())
23206c3fb27SDimitry Andric           return false;
2330b57cec5SDimitry Andric         next();
2340b57cec5SDimitry Andric         return true;
2350b57cec5SDimitry Andric       }
2360b57cec5SDimitry Andric       if (CurrentToken->is(tok::question) &&
2370b57cec5SDimitry Andric           Style.Language == FormatStyle::LK_Java) {
2380b57cec5SDimitry Andric         next();
2390b57cec5SDimitry Andric         continue;
2400b57cec5SDimitry Andric       }
2410fca6ea1SDimitry Andric       if (CurrentToken->isOneOf(tok::r_paren, tok::r_square, tok::r_brace))
2420b57cec5SDimitry Andric         return false;
24352418fc2SDimitry Andric       const auto &Prev = *CurrentToken->Previous;
2440b57cec5SDimitry Andric       // If a && or || is found and interpreted as a binary operator, this set
2450b57cec5SDimitry Andric       // of angles is likely part of something like "a < b && c > d". If the
2460b57cec5SDimitry Andric       // angles are inside an expression, the ||/&& might also be a binary
2470b57cec5SDimitry Andric       // operator that was misinterpreted because we are parsing template
2480b57cec5SDimitry Andric       // parameters.
2490b57cec5SDimitry Andric       // FIXME: This is getting out of hand, write a decent parser.
250*5deeebd8SDimitry Andric       if (MaybeAngles && InExpr && !Line.startsWith(tok::kw_template) &&
25152418fc2SDimitry Andric           Prev.is(TT_BinaryOperator)) {
25252418fc2SDimitry Andric         const auto Precedence = Prev.getPrecedence();
25352418fc2SDimitry Andric         if (Precedence > prec::Conditional && Precedence < prec::Relational)
254*5deeebd8SDimitry Andric           MaybeAngles = false;
25581ad6265SDimitry Andric       }
2566c4b055cSDimitry Andric       if (Prev.isOneOf(tok::question, tok::colon) && !Style.isProto())
25752418fc2SDimitry Andric         SeenTernaryOperator = true;
2580b57cec5SDimitry Andric       updateParameterCount(Left, CurrentToken);
2590b57cec5SDimitry Andric       if (Style.Language == FormatStyle::LK_Proto) {
2600b57cec5SDimitry Andric         if (FormatToken *Previous = CurrentToken->getPreviousNonComment()) {
2610b57cec5SDimitry Andric           if (CurrentToken->is(tok::colon) ||
2620b57cec5SDimitry Andric               (CurrentToken->isOneOf(tok::l_brace, tok::less) &&
26381ad6265SDimitry Andric                Previous->isNot(tok::colon))) {
2645ffd83dbSDimitry Andric             Previous->setType(TT_SelectorName);
2650b57cec5SDimitry Andric           }
2660b57cec5SDimitry Andric         }
26781ad6265SDimitry Andric       }
2680fca6ea1SDimitry Andric       if (Style.isTableGen()) {
2690fca6ea1SDimitry Andric         if (CurrentToken->isOneOf(tok::comma, tok::equal)) {
2700fca6ea1SDimitry Andric           // They appear as separators. Unless they are not in class definition.
2710fca6ea1SDimitry Andric           next();
2720fca6ea1SDimitry Andric           continue;
2730fca6ea1SDimitry Andric         }
2740fca6ea1SDimitry Andric         // In angle, there must be Value like tokens. Types are also able to be
2750fca6ea1SDimitry Andric         // parsed in the same way with Values.
2760fca6ea1SDimitry Andric         if (!parseTableGenValue())
2770fca6ea1SDimitry Andric           return false;
2780fca6ea1SDimitry Andric         continue;
2790fca6ea1SDimitry Andric       }
2800b57cec5SDimitry Andric       if (!consumeToken())
2810b57cec5SDimitry Andric         return false;
2820b57cec5SDimitry Andric     }
2830b57cec5SDimitry Andric     return false;
2840b57cec5SDimitry Andric   }
2850b57cec5SDimitry Andric 
2865ffd83dbSDimitry Andric   bool parseUntouchableParens() {
2875ffd83dbSDimitry Andric     while (CurrentToken) {
2885ffd83dbSDimitry Andric       CurrentToken->Finalized = true;
2895ffd83dbSDimitry Andric       switch (CurrentToken->Tok.getKind()) {
2905ffd83dbSDimitry Andric       case tok::l_paren:
2915ffd83dbSDimitry Andric         next();
2925ffd83dbSDimitry Andric         if (!parseUntouchableParens())
2935ffd83dbSDimitry Andric           return false;
2945ffd83dbSDimitry Andric         continue;
2955ffd83dbSDimitry Andric       case tok::r_paren:
2965ffd83dbSDimitry Andric         next();
2975ffd83dbSDimitry Andric         return true;
2985ffd83dbSDimitry Andric       default:
2995ffd83dbSDimitry Andric         // no-op
3005ffd83dbSDimitry Andric         break;
3015ffd83dbSDimitry Andric       }
3025ffd83dbSDimitry Andric       next();
3035ffd83dbSDimitry Andric     }
3045ffd83dbSDimitry Andric     return false;
3055ffd83dbSDimitry Andric   }
3065ffd83dbSDimitry Andric 
3070b57cec5SDimitry Andric   bool parseParens(bool LookForDecls = false) {
3080b57cec5SDimitry Andric     if (!CurrentToken)
3090b57cec5SDimitry Andric       return false;
31081ad6265SDimitry Andric     assert(CurrentToken->Previous && "Unknown previous token");
31181ad6265SDimitry Andric     FormatToken &OpeningParen = *CurrentToken->Previous;
31281ad6265SDimitry Andric     assert(OpeningParen.is(tok::l_paren));
31381ad6265SDimitry Andric     FormatToken *PrevNonComment = OpeningParen.getPreviousNonComment();
31481ad6265SDimitry Andric     OpeningParen.ParentBracket = Contexts.back().ContextKind;
3150b57cec5SDimitry Andric     ScopedContextCreator ContextCreator(*this, tok::l_paren, 1);
3160b57cec5SDimitry Andric 
3170b57cec5SDimitry Andric     // FIXME: This is a bit of a hack. Do better.
3180b57cec5SDimitry Andric     Contexts.back().ColonIsForRangeExpr =
3190b57cec5SDimitry Andric         Contexts.size() == 2 && Contexts[0].ColonIsForRangeExpr;
3200b57cec5SDimitry Andric 
32181ad6265SDimitry Andric     if (OpeningParen.Previous &&
32281ad6265SDimitry Andric         OpeningParen.Previous->is(TT_UntouchableMacroFunc)) {
32381ad6265SDimitry Andric       OpeningParen.Finalized = true;
3245ffd83dbSDimitry Andric       return parseUntouchableParens();
3255ffd83dbSDimitry Andric     }
3265ffd83dbSDimitry Andric 
3270b57cec5SDimitry Andric     bool StartsObjCMethodExpr = false;
328bdd1243dSDimitry Andric     if (!Style.isVerilog()) {
32981ad6265SDimitry Andric       if (FormatToken *MaybeSel = OpeningParen.Previous) {
3300b57cec5SDimitry Andric         // @selector( starts a selector.
331bdd1243dSDimitry Andric         if (MaybeSel->isObjCAtKeyword(tok::objc_selector) &&
332bdd1243dSDimitry Andric             MaybeSel->Previous && MaybeSel->Previous->is(tok::at)) {
3330b57cec5SDimitry Andric           StartsObjCMethodExpr = true;
3340b57cec5SDimitry Andric         }
3350b57cec5SDimitry Andric       }
336bdd1243dSDimitry Andric     }
3370b57cec5SDimitry Andric 
33881ad6265SDimitry Andric     if (OpeningParen.is(TT_OverloadedOperatorLParen)) {
339fe6060f1SDimitry Andric       // Find the previous kw_operator token.
34081ad6265SDimitry Andric       FormatToken *Prev = &OpeningParen;
3415f757f3fSDimitry Andric       while (Prev->isNot(tok::kw_operator)) {
342fe6060f1SDimitry Andric         Prev = Prev->Previous;
343fe6060f1SDimitry Andric         assert(Prev && "Expect a kw_operator prior to the OperatorLParen!");
344fe6060f1SDimitry Andric       }
345fe6060f1SDimitry Andric 
346fe6060f1SDimitry Andric       // If faced with "a.operator*(argument)" or "a->operator*(argument)",
347fe6060f1SDimitry Andric       // i.e. the operator is called as a member function,
348fe6060f1SDimitry Andric       // then the argument must be an expression.
349fe6060f1SDimitry Andric       bool OperatorCalledAsMemberFunction =
350fe6060f1SDimitry Andric           Prev->Previous && Prev->Previous->isOneOf(tok::period, tok::arrow);
351fe6060f1SDimitry Andric       Contexts.back().IsExpression = OperatorCalledAsMemberFunction;
35206c3fb27SDimitry Andric     } else if (OpeningParen.is(TT_VerilogInstancePortLParen)) {
35306c3fb27SDimitry Andric       Contexts.back().IsExpression = true;
35406c3fb27SDimitry Andric       Contexts.back().ContextType = Context::VerilogInstancePortList;
3550eae32dcSDimitry Andric     } else if (Style.isJavaScript() &&
3560b57cec5SDimitry Andric                (Line.startsWith(Keywords.kw_type, tok::identifier) ||
3570b57cec5SDimitry Andric                 Line.startsWith(tok::kw_export, Keywords.kw_type,
3580b57cec5SDimitry Andric                                 tok::identifier))) {
3590b57cec5SDimitry Andric       // type X = (...);
3600b57cec5SDimitry Andric       // export type X = (...);
3610b57cec5SDimitry Andric       Contexts.back().IsExpression = false;
36281ad6265SDimitry Andric     } else if (OpeningParen.Previous &&
36306c3fb27SDimitry Andric                (OpeningParen.Previous->isOneOf(
36406c3fb27SDimitry Andric                     tok::kw_static_assert, tok::kw_noexcept, tok::kw_explicit,
36506c3fb27SDimitry Andric                     tok::kw_while, tok::l_paren, tok::comma,
36606c3fb27SDimitry Andric                     TT_BinaryOperator) ||
36781ad6265SDimitry Andric                 OpeningParen.Previous->isIf())) {
3680b57cec5SDimitry Andric       // static_assert, if and while usually contain expressions.
3690b57cec5SDimitry Andric       Contexts.back().IsExpression = true;
37081ad6265SDimitry Andric     } else if (Style.isJavaScript() && OpeningParen.Previous &&
37181ad6265SDimitry Andric                (OpeningParen.Previous->is(Keywords.kw_function) ||
37281ad6265SDimitry Andric                 (OpeningParen.Previous->endsSequence(tok::identifier,
3730b57cec5SDimitry Andric                                                      Keywords.kw_function)))) {
3740b57cec5SDimitry Andric       // function(...) or function f(...)
3750b57cec5SDimitry Andric       Contexts.back().IsExpression = false;
37681ad6265SDimitry Andric     } else if (Style.isJavaScript() && OpeningParen.Previous &&
37781ad6265SDimitry Andric                OpeningParen.Previous->is(TT_JsTypeColon)) {
3780b57cec5SDimitry Andric       // let x: (SomeType);
3790b57cec5SDimitry Andric       Contexts.back().IsExpression = false;
38081ad6265SDimitry Andric     } else if (isLambdaParameterList(&OpeningParen)) {
3810b57cec5SDimitry Andric       // This is a parameter list of a lambda expression.
3820b57cec5SDimitry Andric       Contexts.back().IsExpression = false;
383bdd1243dSDimitry Andric     } else if (OpeningParen.is(TT_RequiresExpressionLParen)) {
384bdd1243dSDimitry Andric       Contexts.back().IsExpression = false;
385bdd1243dSDimitry Andric     } else if (OpeningParen.Previous &&
386bdd1243dSDimitry Andric                OpeningParen.Previous->is(tok::kw__Generic)) {
387bdd1243dSDimitry Andric       Contexts.back().ContextType = Context::C11GenericSelection;
388bdd1243dSDimitry Andric       Contexts.back().IsExpression = true;
38952418fc2SDimitry Andric     } else if (Line.InPPDirective &&
39052418fc2SDimitry Andric                (!OpeningParen.Previous ||
39152418fc2SDimitry Andric                 OpeningParen.Previous->isNot(tok::identifier))) {
39252418fc2SDimitry Andric       Contexts.back().IsExpression = true;
3930b57cec5SDimitry Andric     } else if (Contexts[Contexts.size() - 2].CaretFound) {
3940b57cec5SDimitry Andric       // This is the parameter list of an ObjC block.
3950b57cec5SDimitry Andric       Contexts.back().IsExpression = false;
39681ad6265SDimitry Andric     } else if (OpeningParen.Previous &&
39781ad6265SDimitry Andric                OpeningParen.Previous->is(TT_ForEachMacro)) {
3980b57cec5SDimitry Andric       // The first argument to a foreach macro is a declaration.
39981ad6265SDimitry Andric       Contexts.back().ContextType = Context::ForEachMacro;
4000b57cec5SDimitry Andric       Contexts.back().IsExpression = false;
40181ad6265SDimitry Andric     } else if (OpeningParen.Previous && OpeningParen.Previous->MatchingParen &&
402bdd1243dSDimitry Andric                OpeningParen.Previous->MatchingParen->isOneOf(
403bdd1243dSDimitry Andric                    TT_ObjCBlockLParen, TT_FunctionTypeLParen)) {
4040b57cec5SDimitry Andric       Contexts.back().IsExpression = false;
40552418fc2SDimitry Andric     } else if (!Line.MustBeDeclaration && !Line.InPPDirective) {
4060b57cec5SDimitry Andric       bool IsForOrCatch =
40781ad6265SDimitry Andric           OpeningParen.Previous &&
40881ad6265SDimitry Andric           OpeningParen.Previous->isOneOf(tok::kw_for, tok::kw_catch);
4090b57cec5SDimitry Andric       Contexts.back().IsExpression = !IsForOrCatch;
4100b57cec5SDimitry Andric     }
4110b57cec5SDimitry Andric 
4120fca6ea1SDimitry Andric     if (Style.isTableGen()) {
4130fca6ea1SDimitry Andric       if (FormatToken *Prev = OpeningParen.Previous) {
4140fca6ea1SDimitry Andric         if (Prev->is(TT_TableGenCondOperator)) {
4150fca6ea1SDimitry Andric           Contexts.back().IsTableGenCondOpe = true;
4160fca6ea1SDimitry Andric           Contexts.back().IsExpression = true;
4170fca6ea1SDimitry Andric         } else if (Contexts.size() > 1 &&
4180fca6ea1SDimitry Andric                    Contexts[Contexts.size() - 2].IsTableGenBangOpe) {
4190fca6ea1SDimitry Andric           // Hack to handle bang operators. The parent context's flag
4200fca6ea1SDimitry Andric           // was set by parseTableGenSimpleValue().
4210fca6ea1SDimitry Andric           // We have to specify the context outside because the prev of "(" may
4220fca6ea1SDimitry Andric           // be ">", not the bang operator in this case.
4230fca6ea1SDimitry Andric           Contexts.back().IsTableGenBangOpe = true;
4240fca6ea1SDimitry Andric           Contexts.back().IsExpression = true;
4250fca6ea1SDimitry Andric         } else {
4260fca6ea1SDimitry Andric           // Otherwise, this paren seems DAGArg.
4270fca6ea1SDimitry Andric           if (!parseTableGenDAGArg())
4280fca6ea1SDimitry Andric             return false;
4290fca6ea1SDimitry Andric           return parseTableGenDAGArgAndList(&OpeningParen);
4300fca6ea1SDimitry Andric         }
4310fca6ea1SDimitry Andric       }
4320fca6ea1SDimitry Andric     }
4330fca6ea1SDimitry Andric 
434e8d8bef9SDimitry Andric     // Infer the role of the l_paren based on the previous token if we haven't
435bdd1243dSDimitry Andric     // detected one yet.
43681ad6265SDimitry Andric     if (PrevNonComment && OpeningParen.is(TT_Unknown)) {
4375f757f3fSDimitry Andric       if (PrevNonComment->isAttribute()) {
4385f757f3fSDimitry Andric         OpeningParen.setType(TT_AttributeLParen);
439e8d8bef9SDimitry Andric       } else if (PrevNonComment->isOneOf(TT_TypenameMacro, tok::kw_decltype,
440bdd1243dSDimitry Andric                                          tok::kw_typeof,
441bdd1243dSDimitry Andric #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) tok::kw___##Trait,
442bdd1243dSDimitry Andric #include "clang/Basic/TransformTypeTraits.def"
443bdd1243dSDimitry Andric                                          tok::kw__Atomic)) {
44481ad6265SDimitry Andric         OpeningParen.setType(TT_TypeDeclarationParen);
445e8d8bef9SDimitry Andric         // decltype() and typeof() usually contain expressions.
446e8d8bef9SDimitry Andric         if (PrevNonComment->isOneOf(tok::kw_decltype, tok::kw_typeof))
447e8d8bef9SDimitry Andric           Contexts.back().IsExpression = true;
448e8d8bef9SDimitry Andric       }
449e8d8bef9SDimitry Andric     }
450e8d8bef9SDimitry Andric 
4510b57cec5SDimitry Andric     if (StartsObjCMethodExpr) {
4520b57cec5SDimitry Andric       Contexts.back().ColonIsObjCMethodExpr = true;
45381ad6265SDimitry Andric       OpeningParen.setType(TT_ObjCMethodExpr);
4540b57cec5SDimitry Andric     }
4550b57cec5SDimitry Andric 
4560b57cec5SDimitry Andric     // MightBeFunctionType and ProbablyFunctionType are used for
4570b57cec5SDimitry Andric     // function pointer and reference types as well as Objective-C
4580b57cec5SDimitry Andric     // block types:
4590b57cec5SDimitry Andric     //
4600b57cec5SDimitry Andric     // void (*FunctionPointer)(void);
4610b57cec5SDimitry Andric     // void (&FunctionReference)(void);
4624824e7fdSDimitry Andric     // void (&&FunctionReference)(void);
4630b57cec5SDimitry Andric     // void (^ObjCBlock)(void);
4640b57cec5SDimitry Andric     bool MightBeFunctionType = !Contexts[Contexts.size() - 2].IsExpression;
4650b57cec5SDimitry Andric     bool ProbablyFunctionType =
4665f757f3fSDimitry Andric         CurrentToken->isPointerOrReference() || CurrentToken->is(tok::caret);
4670b57cec5SDimitry Andric     bool HasMultipleLines = false;
4680b57cec5SDimitry Andric     bool HasMultipleParametersOnALine = false;
4690b57cec5SDimitry Andric     bool MightBeObjCForRangeLoop =
47081ad6265SDimitry Andric         OpeningParen.Previous && OpeningParen.Previous->is(tok::kw_for);
4710b57cec5SDimitry Andric     FormatToken *PossibleObjCForInToken = nullptr;
4720b57cec5SDimitry Andric     while (CurrentToken) {
4730b57cec5SDimitry Andric       // LookForDecls is set when "if (" has been seen. Check for
4740b57cec5SDimitry Andric       // 'identifier' '*' 'identifier' followed by not '=' -- this
4750b57cec5SDimitry Andric       // '*' has to be a binary operator but determineStarAmpUsage() will
4760b57cec5SDimitry Andric       // categorize it as an unary operator, so set the right type here.
4770b57cec5SDimitry Andric       if (LookForDecls && CurrentToken->Next) {
4780b57cec5SDimitry Andric         FormatToken *Prev = CurrentToken->getPreviousNonComment();
4790b57cec5SDimitry Andric         if (Prev) {
4800b57cec5SDimitry Andric           FormatToken *PrevPrev = Prev->getPreviousNonComment();
4810b57cec5SDimitry Andric           FormatToken *Next = CurrentToken->Next;
4820b57cec5SDimitry Andric           if (PrevPrev && PrevPrev->is(tok::identifier) &&
4835f757f3fSDimitry Andric               PrevPrev->isNot(TT_TypeName) && Prev->isPointerOrReference() &&
4849e7101a8SDimitry Andric               CurrentToken->is(tok::identifier) && Next->isNot(tok::equal)) {
4855ffd83dbSDimitry Andric             Prev->setType(TT_BinaryOperator);
4860b57cec5SDimitry Andric             LookForDecls = false;
4870b57cec5SDimitry Andric           }
4880b57cec5SDimitry Andric         }
4890b57cec5SDimitry Andric       }
4900b57cec5SDimitry Andric 
4910b57cec5SDimitry Andric       if (CurrentToken->Previous->is(TT_PointerOrReference) &&
4920b57cec5SDimitry Andric           CurrentToken->Previous->Previous->isOneOf(tok::l_paren,
49381ad6265SDimitry Andric                                                     tok::coloncolon)) {
4940b57cec5SDimitry Andric         ProbablyFunctionType = true;
49581ad6265SDimitry Andric       }
4960b57cec5SDimitry Andric       if (CurrentToken->is(tok::comma))
4970b57cec5SDimitry Andric         MightBeFunctionType = false;
4980b57cec5SDimitry Andric       if (CurrentToken->Previous->is(TT_BinaryOperator))
4990b57cec5SDimitry Andric         Contexts.back().IsExpression = true;
5000b57cec5SDimitry Andric       if (CurrentToken->is(tok::r_paren)) {
50181ad6265SDimitry Andric         if (OpeningParen.isNot(TT_CppCastLParen) && MightBeFunctionType &&
50281ad6265SDimitry Andric             ProbablyFunctionType && CurrentToken->Next &&
5030b57cec5SDimitry Andric             (CurrentToken->Next->is(tok::l_paren) ||
50481ad6265SDimitry Andric              (CurrentToken->Next->is(tok::l_square) &&
50581ad6265SDimitry Andric               Line.MustBeDeclaration))) {
50681ad6265SDimitry Andric           OpeningParen.setType(OpeningParen.Next->is(tok::caret)
50781ad6265SDimitry Andric                                    ? TT_ObjCBlockLParen
5085ffd83dbSDimitry Andric                                    : TT_FunctionTypeLParen);
50981ad6265SDimitry Andric         }
51081ad6265SDimitry Andric         OpeningParen.MatchingParen = CurrentToken;
51181ad6265SDimitry Andric         CurrentToken->MatchingParen = &OpeningParen;
5120b57cec5SDimitry Andric 
5130b57cec5SDimitry Andric         if (CurrentToken->Next && CurrentToken->Next->is(tok::l_brace) &&
51481ad6265SDimitry Andric             OpeningParen.Previous && OpeningParen.Previous->is(tok::l_paren)) {
5150b57cec5SDimitry Andric           // Detect the case where macros are used to generate lambdas or
5160b57cec5SDimitry Andric           // function bodies, e.g.:
517fe6060f1SDimitry Andric           //   auto my_lambda = MACRO((Type *type, int i) { .. body .. });
51881ad6265SDimitry Andric           for (FormatToken *Tok = &OpeningParen; Tok != CurrentToken;
51981ad6265SDimitry Andric                Tok = Tok->Next) {
5205f757f3fSDimitry Andric             if (Tok->is(TT_BinaryOperator) && Tok->isPointerOrReference())
5215ffd83dbSDimitry Andric               Tok->setType(TT_PointerOrReference);
5220b57cec5SDimitry Andric           }
5230b57cec5SDimitry Andric         }
5240b57cec5SDimitry Andric 
5250b57cec5SDimitry Andric         if (StartsObjCMethodExpr) {
5265ffd83dbSDimitry Andric           CurrentToken->setType(TT_ObjCMethodExpr);
5270b57cec5SDimitry Andric           if (Contexts.back().FirstObjCSelectorName) {
5280b57cec5SDimitry Andric             Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
5290b57cec5SDimitry Andric                 Contexts.back().LongestObjCSelectorName;
5300b57cec5SDimitry Andric           }
5310b57cec5SDimitry Andric         }
5320b57cec5SDimitry Andric 
5335f757f3fSDimitry Andric         if (OpeningParen.is(TT_AttributeLParen))
5345f757f3fSDimitry Andric           CurrentToken->setType(TT_AttributeRParen);
53581ad6265SDimitry Andric         if (OpeningParen.is(TT_TypeDeclarationParen))
536e8d8bef9SDimitry Andric           CurrentToken->setType(TT_TypeDeclarationParen);
53781ad6265SDimitry Andric         if (OpeningParen.Previous &&
53881ad6265SDimitry Andric             OpeningParen.Previous->is(TT_JavaAnnotation)) {
5395ffd83dbSDimitry Andric           CurrentToken->setType(TT_JavaAnnotation);
54081ad6265SDimitry Andric         }
54181ad6265SDimitry Andric         if (OpeningParen.Previous &&
54281ad6265SDimitry Andric             OpeningParen.Previous->is(TT_LeadingJavaAnnotation)) {
5435ffd83dbSDimitry Andric           CurrentToken->setType(TT_LeadingJavaAnnotation);
54481ad6265SDimitry Andric         }
54581ad6265SDimitry Andric         if (OpeningParen.Previous &&
54681ad6265SDimitry Andric             OpeningParen.Previous->is(TT_AttributeSquare)) {
5475ffd83dbSDimitry Andric           CurrentToken->setType(TT_AttributeSquare);
54881ad6265SDimitry Andric         }
5490b57cec5SDimitry Andric 
5500b57cec5SDimitry Andric         if (!HasMultipleLines)
55181ad6265SDimitry Andric           OpeningParen.setPackingKind(PPK_Inconclusive);
5520b57cec5SDimitry Andric         else if (HasMultipleParametersOnALine)
55381ad6265SDimitry Andric           OpeningParen.setPackingKind(PPK_BinPacked);
5540b57cec5SDimitry Andric         else
55581ad6265SDimitry Andric           OpeningParen.setPackingKind(PPK_OnePerLine);
5560b57cec5SDimitry Andric 
5570b57cec5SDimitry Andric         next();
5580b57cec5SDimitry Andric         return true;
5590b57cec5SDimitry Andric       }
5600b57cec5SDimitry Andric       if (CurrentToken->isOneOf(tok::r_square, tok::r_brace))
5610b57cec5SDimitry Andric         return false;
5620b57cec5SDimitry Andric 
56381ad6265SDimitry Andric       if (CurrentToken->is(tok::l_brace) && OpeningParen.is(TT_ObjCBlockLParen))
56481ad6265SDimitry Andric         OpeningParen.setType(TT_Unknown);
5650b57cec5SDimitry Andric       if (CurrentToken->is(tok::comma) && CurrentToken->Next &&
5660b57cec5SDimitry Andric           !CurrentToken->Next->HasUnescapedNewline &&
56781ad6265SDimitry Andric           !CurrentToken->Next->isTrailingComment()) {
5680b57cec5SDimitry Andric         HasMultipleParametersOnALine = true;
56981ad6265SDimitry Andric       }
570fe6060f1SDimitry Andric       bool ProbablyFunctionTypeLParen =
571fe6060f1SDimitry Andric           (CurrentToken->is(tok::l_paren) && CurrentToken->Next &&
572fe6060f1SDimitry Andric            CurrentToken->Next->isOneOf(tok::star, tok::amp, tok::caret));
5730b57cec5SDimitry Andric       if ((CurrentToken->Previous->isOneOf(tok::kw_const, tok::kw_auto) ||
5740fca6ea1SDimitry Andric            CurrentToken->Previous->isTypeName(LangOpts)) &&
575fe6060f1SDimitry Andric           !(CurrentToken->is(tok::l_brace) ||
57681ad6265SDimitry Andric             (CurrentToken->is(tok::l_paren) && !ProbablyFunctionTypeLParen))) {
5770b57cec5SDimitry Andric         Contexts.back().IsExpression = false;
57881ad6265SDimitry Andric       }
5790b57cec5SDimitry Andric       if (CurrentToken->isOneOf(tok::semi, tok::colon)) {
5800b57cec5SDimitry Andric         MightBeObjCForRangeLoop = false;
5810b57cec5SDimitry Andric         if (PossibleObjCForInToken) {
5825ffd83dbSDimitry Andric           PossibleObjCForInToken->setType(TT_Unknown);
5830b57cec5SDimitry Andric           PossibleObjCForInToken = nullptr;
5840b57cec5SDimitry Andric         }
5850b57cec5SDimitry Andric       }
5860b57cec5SDimitry Andric       if (MightBeObjCForRangeLoop && CurrentToken->is(Keywords.kw_in)) {
5870b57cec5SDimitry Andric         PossibleObjCForInToken = CurrentToken;
5885ffd83dbSDimitry Andric         PossibleObjCForInToken->setType(TT_ObjCForIn);
5890b57cec5SDimitry Andric       }
5900b57cec5SDimitry Andric       // When we discover a 'new', we set CanBeExpression to 'false' in order to
5910b57cec5SDimitry Andric       // parse the type correctly. Reset that after a comma.
5920b57cec5SDimitry Andric       if (CurrentToken->is(tok::comma))
5930b57cec5SDimitry Andric         Contexts.back().CanBeExpression = true;
5940b57cec5SDimitry Andric 
5950fca6ea1SDimitry Andric       if (Style.isTableGen()) {
5960fca6ea1SDimitry Andric         if (CurrentToken->is(tok::comma)) {
5970fca6ea1SDimitry Andric           if (Contexts.back().IsTableGenCondOpe)
5980fca6ea1SDimitry Andric             CurrentToken->setType(TT_TableGenCondOperatorComma);
5990fca6ea1SDimitry Andric           next();
6000fca6ea1SDimitry Andric         } else if (CurrentToken->is(tok::colon)) {
6010fca6ea1SDimitry Andric           if (Contexts.back().IsTableGenCondOpe)
6020fca6ea1SDimitry Andric             CurrentToken->setType(TT_TableGenCondOperatorColon);
6030fca6ea1SDimitry Andric           next();
6040fca6ea1SDimitry Andric         }
6050fca6ea1SDimitry Andric         // In TableGen there must be Values in parens.
6060fca6ea1SDimitry Andric         if (!parseTableGenValue())
6070fca6ea1SDimitry Andric           return false;
6080fca6ea1SDimitry Andric         continue;
6090fca6ea1SDimitry Andric       }
6100fca6ea1SDimitry Andric 
6110b57cec5SDimitry Andric       FormatToken *Tok = CurrentToken;
6120b57cec5SDimitry Andric       if (!consumeToken())
6130b57cec5SDimitry Andric         return false;
61481ad6265SDimitry Andric       updateParameterCount(&OpeningParen, Tok);
6150b57cec5SDimitry Andric       if (CurrentToken && CurrentToken->HasUnescapedNewline)
6160b57cec5SDimitry Andric         HasMultipleLines = true;
6170b57cec5SDimitry Andric     }
6180b57cec5SDimitry Andric     return false;
6190b57cec5SDimitry Andric   }
6200b57cec5SDimitry Andric 
6210b57cec5SDimitry Andric   bool isCSharpAttributeSpecifier(const FormatToken &Tok) {
6220b57cec5SDimitry Andric     if (!Style.isCSharp())
6230b57cec5SDimitry Andric       return false;
6240b57cec5SDimitry Andric 
6255ffd83dbSDimitry Andric     // `identifier[i]` is not an attribute.
6265ffd83dbSDimitry Andric     if (Tok.Previous && Tok.Previous->is(tok::identifier))
6275ffd83dbSDimitry Andric       return false;
6285ffd83dbSDimitry Andric 
6295ffd83dbSDimitry Andric     // Chains of [] in `identifier[i][j][k]` are not attributes.
6305ffd83dbSDimitry Andric     if (Tok.Previous && Tok.Previous->is(tok::r_square)) {
6315ffd83dbSDimitry Andric       auto *MatchingParen = Tok.Previous->MatchingParen;
6325ffd83dbSDimitry Andric       if (!MatchingParen || MatchingParen->is(TT_ArraySubscriptLSquare))
6335ffd83dbSDimitry Andric         return false;
6345ffd83dbSDimitry Andric     }
6355ffd83dbSDimitry Andric 
6360b57cec5SDimitry Andric     const FormatToken *AttrTok = Tok.Next;
6370b57cec5SDimitry Andric     if (!AttrTok)
6380b57cec5SDimitry Andric       return false;
6390b57cec5SDimitry Andric 
6400b57cec5SDimitry Andric     // Just an empty declaration e.g. string [].
6410b57cec5SDimitry Andric     if (AttrTok->is(tok::r_square))
6420b57cec5SDimitry Andric       return false;
6430b57cec5SDimitry Andric 
6440b57cec5SDimitry Andric     // Move along the tokens inbetween the '[' and ']' e.g. [STAThread].
64581ad6265SDimitry Andric     while (AttrTok && AttrTok->isNot(tok::r_square))
6460b57cec5SDimitry Andric       AttrTok = AttrTok->Next;
6470b57cec5SDimitry Andric 
6480b57cec5SDimitry Andric     if (!AttrTok)
6490b57cec5SDimitry Andric       return false;
6500b57cec5SDimitry Andric 
6515ffd83dbSDimitry Andric     // Allow an attribute to be the only content of a file.
6520b57cec5SDimitry Andric     AttrTok = AttrTok->Next;
6530b57cec5SDimitry Andric     if (!AttrTok)
6545ffd83dbSDimitry Andric       return true;
6550b57cec5SDimitry Andric 
6560b57cec5SDimitry Andric     // Limit this to being an access modifier that follows.
6570fca6ea1SDimitry Andric     if (AttrTok->isAccessSpecifierKeyword() ||
6580fca6ea1SDimitry Andric         AttrTok->isOneOf(tok::comment, tok::kw_class, tok::kw_static,
6595ffd83dbSDimitry Andric                          tok::l_square, Keywords.kw_internal)) {
6600b57cec5SDimitry Andric       return true;
6610b57cec5SDimitry Andric     }
662a7dea167SDimitry Andric 
663a7dea167SDimitry Andric     // incase its a [XXX] retval func(....
664a7dea167SDimitry Andric     if (AttrTok->Next &&
66581ad6265SDimitry Andric         AttrTok->Next->startsSequence(tok::identifier, tok::l_paren)) {
666a7dea167SDimitry Andric       return true;
66781ad6265SDimitry Andric     }
668a7dea167SDimitry Andric 
6690b57cec5SDimitry Andric     return false;
6700b57cec5SDimitry Andric   }
6710b57cec5SDimitry Andric 
6720b57cec5SDimitry Andric   bool parseSquare() {
6730b57cec5SDimitry Andric     if (!CurrentToken)
6740b57cec5SDimitry Andric       return false;
6750b57cec5SDimitry Andric 
6760b57cec5SDimitry Andric     // A '[' could be an index subscript (after an identifier or after
6770b57cec5SDimitry Andric     // ')' or ']'), it could be the start of an Objective-C method
6780b57cec5SDimitry Andric     // expression, it could the start of an Objective-C array literal,
6790b57cec5SDimitry Andric     // or it could be a C++ attribute specifier [[foo::bar]].
6800b57cec5SDimitry Andric     FormatToken *Left = CurrentToken->Previous;
6810b57cec5SDimitry Andric     Left->ParentBracket = Contexts.back().ContextKind;
6820b57cec5SDimitry Andric     FormatToken *Parent = Left->getPreviousNonComment();
6830b57cec5SDimitry Andric 
6840b57cec5SDimitry Andric     // Cases where '>' is followed by '['.
6850b57cec5SDimitry Andric     // In C++, this can happen either in array of templates (foo<int>[10])
6860b57cec5SDimitry Andric     // or when array is a nested template type (unique_ptr<type1<type2>[]>).
6870b57cec5SDimitry Andric     bool CppArrayTemplates =
6880fca6ea1SDimitry Andric         IsCpp && Parent && Parent->is(TT_TemplateCloser) &&
6890b57cec5SDimitry Andric         (Contexts.back().CanBeExpression || Contexts.back().IsExpression ||
69081ad6265SDimitry Andric          Contexts.back().ContextType == Context::TemplateArgument);
6910b57cec5SDimitry Andric 
692bdd1243dSDimitry Andric     const bool IsInnerSquare = Contexts.back().InCpp11AttributeSpecifier;
693bdd1243dSDimitry Andric     const bool IsCpp11AttributeSpecifier =
6940fca6ea1SDimitry Andric         isCppAttribute(IsCpp, *Left) || IsInnerSquare;
6950b57cec5SDimitry Andric 
6960b57cec5SDimitry Andric     // Treat C# Attributes [STAThread] much like C++ attributes [[...]].
6975ffd83dbSDimitry Andric     bool IsCSharpAttributeSpecifier =
6980b57cec5SDimitry Andric         isCSharpAttributeSpecifier(*Left) ||
6990b57cec5SDimitry Andric         Contexts.back().InCSharpAttributeSpecifier;
7000b57cec5SDimitry Andric 
7010b57cec5SDimitry Andric     bool InsideInlineASM = Line.startsWith(tok::kw_asm);
7020fca6ea1SDimitry Andric     bool IsCppStructuredBinding = Left->isCppStructuredBinding(IsCpp);
7030b57cec5SDimitry Andric     bool StartsObjCMethodExpr =
7040b57cec5SDimitry Andric         !IsCppStructuredBinding && !InsideInlineASM && !CppArrayTemplates &&
7050fca6ea1SDimitry Andric         IsCpp && !IsCpp11AttributeSpecifier && !IsCSharpAttributeSpecifier &&
7060fca6ea1SDimitry Andric         Contexts.back().CanBeExpression && Left->isNot(TT_LambdaLSquare) &&
7070b57cec5SDimitry Andric         !CurrentToken->isOneOf(tok::l_brace, tok::r_square) &&
7080b57cec5SDimitry Andric         (!Parent ||
7090b57cec5SDimitry Andric          Parent->isOneOf(tok::colon, tok::l_square, tok::l_paren,
7100b57cec5SDimitry Andric                          tok::kw_return, tok::kw_throw) ||
7110b57cec5SDimitry Andric          Parent->isUnaryOperator() ||
7120b57cec5SDimitry Andric          // FIXME(bug 36976): ObjC return types shouldn't use TT_CastRParen.
7130b57cec5SDimitry Andric          Parent->isOneOf(TT_ObjCForIn, TT_CastRParen) ||
7140b57cec5SDimitry Andric          (getBinOpPrecedence(Parent->Tok.getKind(), true, true) >
7150b57cec5SDimitry Andric           prec::Unknown));
7160b57cec5SDimitry Andric     bool ColonFound = false;
7170b57cec5SDimitry Andric 
7180b57cec5SDimitry Andric     unsigned BindingIncrease = 1;
7190b57cec5SDimitry Andric     if (IsCppStructuredBinding) {
7205ffd83dbSDimitry Andric       Left->setType(TT_StructuredBindingLSquare);
7210b57cec5SDimitry Andric     } else if (Left->is(TT_Unknown)) {
7220b57cec5SDimitry Andric       if (StartsObjCMethodExpr) {
7235ffd83dbSDimitry Andric         Left->setType(TT_ObjCMethodExpr);
7245ffd83dbSDimitry Andric       } else if (InsideInlineASM) {
7255ffd83dbSDimitry Andric         Left->setType(TT_InlineASMSymbolicNameLSquare);
7260b57cec5SDimitry Andric       } else if (IsCpp11AttributeSpecifier) {
7275ffd83dbSDimitry Andric         Left->setType(TT_AttributeSquare);
728bdd1243dSDimitry Andric         if (!IsInnerSquare && Left->Previous)
729bdd1243dSDimitry Andric           Left->Previous->EndsCppAttributeGroup = false;
7300eae32dcSDimitry Andric       } else if (Style.isJavaScript() && Parent &&
7310b57cec5SDimitry Andric                  Contexts.back().ContextKind == tok::l_brace &&
7320b57cec5SDimitry Andric                  Parent->isOneOf(tok::l_brace, tok::comma)) {
7335ffd83dbSDimitry Andric         Left->setType(TT_JsComputedPropertyName);
7340fca6ea1SDimitry Andric       } else if (IsCpp && Contexts.back().ContextKind == tok::l_brace &&
7350b57cec5SDimitry Andric                  Parent && Parent->isOneOf(tok::l_brace, tok::comma)) {
7365ffd83dbSDimitry Andric         Left->setType(TT_DesignatedInitializerLSquare);
7375ffd83dbSDimitry Andric       } else if (IsCSharpAttributeSpecifier) {
7385ffd83dbSDimitry Andric         Left->setType(TT_AttributeSquare);
7390b57cec5SDimitry Andric       } else if (CurrentToken->is(tok::r_square) && Parent &&
7400b57cec5SDimitry Andric                  Parent->is(TT_TemplateCloser)) {
7415ffd83dbSDimitry Andric         Left->setType(TT_ArraySubscriptLSquare);
7425f757f3fSDimitry Andric       } else if (Style.isProto()) {
7430b57cec5SDimitry Andric         // Square braces in LK_Proto can either be message field attributes:
7440b57cec5SDimitry Andric         //
7450b57cec5SDimitry Andric         // optional Aaa aaa = 1 [
7460b57cec5SDimitry Andric         //   (aaa) = aaa
7470b57cec5SDimitry Andric         // ];
7480b57cec5SDimitry Andric         //
7490b57cec5SDimitry Andric         // extensions 123 [
7500b57cec5SDimitry Andric         //   (aaa) = aaa
7510b57cec5SDimitry Andric         // ];
7520b57cec5SDimitry Andric         //
7530b57cec5SDimitry Andric         // or text proto extensions (in options):
7540b57cec5SDimitry Andric         //
7550b57cec5SDimitry Andric         // option (Aaa.options) = {
7560b57cec5SDimitry Andric         //   [type.type/type] {
7570b57cec5SDimitry Andric         //     key: value
7580b57cec5SDimitry Andric         //   }
7590b57cec5SDimitry Andric         // }
7600b57cec5SDimitry Andric         //
7610b57cec5SDimitry Andric         // or repeated fields (in options):
7620b57cec5SDimitry Andric         //
7630b57cec5SDimitry Andric         // option (Aaa.options) = {
7640b57cec5SDimitry Andric         //   keys: [ 1, 2, 3 ]
7650b57cec5SDimitry Andric         // }
7660b57cec5SDimitry Andric         //
7670b57cec5SDimitry Andric         // In the first and the third case we want to spread the contents inside
7680b57cec5SDimitry Andric         // the square braces; in the second we want to keep them inline.
7695ffd83dbSDimitry Andric         Left->setType(TT_ArrayInitializerLSquare);
7700b57cec5SDimitry Andric         if (!Left->endsSequence(tok::l_square, tok::numeric_constant,
7710b57cec5SDimitry Andric                                 tok::equal) &&
7720b57cec5SDimitry Andric             !Left->endsSequence(tok::l_square, tok::numeric_constant,
7730b57cec5SDimitry Andric                                 tok::identifier) &&
7740b57cec5SDimitry Andric             !Left->endsSequence(tok::l_square, tok::colon, TT_SelectorName)) {
7755ffd83dbSDimitry Andric           Left->setType(TT_ProtoExtensionLSquare);
7760b57cec5SDimitry Andric           BindingIncrease = 10;
7770b57cec5SDimitry Andric         }
7780b57cec5SDimitry Andric       } else if (!CppArrayTemplates && Parent &&
7790b57cec5SDimitry Andric                  Parent->isOneOf(TT_BinaryOperator, TT_TemplateCloser, tok::at,
7800b57cec5SDimitry Andric                                  tok::comma, tok::l_paren, tok::l_square,
7810b57cec5SDimitry Andric                                  tok::question, tok::colon, tok::kw_return,
7820b57cec5SDimitry Andric                                  // Should only be relevant to JavaScript:
7830b57cec5SDimitry Andric                                  tok::kw_default)) {
7845ffd83dbSDimitry Andric         Left->setType(TT_ArrayInitializerLSquare);
7850b57cec5SDimitry Andric       } else {
7860b57cec5SDimitry Andric         BindingIncrease = 10;
7875ffd83dbSDimitry Andric         Left->setType(TT_ArraySubscriptLSquare);
7880b57cec5SDimitry Andric       }
7890b57cec5SDimitry Andric     }
7900b57cec5SDimitry Andric 
7910b57cec5SDimitry Andric     ScopedContextCreator ContextCreator(*this, tok::l_square, BindingIncrease);
7920b57cec5SDimitry Andric     Contexts.back().IsExpression = true;
7930eae32dcSDimitry Andric     if (Style.isJavaScript() && Parent && Parent->is(TT_JsTypeColon))
7940b57cec5SDimitry Andric       Contexts.back().IsExpression = false;
7950b57cec5SDimitry Andric 
7960b57cec5SDimitry Andric     Contexts.back().ColonIsObjCMethodExpr = StartsObjCMethodExpr;
7970b57cec5SDimitry Andric     Contexts.back().InCpp11AttributeSpecifier = IsCpp11AttributeSpecifier;
7985ffd83dbSDimitry Andric     Contexts.back().InCSharpAttributeSpecifier = IsCSharpAttributeSpecifier;
7990b57cec5SDimitry Andric 
8000b57cec5SDimitry Andric     while (CurrentToken) {
8010b57cec5SDimitry Andric       if (CurrentToken->is(tok::r_square)) {
802bdd1243dSDimitry Andric         if (IsCpp11AttributeSpecifier) {
8035ffd83dbSDimitry Andric           CurrentToken->setType(TT_AttributeSquare);
804bdd1243dSDimitry Andric           if (!IsInnerSquare)
805bdd1243dSDimitry Andric             CurrentToken->EndsCppAttributeGroup = true;
806bdd1243dSDimitry Andric         }
80781ad6265SDimitry Andric         if (IsCSharpAttributeSpecifier) {
8085ffd83dbSDimitry Andric           CurrentToken->setType(TT_AttributeSquare);
80981ad6265SDimitry Andric         } else if (((CurrentToken->Next &&
8100b57cec5SDimitry Andric                      CurrentToken->Next->is(tok::l_paren)) ||
8110b57cec5SDimitry Andric                     (CurrentToken->Previous &&
8120b57cec5SDimitry Andric                      CurrentToken->Previous->Previous == Left)) &&
8130b57cec5SDimitry Andric                    Left->is(TT_ObjCMethodExpr)) {
8140b57cec5SDimitry Andric           // An ObjC method call is rarely followed by an open parenthesis. It
8150b57cec5SDimitry Andric           // also can't be composed of just one token, unless it's a macro that
8160b57cec5SDimitry Andric           // will be expanded to more tokens.
8170b57cec5SDimitry Andric           // FIXME: Do we incorrectly label ":" with this?
8180b57cec5SDimitry Andric           StartsObjCMethodExpr = false;
8195ffd83dbSDimitry Andric           Left->setType(TT_Unknown);
8200b57cec5SDimitry Andric         }
8210b57cec5SDimitry Andric         if (StartsObjCMethodExpr && CurrentToken->Previous != Left) {
8225ffd83dbSDimitry Andric           CurrentToken->setType(TT_ObjCMethodExpr);
8230b57cec5SDimitry Andric           // If we haven't seen a colon yet, make sure the last identifier
8240b57cec5SDimitry Andric           // before the r_square is tagged as a selector name component.
8250b57cec5SDimitry Andric           if (!ColonFound && CurrentToken->Previous &&
8260b57cec5SDimitry Andric               CurrentToken->Previous->is(TT_Unknown) &&
82781ad6265SDimitry Andric               canBeObjCSelectorComponent(*CurrentToken->Previous)) {
8285ffd83dbSDimitry Andric             CurrentToken->Previous->setType(TT_SelectorName);
82981ad6265SDimitry Andric           }
8300b57cec5SDimitry Andric           // determineStarAmpUsage() thinks that '*' '[' is allocating an
8310b57cec5SDimitry Andric           // array of pointers, but if '[' starts a selector then '*' is a
8320b57cec5SDimitry Andric           // binary operator.
8330b57cec5SDimitry Andric           if (Parent && Parent->is(TT_PointerOrReference))
83481ad6265SDimitry Andric             Parent->overwriteFixedType(TT_BinaryOperator);
8350b57cec5SDimitry Andric         }
8360b57cec5SDimitry Andric         // An arrow after an ObjC method expression is not a lambda arrow.
8370fca6ea1SDimitry Andric         if (CurrentToken->is(TT_ObjCMethodExpr) && CurrentToken->Next &&
8386c4b055cSDimitry Andric             CurrentToken->Next->is(TT_LambdaArrow)) {
83981ad6265SDimitry Andric           CurrentToken->Next->overwriteFixedType(TT_Unknown);
84081ad6265SDimitry Andric         }
8410b57cec5SDimitry Andric         Left->MatchingParen = CurrentToken;
8420b57cec5SDimitry Andric         CurrentToken->MatchingParen = Left;
8430b57cec5SDimitry Andric         // FirstObjCSelectorName is set when a colon is found. This does
8440b57cec5SDimitry Andric         // not work, however, when the method has no parameters.
8450b57cec5SDimitry Andric         // Here, we set FirstObjCSelectorName when the end of the method call is
8460b57cec5SDimitry Andric         // reached, in case it was not set already.
8470b57cec5SDimitry Andric         if (!Contexts.back().FirstObjCSelectorName) {
8480b57cec5SDimitry Andric           FormatToken *Previous = CurrentToken->getPreviousNonComment();
8490b57cec5SDimitry Andric           if (Previous && Previous->is(TT_SelectorName)) {
8500b57cec5SDimitry Andric             Previous->ObjCSelectorNameParts = 1;
8510b57cec5SDimitry Andric             Contexts.back().FirstObjCSelectorName = Previous;
8520b57cec5SDimitry Andric           }
8530b57cec5SDimitry Andric         } else {
8540b57cec5SDimitry Andric           Left->ParameterCount =
8550b57cec5SDimitry Andric               Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts;
8560b57cec5SDimitry Andric         }
8570b57cec5SDimitry Andric         if (Contexts.back().FirstObjCSelectorName) {
8580b57cec5SDimitry Andric           Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
8590b57cec5SDimitry Andric               Contexts.back().LongestObjCSelectorName;
8600b57cec5SDimitry Andric           if (Left->BlockParameterCount > 1)
8610b57cec5SDimitry Andric             Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 0;
8620b57cec5SDimitry Andric         }
8630fca6ea1SDimitry Andric         if (Style.isTableGen() && Left->is(TT_TableGenListOpener))
8640fca6ea1SDimitry Andric           CurrentToken->setType(TT_TableGenListCloser);
8650b57cec5SDimitry Andric         next();
8660b57cec5SDimitry Andric         return true;
8670b57cec5SDimitry Andric       }
8680b57cec5SDimitry Andric       if (CurrentToken->isOneOf(tok::r_paren, tok::r_brace))
8690b57cec5SDimitry Andric         return false;
8700b57cec5SDimitry Andric       if (CurrentToken->is(tok::colon)) {
8710b57cec5SDimitry Andric         if (IsCpp11AttributeSpecifier &&
8720b57cec5SDimitry Andric             CurrentToken->endsSequence(tok::colon, tok::identifier,
8730b57cec5SDimitry Andric                                        tok::kw_using)) {
8740b57cec5SDimitry Andric           // Remember that this is a [[using ns: foo]] C++ attribute, so we
8750b57cec5SDimitry Andric           // don't add a space before the colon (unlike other colons).
8765ffd83dbSDimitry Andric           CurrentToken->setType(TT_AttributeColon);
877bdd1243dSDimitry Andric         } else if (!Style.isVerilog() && !Line.InPragmaDirective &&
878bdd1243dSDimitry Andric                    Left->isOneOf(TT_ArraySubscriptLSquare,
8790b57cec5SDimitry Andric                                  TT_DesignatedInitializerLSquare)) {
8805ffd83dbSDimitry Andric           Left->setType(TT_ObjCMethodExpr);
8810b57cec5SDimitry Andric           StartsObjCMethodExpr = true;
8820b57cec5SDimitry Andric           Contexts.back().ColonIsObjCMethodExpr = true;
88381ad6265SDimitry Andric           if (Parent && Parent->is(tok::r_paren)) {
8840b57cec5SDimitry Andric             // FIXME(bug 36976): ObjC return types shouldn't use TT_CastRParen.
8855ffd83dbSDimitry Andric             Parent->setType(TT_CastRParen);
8860b57cec5SDimitry Andric           }
88781ad6265SDimitry Andric         }
8880b57cec5SDimitry Andric         ColonFound = true;
8890b57cec5SDimitry Andric       }
8900b57cec5SDimitry Andric       if (CurrentToken->is(tok::comma) && Left->is(TT_ObjCMethodExpr) &&
89181ad6265SDimitry Andric           !ColonFound) {
8925ffd83dbSDimitry Andric         Left->setType(TT_ArrayInitializerLSquare);
89381ad6265SDimitry Andric       }
8940b57cec5SDimitry Andric       FormatToken *Tok = CurrentToken;
8950fca6ea1SDimitry Andric       if (Style.isTableGen()) {
8960fca6ea1SDimitry Andric         if (CurrentToken->isOneOf(tok::comma, tok::minus, tok::ellipsis)) {
8970fca6ea1SDimitry Andric           // '-' and '...' appears as a separator in slice.
8980fca6ea1SDimitry Andric           next();
8990fca6ea1SDimitry Andric         } else {
9000fca6ea1SDimitry Andric           // In TableGen there must be a list of Values in square brackets.
9010fca6ea1SDimitry Andric           // It must be ValueList or SliceElements.
9020fca6ea1SDimitry Andric           if (!parseTableGenValue())
9030fca6ea1SDimitry Andric             return false;
9040fca6ea1SDimitry Andric         }
9050fca6ea1SDimitry Andric         updateParameterCount(Left, Tok);
9060fca6ea1SDimitry Andric         continue;
9070fca6ea1SDimitry Andric       }
9080b57cec5SDimitry Andric       if (!consumeToken())
9090b57cec5SDimitry Andric         return false;
9100b57cec5SDimitry Andric       updateParameterCount(Left, Tok);
9110b57cec5SDimitry Andric     }
9120b57cec5SDimitry Andric     return false;
9130b57cec5SDimitry Andric   }
9140b57cec5SDimitry Andric 
9150fca6ea1SDimitry Andric   void skipToNextNonComment() {
9160fca6ea1SDimitry Andric     next();
9170fca6ea1SDimitry Andric     while (CurrentToken && CurrentToken->is(tok::comment))
9180fca6ea1SDimitry Andric       next();
9190fca6ea1SDimitry Andric   }
9200fca6ea1SDimitry Andric 
9210fca6ea1SDimitry Andric   // Simplified parser for TableGen Value. Returns true on success.
9220fca6ea1SDimitry Andric   // It consists of SimpleValues, SimpleValues with Suffixes, and Value followed
9230fca6ea1SDimitry Andric   // by '#', paste operator.
9240fca6ea1SDimitry Andric   // There also exists the case the Value is parsed as NameValue.
9250fca6ea1SDimitry Andric   // In this case, the Value ends if '{' is found.
9260fca6ea1SDimitry Andric   bool parseTableGenValue(bool ParseNameMode = false) {
9270fca6ea1SDimitry Andric     if (!CurrentToken)
9280fca6ea1SDimitry Andric       return false;
9290fca6ea1SDimitry Andric     while (CurrentToken->is(tok::comment))
9300fca6ea1SDimitry Andric       next();
9310fca6ea1SDimitry Andric     if (!parseTableGenSimpleValue())
9320fca6ea1SDimitry Andric       return false;
9330fca6ea1SDimitry Andric     if (!CurrentToken)
9340fca6ea1SDimitry Andric       return true;
9350fca6ea1SDimitry Andric     // Value "#" [Value]
9360fca6ea1SDimitry Andric     if (CurrentToken->is(tok::hash)) {
9370fca6ea1SDimitry Andric       if (CurrentToken->Next &&
9380fca6ea1SDimitry Andric           CurrentToken->Next->isOneOf(tok::colon, tok::semi, tok::l_brace)) {
9390fca6ea1SDimitry Andric         // Trailing paste operator.
9400fca6ea1SDimitry Andric         // These are only the allowed cases in TGParser::ParseValue().
9410fca6ea1SDimitry Andric         CurrentToken->setType(TT_TableGenTrailingPasteOperator);
9420fca6ea1SDimitry Andric         next();
9430fca6ea1SDimitry Andric         return true;
9440fca6ea1SDimitry Andric       }
9450fca6ea1SDimitry Andric       FormatToken *HashTok = CurrentToken;
9460fca6ea1SDimitry Andric       skipToNextNonComment();
9470fca6ea1SDimitry Andric       HashTok->setType(TT_Unknown);
9480fca6ea1SDimitry Andric       if (!parseTableGenValue(ParseNameMode))
9490fca6ea1SDimitry Andric         return false;
9500fca6ea1SDimitry Andric     }
9510fca6ea1SDimitry Andric     // In name mode, '{' is regarded as the end of the value.
9520fca6ea1SDimitry Andric     // See TGParser::ParseValue in TGParser.cpp
9530fca6ea1SDimitry Andric     if (ParseNameMode && CurrentToken->is(tok::l_brace))
9540fca6ea1SDimitry Andric       return true;
9550fca6ea1SDimitry Andric     // These tokens indicates this is a value with suffixes.
9560fca6ea1SDimitry Andric     if (CurrentToken->isOneOf(tok::l_brace, tok::l_square, tok::period)) {
9570fca6ea1SDimitry Andric       CurrentToken->setType(TT_TableGenValueSuffix);
9580fca6ea1SDimitry Andric       FormatToken *Suffix = CurrentToken;
9590fca6ea1SDimitry Andric       skipToNextNonComment();
9600fca6ea1SDimitry Andric       if (Suffix->is(tok::l_square))
9610fca6ea1SDimitry Andric         return parseSquare();
9620fca6ea1SDimitry Andric       if (Suffix->is(tok::l_brace)) {
9630fca6ea1SDimitry Andric         Scopes.push_back(getScopeType(*Suffix));
9640fca6ea1SDimitry Andric         return parseBrace();
9650fca6ea1SDimitry Andric       }
9660fca6ea1SDimitry Andric     }
9670fca6ea1SDimitry Andric     return true;
9680fca6ea1SDimitry Andric   }
9690fca6ea1SDimitry Andric 
9700fca6ea1SDimitry Andric   // TokVarName    ::=  "$" ualpha (ualpha |  "0"..."9")*
9710fca6ea1SDimitry Andric   // Appears as a part of DagArg.
9720fca6ea1SDimitry Andric   // This does not change the current token on fail.
9730fca6ea1SDimitry Andric   bool tryToParseTableGenTokVar() {
9740fca6ea1SDimitry Andric     if (!CurrentToken)
9750fca6ea1SDimitry Andric       return false;
9760fca6ea1SDimitry Andric     if (CurrentToken->is(tok::identifier) &&
9770fca6ea1SDimitry Andric         CurrentToken->TokenText.front() == '$') {
9780fca6ea1SDimitry Andric       skipToNextNonComment();
9790fca6ea1SDimitry Andric       return true;
9800fca6ea1SDimitry Andric     }
9810fca6ea1SDimitry Andric     return false;
9820fca6ea1SDimitry Andric   }
9830fca6ea1SDimitry Andric 
9840fca6ea1SDimitry Andric   // DagArg       ::=  Value [":" TokVarName] | TokVarName
9850fca6ea1SDimitry Andric   // Appears as a part of SimpleValue6.
9860fca6ea1SDimitry Andric   bool parseTableGenDAGArg(bool AlignColon = false) {
9870fca6ea1SDimitry Andric     if (tryToParseTableGenTokVar())
9880fca6ea1SDimitry Andric       return true;
9890fca6ea1SDimitry Andric     if (parseTableGenValue()) {
9900fca6ea1SDimitry Andric       if (CurrentToken && CurrentToken->is(tok::colon)) {
9910fca6ea1SDimitry Andric         if (AlignColon)
9920fca6ea1SDimitry Andric           CurrentToken->setType(TT_TableGenDAGArgListColonToAlign);
9930fca6ea1SDimitry Andric         else
9940fca6ea1SDimitry Andric           CurrentToken->setType(TT_TableGenDAGArgListColon);
9950fca6ea1SDimitry Andric         skipToNextNonComment();
9960fca6ea1SDimitry Andric         return tryToParseTableGenTokVar();
9970fca6ea1SDimitry Andric       }
9980fca6ea1SDimitry Andric       return true;
9990fca6ea1SDimitry Andric     }
10000fca6ea1SDimitry Andric     return false;
10010fca6ea1SDimitry Andric   }
10020fca6ea1SDimitry Andric 
10030fca6ea1SDimitry Andric   // Judge if the token is a operator ID to insert line break in DAGArg.
10040fca6ea1SDimitry Andric   // That is, TableGenBreakingDAGArgOperators is empty (by the definition of the
10050fca6ea1SDimitry Andric   // option) or the token is in the list.
10060fca6ea1SDimitry Andric   bool isTableGenDAGArgBreakingOperator(const FormatToken &Tok) {
10070fca6ea1SDimitry Andric     auto &Opes = Style.TableGenBreakingDAGArgOperators;
10080fca6ea1SDimitry Andric     // If the list is empty, all operators are breaking operators.
10090fca6ea1SDimitry Andric     if (Opes.empty())
10100fca6ea1SDimitry Andric       return true;
10110fca6ea1SDimitry Andric     // Otherwise, the operator is limited to normal identifiers.
10120fca6ea1SDimitry Andric     if (Tok.isNot(tok::identifier) ||
10130fca6ea1SDimitry Andric         Tok.isOneOf(TT_TableGenBangOperator, TT_TableGenCondOperator)) {
10140fca6ea1SDimitry Andric       return false;
10150fca6ea1SDimitry Andric     }
10160fca6ea1SDimitry Andric     // The case next is colon, it is not a operator of identifier.
10170fca6ea1SDimitry Andric     if (!Tok.Next || Tok.Next->is(tok::colon))
10180fca6ea1SDimitry Andric       return false;
10190fca6ea1SDimitry Andric     return std::find(Opes.begin(), Opes.end(), Tok.TokenText.str()) !=
10200fca6ea1SDimitry Andric            Opes.end();
10210fca6ea1SDimitry Andric   }
10220fca6ea1SDimitry Andric 
10230fca6ea1SDimitry Andric   // SimpleValue6 ::=  "(" DagArg [DagArgList] ")"
10240fca6ea1SDimitry Andric   // This parses SimpleValue 6's inside part of "(" ")"
10250fca6ea1SDimitry Andric   bool parseTableGenDAGArgAndList(FormatToken *Opener) {
10260fca6ea1SDimitry Andric     FormatToken *FirstTok = CurrentToken;
10270fca6ea1SDimitry Andric     if (!parseTableGenDAGArg())
10280fca6ea1SDimitry Andric       return false;
10290fca6ea1SDimitry Andric     bool BreakInside = false;
10300fca6ea1SDimitry Andric     if (Style.TableGenBreakInsideDAGArg != FormatStyle::DAS_DontBreak) {
10310fca6ea1SDimitry Andric       // Specialized detection for DAGArgOperator, that determines the way of
10320fca6ea1SDimitry Andric       // line break for this DAGArg elements.
10330fca6ea1SDimitry Andric       if (isTableGenDAGArgBreakingOperator(*FirstTok)) {
10340fca6ea1SDimitry Andric         // Special case for identifier DAGArg operator.
10350fca6ea1SDimitry Andric         BreakInside = true;
10360fca6ea1SDimitry Andric         Opener->setType(TT_TableGenDAGArgOpenerToBreak);
10370fca6ea1SDimitry Andric         if (FirstTok->isOneOf(TT_TableGenBangOperator,
10380fca6ea1SDimitry Andric                               TT_TableGenCondOperator)) {
10390fca6ea1SDimitry Andric           // Special case for bang/cond operators. Set the whole operator as
10400fca6ea1SDimitry Andric           // the DAGArg operator. Always break after it.
10410fca6ea1SDimitry Andric           CurrentToken->Previous->setType(TT_TableGenDAGArgOperatorToBreak);
10420fca6ea1SDimitry Andric         } else if (FirstTok->is(tok::identifier)) {
10430fca6ea1SDimitry Andric           if (Style.TableGenBreakInsideDAGArg == FormatStyle::DAS_BreakAll)
10440fca6ea1SDimitry Andric             FirstTok->setType(TT_TableGenDAGArgOperatorToBreak);
10450fca6ea1SDimitry Andric           else
10460fca6ea1SDimitry Andric             FirstTok->setType(TT_TableGenDAGArgOperatorID);
10470fca6ea1SDimitry Andric         }
10480fca6ea1SDimitry Andric       }
10490fca6ea1SDimitry Andric     }
10500fca6ea1SDimitry Andric     // Parse the [DagArgList] part
10510fca6ea1SDimitry Andric     bool FirstDAGArgListElm = true;
10520fca6ea1SDimitry Andric     while (CurrentToken) {
10530fca6ea1SDimitry Andric       if (!FirstDAGArgListElm && CurrentToken->is(tok::comma)) {
10540fca6ea1SDimitry Andric         CurrentToken->setType(BreakInside ? TT_TableGenDAGArgListCommaToBreak
10550fca6ea1SDimitry Andric                                           : TT_TableGenDAGArgListComma);
10560fca6ea1SDimitry Andric         skipToNextNonComment();
10570fca6ea1SDimitry Andric       }
10580fca6ea1SDimitry Andric       if (CurrentToken && CurrentToken->is(tok::r_paren)) {
10590fca6ea1SDimitry Andric         CurrentToken->setType(TT_TableGenDAGArgCloser);
10600fca6ea1SDimitry Andric         Opener->MatchingParen = CurrentToken;
10610fca6ea1SDimitry Andric         CurrentToken->MatchingParen = Opener;
10620fca6ea1SDimitry Andric         skipToNextNonComment();
10630fca6ea1SDimitry Andric         return true;
10640fca6ea1SDimitry Andric       }
10650fca6ea1SDimitry Andric       if (!parseTableGenDAGArg(
10660fca6ea1SDimitry Andric               BreakInside &&
10670fca6ea1SDimitry Andric               Style.AlignConsecutiveTableGenBreakingDAGArgColons.Enabled)) {
10680fca6ea1SDimitry Andric         return false;
10690fca6ea1SDimitry Andric       }
10700fca6ea1SDimitry Andric       FirstDAGArgListElm = false;
10710fca6ea1SDimitry Andric     }
10720fca6ea1SDimitry Andric     return false;
10730fca6ea1SDimitry Andric   }
10740fca6ea1SDimitry Andric 
10750fca6ea1SDimitry Andric   bool parseTableGenSimpleValue() {
10760fca6ea1SDimitry Andric     assert(Style.isTableGen());
10770fca6ea1SDimitry Andric     if (!CurrentToken)
10780fca6ea1SDimitry Andric       return false;
10790fca6ea1SDimitry Andric     FormatToken *Tok = CurrentToken;
10800fca6ea1SDimitry Andric     skipToNextNonComment();
10810fca6ea1SDimitry Andric     // SimpleValue 1, 2, 3: Literals
10820fca6ea1SDimitry Andric     if (Tok->isOneOf(tok::numeric_constant, tok::string_literal,
10830fca6ea1SDimitry Andric                      TT_TableGenMultiLineString, tok::kw_true, tok::kw_false,
10840fca6ea1SDimitry Andric                      tok::question, tok::kw_int)) {
10850fca6ea1SDimitry Andric       return true;
10860fca6ea1SDimitry Andric     }
10870fca6ea1SDimitry Andric     // SimpleValue 4: ValueList, Type
10880fca6ea1SDimitry Andric     if (Tok->is(tok::l_brace)) {
10890fca6ea1SDimitry Andric       Scopes.push_back(getScopeType(*Tok));
10900fca6ea1SDimitry Andric       return parseBrace();
10910fca6ea1SDimitry Andric     }
10920fca6ea1SDimitry Andric     // SimpleValue 5: List initializer
10930fca6ea1SDimitry Andric     if (Tok->is(tok::l_square)) {
10940fca6ea1SDimitry Andric       Tok->setType(TT_TableGenListOpener);
10950fca6ea1SDimitry Andric       if (!parseSquare())
10960fca6ea1SDimitry Andric         return false;
10970fca6ea1SDimitry Andric       if (Tok->is(tok::less)) {
10980fca6ea1SDimitry Andric         CurrentToken->setType(TT_TemplateOpener);
10990fca6ea1SDimitry Andric         return parseAngle();
11000fca6ea1SDimitry Andric       }
11010fca6ea1SDimitry Andric       return true;
11020fca6ea1SDimitry Andric     }
11030fca6ea1SDimitry Andric     // SimpleValue 6: DAGArg [DAGArgList]
11040fca6ea1SDimitry Andric     // SimpleValue6 ::=  "(" DagArg [DagArgList] ")"
11050fca6ea1SDimitry Andric     if (Tok->is(tok::l_paren)) {
11060fca6ea1SDimitry Andric       Tok->setType(TT_TableGenDAGArgOpener);
11070fca6ea1SDimitry Andric       return parseTableGenDAGArgAndList(Tok);
11080fca6ea1SDimitry Andric     }
11090fca6ea1SDimitry Andric     // SimpleValue 9: Bang operator
11100fca6ea1SDimitry Andric     if (Tok->is(TT_TableGenBangOperator)) {
11110fca6ea1SDimitry Andric       if (CurrentToken && CurrentToken->is(tok::less)) {
11120fca6ea1SDimitry Andric         CurrentToken->setType(TT_TemplateOpener);
11130fca6ea1SDimitry Andric         skipToNextNonComment();
11140fca6ea1SDimitry Andric         if (!parseAngle())
11150fca6ea1SDimitry Andric           return false;
11160fca6ea1SDimitry Andric       }
11170fca6ea1SDimitry Andric       if (!CurrentToken || CurrentToken->isNot(tok::l_paren))
11180fca6ea1SDimitry Andric         return false;
11190fca6ea1SDimitry Andric       skipToNextNonComment();
11200fca6ea1SDimitry Andric       // FIXME: Hack using inheritance to child context
11210fca6ea1SDimitry Andric       Contexts.back().IsTableGenBangOpe = true;
11220fca6ea1SDimitry Andric       bool Result = parseParens();
11230fca6ea1SDimitry Andric       Contexts.back().IsTableGenBangOpe = false;
11240fca6ea1SDimitry Andric       return Result;
11250fca6ea1SDimitry Andric     }
11260fca6ea1SDimitry Andric     // SimpleValue 9: Cond operator
11270fca6ea1SDimitry Andric     if (Tok->is(TT_TableGenCondOperator)) {
11280fca6ea1SDimitry Andric       Tok = CurrentToken;
11290fca6ea1SDimitry Andric       skipToNextNonComment();
11300fca6ea1SDimitry Andric       if (!Tok || Tok->isNot(tok::l_paren))
11310fca6ea1SDimitry Andric         return false;
11320fca6ea1SDimitry Andric       bool Result = parseParens();
11330fca6ea1SDimitry Andric       return Result;
11340fca6ea1SDimitry Andric     }
11350fca6ea1SDimitry Andric     // We have to check identifier at the last because the kind of bang/cond
11360fca6ea1SDimitry Andric     // operators are also identifier.
11370fca6ea1SDimitry Andric     // SimpleValue 7: Identifiers
11380fca6ea1SDimitry Andric     if (Tok->is(tok::identifier)) {
11390fca6ea1SDimitry Andric       // SimpleValue 8: Anonymous record
11400fca6ea1SDimitry Andric       if (CurrentToken && CurrentToken->is(tok::less)) {
11410fca6ea1SDimitry Andric         CurrentToken->setType(TT_TemplateOpener);
11420fca6ea1SDimitry Andric         skipToNextNonComment();
11430fca6ea1SDimitry Andric         return parseAngle();
11440fca6ea1SDimitry Andric       }
11450fca6ea1SDimitry Andric       return true;
11460fca6ea1SDimitry Andric     }
11470fca6ea1SDimitry Andric 
11480fca6ea1SDimitry Andric     return false;
11490fca6ea1SDimitry Andric   }
11500fca6ea1SDimitry Andric 
1151fe6060f1SDimitry Andric   bool couldBeInStructArrayInitializer() const {
1152fe6060f1SDimitry Andric     if (Contexts.size() < 2)
1153fe6060f1SDimitry Andric       return false;
1154fe6060f1SDimitry Andric     // We want to back up no more then 2 context levels i.e.
1155fe6060f1SDimitry Andric     // . { { <-
1156fe6060f1SDimitry Andric     const auto End = std::next(Contexts.rbegin(), 2);
1157fe6060f1SDimitry Andric     auto Last = Contexts.rbegin();
1158fe6060f1SDimitry Andric     unsigned Depth = 0;
115981ad6265SDimitry Andric     for (; Last != End; ++Last)
1160fe6060f1SDimitry Andric       if (Last->ContextKind == tok::l_brace)
1161fe6060f1SDimitry Andric         ++Depth;
1162fe6060f1SDimitry Andric     return Depth == 2 && Last->ContextKind != tok::l_brace;
1163fe6060f1SDimitry Andric   }
1164fe6060f1SDimitry Andric 
11650b57cec5SDimitry Andric   bool parseBrace() {
116681ad6265SDimitry Andric     if (!CurrentToken)
116781ad6265SDimitry Andric       return true;
116881ad6265SDimitry Andric 
116981ad6265SDimitry Andric     assert(CurrentToken->Previous);
117081ad6265SDimitry Andric     FormatToken &OpeningBrace = *CurrentToken->Previous;
117181ad6265SDimitry Andric     assert(OpeningBrace.is(tok::l_brace));
117281ad6265SDimitry Andric     OpeningBrace.ParentBracket = Contexts.back().ContextKind;
11730b57cec5SDimitry Andric 
11740b57cec5SDimitry Andric     if (Contexts.back().CaretFound)
117581ad6265SDimitry Andric       OpeningBrace.overwriteFixedType(TT_ObjCBlockLBrace);
11760b57cec5SDimitry Andric     Contexts.back().CaretFound = false;
11770b57cec5SDimitry Andric 
11780b57cec5SDimitry Andric     ScopedContextCreator ContextCreator(*this, tok::l_brace, 1);
11790b57cec5SDimitry Andric     Contexts.back().ColonIsDictLiteral = true;
118081ad6265SDimitry Andric     if (OpeningBrace.is(BK_BracedInit))
11810b57cec5SDimitry Andric       Contexts.back().IsExpression = true;
118281ad6265SDimitry Andric     if (Style.isJavaScript() && OpeningBrace.Previous &&
118381ad6265SDimitry Andric         OpeningBrace.Previous->is(TT_JsTypeColon)) {
11840b57cec5SDimitry Andric       Contexts.back().IsExpression = false;
118581ad6265SDimitry Andric     }
11865f757f3fSDimitry Andric     if (Style.isVerilog() &&
11875f757f3fSDimitry Andric         (!OpeningBrace.getPreviousNonComment() ||
11885f757f3fSDimitry Andric          OpeningBrace.getPreviousNonComment()->isNot(Keywords.kw_apostrophe))) {
11895f757f3fSDimitry Andric       Contexts.back().VerilogMayBeConcatenation = true;
11905f757f3fSDimitry Andric     }
11910fca6ea1SDimitry Andric     if (Style.isTableGen())
11920fca6ea1SDimitry Andric       Contexts.back().ColonIsDictLiteral = false;
11930b57cec5SDimitry Andric 
1194fe6060f1SDimitry Andric     unsigned CommaCount = 0;
11950b57cec5SDimitry Andric     while (CurrentToken) {
11960b57cec5SDimitry Andric       if (CurrentToken->is(tok::r_brace)) {
119706c3fb27SDimitry Andric         assert(!Scopes.empty());
119806c3fb27SDimitry Andric         assert(Scopes.back() == getScopeType(OpeningBrace));
119906c3fb27SDimitry Andric         Scopes.pop_back();
120081ad6265SDimitry Andric         assert(OpeningBrace.Optional == CurrentToken->Optional);
120181ad6265SDimitry Andric         OpeningBrace.MatchingParen = CurrentToken;
120281ad6265SDimitry Andric         CurrentToken->MatchingParen = &OpeningBrace;
1203fe6060f1SDimitry Andric         if (Style.AlignArrayOfStructures != FormatStyle::AIAS_None) {
120481ad6265SDimitry Andric           if (OpeningBrace.ParentBracket == tok::l_brace &&
1205fe6060f1SDimitry Andric               couldBeInStructArrayInitializer() && CommaCount > 0) {
120681ad6265SDimitry Andric             Contexts.back().ContextType = Context::StructArrayInitializer;
1207fe6060f1SDimitry Andric           }
1208fe6060f1SDimitry Andric         }
12090b57cec5SDimitry Andric         next();
12100b57cec5SDimitry Andric         return true;
12110b57cec5SDimitry Andric       }
12120b57cec5SDimitry Andric       if (CurrentToken->isOneOf(tok::r_paren, tok::r_square))
12130b57cec5SDimitry Andric         return false;
121481ad6265SDimitry Andric       updateParameterCount(&OpeningBrace, CurrentToken);
12150b57cec5SDimitry Andric       if (CurrentToken->isOneOf(tok::colon, tok::l_brace, tok::less)) {
12160b57cec5SDimitry Andric         FormatToken *Previous = CurrentToken->getPreviousNonComment();
12170b57cec5SDimitry Andric         if (Previous->is(TT_JsTypeOptionalQuestion))
12180b57cec5SDimitry Andric           Previous = Previous->getPreviousNonComment();
12190fca6ea1SDimitry Andric         if ((CurrentToken->is(tok::colon) && !Style.isTableGen() &&
12200fca6ea1SDimitry Andric              (!Contexts.back().ColonIsDictLiteral || !IsCpp)) ||
12215f757f3fSDimitry Andric             Style.isProto()) {
122281ad6265SDimitry Andric           OpeningBrace.setType(TT_DictLiteral);
12230b57cec5SDimitry Andric           if (Previous->Tok.getIdentifierInfo() ||
122481ad6265SDimitry Andric               Previous->is(tok::string_literal)) {
12255ffd83dbSDimitry Andric             Previous->setType(TT_SelectorName);
12260b57cec5SDimitry Andric           }
122781ad6265SDimitry Andric         }
12280fca6ea1SDimitry Andric         if (CurrentToken->is(tok::colon) && OpeningBrace.is(TT_Unknown) &&
12290fca6ea1SDimitry Andric             !Style.isTableGen()) {
123081ad6265SDimitry Andric           OpeningBrace.setType(TT_DictLiteral);
12310fca6ea1SDimitry Andric         } else if (Style.isJavaScript()) {
123281ad6265SDimitry Andric           OpeningBrace.overwriteFixedType(TT_DictLiteral);
12330b57cec5SDimitry Andric         }
12340fca6ea1SDimitry Andric       }
1235fe6060f1SDimitry Andric       if (CurrentToken->is(tok::comma)) {
12360eae32dcSDimitry Andric         if (Style.isJavaScript())
123781ad6265SDimitry Andric           OpeningBrace.overwriteFixedType(TT_DictLiteral);
1238fe6060f1SDimitry Andric         ++CommaCount;
1239fe6060f1SDimitry Andric       }
12400b57cec5SDimitry Andric       if (!consumeToken())
12410b57cec5SDimitry Andric         return false;
12420b57cec5SDimitry Andric     }
12430b57cec5SDimitry Andric     return true;
12440b57cec5SDimitry Andric   }
12450b57cec5SDimitry Andric 
12460b57cec5SDimitry Andric   void updateParameterCount(FormatToken *Left, FormatToken *Current) {
12470b57cec5SDimitry Andric     // For ObjC methods, the number of parameters is calculated differently as
12480b57cec5SDimitry Andric     // method declarations have a different structure (the parameters are not
12490b57cec5SDimitry Andric     // inside a bracket scope).
1250e8d8bef9SDimitry Andric     if (Current->is(tok::l_brace) && Current->is(BK_Block))
12510b57cec5SDimitry Andric       ++Left->BlockParameterCount;
12520b57cec5SDimitry Andric     if (Current->is(tok::comma)) {
12530b57cec5SDimitry Andric       ++Left->ParameterCount;
12540b57cec5SDimitry Andric       if (!Left->Role)
12550b57cec5SDimitry Andric         Left->Role.reset(new CommaSeparatedList(Style));
12560b57cec5SDimitry Andric       Left->Role->CommaFound(Current);
12570b57cec5SDimitry Andric     } else if (Left->ParameterCount == 0 && Current->isNot(tok::comment)) {
12580b57cec5SDimitry Andric       Left->ParameterCount = 1;
12590b57cec5SDimitry Andric     }
12600b57cec5SDimitry Andric   }
12610b57cec5SDimitry Andric 
12620b57cec5SDimitry Andric   bool parseConditional() {
12630b57cec5SDimitry Andric     while (CurrentToken) {
12640b57cec5SDimitry Andric       if (CurrentToken->is(tok::colon)) {
12655ffd83dbSDimitry Andric         CurrentToken->setType(TT_ConditionalExpr);
12660b57cec5SDimitry Andric         next();
12670b57cec5SDimitry Andric         return true;
12680b57cec5SDimitry Andric       }
12690b57cec5SDimitry Andric       if (!consumeToken())
12700b57cec5SDimitry Andric         return false;
12710b57cec5SDimitry Andric     }
12720b57cec5SDimitry Andric     return false;
12730b57cec5SDimitry Andric   }
12740b57cec5SDimitry Andric 
12750b57cec5SDimitry Andric   bool parseTemplateDeclaration() {
12760fca6ea1SDimitry Andric     if (!CurrentToken || CurrentToken->isNot(tok::less))
12770fca6ea1SDimitry Andric       return false;
12780fca6ea1SDimitry Andric 
12795ffd83dbSDimitry Andric     CurrentToken->setType(TT_TemplateOpener);
12800b57cec5SDimitry Andric     next();
12810fca6ea1SDimitry Andric 
12820fca6ea1SDimitry Andric     TemplateDeclarationDepth++;
12830fca6ea1SDimitry Andric     const bool WellFormed = parseAngle();
12840fca6ea1SDimitry Andric     TemplateDeclarationDepth--;
12850fca6ea1SDimitry Andric     if (!WellFormed)
12860b57cec5SDimitry Andric       return false;
12870fca6ea1SDimitry Andric 
12880fca6ea1SDimitry Andric     if (CurrentToken && TemplateDeclarationDepth == 0)
12890b57cec5SDimitry Andric       CurrentToken->Previous->ClosesTemplateDeclaration = true;
12900fca6ea1SDimitry Andric 
12910b57cec5SDimitry Andric     return true;
12920b57cec5SDimitry Andric   }
12930b57cec5SDimitry Andric 
12940b57cec5SDimitry Andric   bool consumeToken() {
12950fca6ea1SDimitry Andric     if (IsCpp) {
12965f757f3fSDimitry Andric       const auto *Prev = CurrentToken->getPreviousNonComment();
12975f757f3fSDimitry Andric       if (Prev && Prev->is(tok::r_square) && Prev->is(TT_AttributeSquare) &&
12985f757f3fSDimitry Andric           CurrentToken->isOneOf(tok::kw_if, tok::kw_switch, tok::kw_case,
12995f757f3fSDimitry Andric                                 tok::kw_default, tok::kw_for, tok::kw_while) &&
13005f757f3fSDimitry Andric           mustBreakAfterAttributes(*CurrentToken, Style)) {
13015f757f3fSDimitry Andric         CurrentToken->MustBreakBefore = true;
13025f757f3fSDimitry Andric       }
13035f757f3fSDimitry Andric     }
13040b57cec5SDimitry Andric     FormatToken *Tok = CurrentToken;
13050b57cec5SDimitry Andric     next();
1306bdd1243dSDimitry Andric     // In Verilog primitives' state tables, `:`, `?`, and `-` aren't normal
1307bdd1243dSDimitry Andric     // operators.
1308bdd1243dSDimitry Andric     if (Tok->is(TT_VerilogTableItem))
1309bdd1243dSDimitry Andric       return true;
13100fca6ea1SDimitry Andric     // Multi-line string itself is a single annotated token.
13110fca6ea1SDimitry Andric     if (Tok->is(TT_TableGenMultiLineString))
13120fca6ea1SDimitry Andric       return true;
13130b57cec5SDimitry Andric     switch (Tok->Tok.getKind()) {
13140b57cec5SDimitry Andric     case tok::plus:
13150b57cec5SDimitry Andric     case tok::minus:
13160b57cec5SDimitry Andric       if (!Tok->Previous && Line.MustBeDeclaration)
13175ffd83dbSDimitry Andric         Tok->setType(TT_ObjCMethodSpecifier);
13180b57cec5SDimitry Andric       break;
13190b57cec5SDimitry Andric     case tok::colon:
13200b57cec5SDimitry Andric       if (!Tok->Previous)
13210b57cec5SDimitry Andric         return false;
132206c3fb27SDimitry Andric       // Goto labels and case labels are already identified in
132306c3fb27SDimitry Andric       // UnwrappedLineParser.
132406c3fb27SDimitry Andric       if (Tok->isTypeFinalized())
132506c3fb27SDimitry Andric         break;
13260b57cec5SDimitry Andric       // Colons from ?: are handled in parseConditional().
13270eae32dcSDimitry Andric       if (Style.isJavaScript()) {
13280b57cec5SDimitry Andric         if (Contexts.back().ColonIsForRangeExpr || // colon in for loop
13290b57cec5SDimitry Andric             (Contexts.size() == 1 &&               // switch/case labels
13300b57cec5SDimitry Andric              !Line.First->isOneOf(tok::kw_enum, tok::kw_case)) ||
13310b57cec5SDimitry Andric             Contexts.back().ContextKind == tok::l_paren ||  // function params
13320b57cec5SDimitry Andric             Contexts.back().ContextKind == tok::l_square || // array type
13330b57cec5SDimitry Andric             (!Contexts.back().IsExpression &&
13340b57cec5SDimitry Andric              Contexts.back().ContextKind == tok::l_brace) || // object type
13350b57cec5SDimitry Andric             (Contexts.size() == 1 &&
13360b57cec5SDimitry Andric              Line.MustBeDeclaration)) { // method/property declaration
13370b57cec5SDimitry Andric           Contexts.back().IsExpression = false;
13385ffd83dbSDimitry Andric           Tok->setType(TT_JsTypeColon);
13395ffd83dbSDimitry Andric           break;
13405ffd83dbSDimitry Andric         }
13415ffd83dbSDimitry Andric       } else if (Style.isCSharp()) {
13425ffd83dbSDimitry Andric         if (Contexts.back().InCSharpAttributeSpecifier) {
13435ffd83dbSDimitry Andric           Tok->setType(TT_AttributeColon);
13445ffd83dbSDimitry Andric           break;
13455ffd83dbSDimitry Andric         }
13465ffd83dbSDimitry Andric         if (Contexts.back().ContextKind == tok::l_paren) {
13475ffd83dbSDimitry Andric           Tok->setType(TT_CSharpNamedArgumentColon);
13480b57cec5SDimitry Andric           break;
13490b57cec5SDimitry Andric         }
1350bdd1243dSDimitry Andric       } else if (Style.isVerilog() && Tok->isNot(TT_BinaryOperator)) {
1351bdd1243dSDimitry Andric         // The distribution weight operators are labeled
1352bdd1243dSDimitry Andric         // TT_BinaryOperator by the lexer.
1353bdd1243dSDimitry Andric         if (Keywords.isVerilogEnd(*Tok->Previous) ||
1354bdd1243dSDimitry Andric             Keywords.isVerilogBegin(*Tok->Previous)) {
1355bdd1243dSDimitry Andric           Tok->setType(TT_VerilogBlockLabelColon);
1356bdd1243dSDimitry Andric         } else if (Contexts.back().ContextKind == tok::l_square) {
1357bdd1243dSDimitry Andric           Tok->setType(TT_BitFieldColon);
1358bdd1243dSDimitry Andric         } else if (Contexts.back().ColonIsDictLiteral) {
1359bdd1243dSDimitry Andric           Tok->setType(TT_DictLiteral);
1360bdd1243dSDimitry Andric         } else if (Contexts.size() == 1) {
1361bdd1243dSDimitry Andric           // In Verilog a case label doesn't have the case keyword. We
1362bdd1243dSDimitry Andric           // assume a colon following an expression is a case label.
1363bdd1243dSDimitry Andric           // Colons from ?: are annotated in parseConditional().
136406c3fb27SDimitry Andric           Tok->setType(TT_CaseLabelColon);
1365bdd1243dSDimitry Andric           if (Line.Level > 1 || (!Line.InPPDirective && Line.Level > 0))
1366bdd1243dSDimitry Andric             --Line.Level;
1367bdd1243dSDimitry Andric         }
1368bdd1243dSDimitry Andric         break;
13690b57cec5SDimitry Andric       }
13704824e7fdSDimitry Andric       if (Line.First->isOneOf(Keywords.kw_module, Keywords.kw_import) ||
13714824e7fdSDimitry Andric           Line.First->startsSequence(tok::kw_export, Keywords.kw_module) ||
13724824e7fdSDimitry Andric           Line.First->startsSequence(tok::kw_export, Keywords.kw_import)) {
13734824e7fdSDimitry Andric         Tok->setType(TT_ModulePartitionColon);
13740fca6ea1SDimitry Andric       } else if (Line.First->is(tok::kw_asm)) {
13750fca6ea1SDimitry Andric         Tok->setType(TT_InlineASMColon);
13765f757f3fSDimitry Andric       } else if (Contexts.back().ColonIsDictLiteral || Style.isProto()) {
13775ffd83dbSDimitry Andric         Tok->setType(TT_DictLiteral);
13780b57cec5SDimitry Andric         if (Style.Language == FormatStyle::LK_TextProto) {
13790b57cec5SDimitry Andric           if (FormatToken *Previous = Tok->getPreviousNonComment())
13805ffd83dbSDimitry Andric             Previous->setType(TT_SelectorName);
13810b57cec5SDimitry Andric         }
13820b57cec5SDimitry Andric       } else if (Contexts.back().ColonIsObjCMethodExpr ||
13830b57cec5SDimitry Andric                  Line.startsWith(TT_ObjCMethodSpecifier)) {
13845ffd83dbSDimitry Andric         Tok->setType(TT_ObjCMethodExpr);
13850b57cec5SDimitry Andric         const FormatToken *BeforePrevious = Tok->Previous->Previous;
13860b57cec5SDimitry Andric         // Ensure we tag all identifiers in method declarations as
13870b57cec5SDimitry Andric         // TT_SelectorName.
13880b57cec5SDimitry Andric         bool UnknownIdentifierInMethodDeclaration =
13890b57cec5SDimitry Andric             Line.startsWith(TT_ObjCMethodSpecifier) &&
13900b57cec5SDimitry Andric             Tok->Previous->is(tok::identifier) && Tok->Previous->is(TT_Unknown);
13910b57cec5SDimitry Andric         if (!BeforePrevious ||
13920b57cec5SDimitry Andric             // FIXME(bug 36976): ObjC return types shouldn't use TT_CastRParen.
13930b57cec5SDimitry Andric             !(BeforePrevious->is(TT_CastRParen) ||
13940b57cec5SDimitry Andric               (BeforePrevious->is(TT_ObjCMethodExpr) &&
13950b57cec5SDimitry Andric                BeforePrevious->is(tok::colon))) ||
13960b57cec5SDimitry Andric             BeforePrevious->is(tok::r_square) ||
13970b57cec5SDimitry Andric             Contexts.back().LongestObjCSelectorName == 0 ||
13980b57cec5SDimitry Andric             UnknownIdentifierInMethodDeclaration) {
13995ffd83dbSDimitry Andric           Tok->Previous->setType(TT_SelectorName);
140081ad6265SDimitry Andric           if (!Contexts.back().FirstObjCSelectorName) {
14010b57cec5SDimitry Andric             Contexts.back().FirstObjCSelectorName = Tok->Previous;
140281ad6265SDimitry Andric           } else if (Tok->Previous->ColumnWidth >
140381ad6265SDimitry Andric                      Contexts.back().LongestObjCSelectorName) {
14040b57cec5SDimitry Andric             Contexts.back().LongestObjCSelectorName =
14050b57cec5SDimitry Andric                 Tok->Previous->ColumnWidth;
140681ad6265SDimitry Andric           }
14070b57cec5SDimitry Andric           Tok->Previous->ParameterIndex =
14080b57cec5SDimitry Andric               Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts;
14090b57cec5SDimitry Andric           ++Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts;
14100b57cec5SDimitry Andric         }
14110b57cec5SDimitry Andric       } else if (Contexts.back().ColonIsForRangeExpr) {
14125ffd83dbSDimitry Andric         Tok->setType(TT_RangeBasedForLoopColon);
1413bdd1243dSDimitry Andric       } else if (Contexts.back().ContextType == Context::C11GenericSelection) {
1414bdd1243dSDimitry Andric         Tok->setType(TT_GenericSelectionColon);
14150b57cec5SDimitry Andric       } else if (CurrentToken && CurrentToken->is(tok::numeric_constant)) {
14165ffd83dbSDimitry Andric         Tok->setType(TT_BitFieldColon);
14170b57cec5SDimitry Andric       } else if (Contexts.size() == 1 &&
1418e8d8bef9SDimitry Andric                  !Line.First->isOneOf(tok::kw_enum, tok::kw_case,
1419e8d8bef9SDimitry Andric                                       tok::kw_default)) {
14205ffd83dbSDimitry Andric         FormatToken *Prev = Tok->getPreviousNonComment();
14214824e7fdSDimitry Andric         if (!Prev)
14224824e7fdSDimitry Andric           break;
1423fcaf7f86SDimitry Andric         if (Prev->isOneOf(tok::r_paren, tok::kw_noexcept) ||
1424fcaf7f86SDimitry Andric             Prev->ClosesRequiresClause) {
14255ffd83dbSDimitry Andric           Tok->setType(TT_CtorInitializerColon);
142681ad6265SDimitry Andric         } else if (Prev->is(tok::kw_try)) {
14275ffd83dbSDimitry Andric           // Member initializer list within function try block.
14285ffd83dbSDimitry Andric           FormatToken *PrevPrev = Prev->getPreviousNonComment();
14294824e7fdSDimitry Andric           if (!PrevPrev)
14304824e7fdSDimitry Andric             break;
14315ffd83dbSDimitry Andric           if (PrevPrev && PrevPrev->isOneOf(tok::r_paren, tok::kw_noexcept))
14325ffd83dbSDimitry Andric             Tok->setType(TT_CtorInitializerColon);
143381ad6265SDimitry Andric         } else {
14345ffd83dbSDimitry Andric           Tok->setType(TT_InheritanceColon);
14350fca6ea1SDimitry Andric           if (Prev->isAccessSpecifierKeyword())
14360fca6ea1SDimitry Andric             Line.Type = LT_AccessModifier;
143781ad6265SDimitry Andric         }
14380b57cec5SDimitry Andric       } else if (canBeObjCSelectorComponent(*Tok->Previous) && Tok->Next &&
14390b57cec5SDimitry Andric                  (Tok->Next->isOneOf(tok::r_paren, tok::comma) ||
14400b57cec5SDimitry Andric                   (canBeObjCSelectorComponent(*Tok->Next) && Tok->Next->Next &&
14410b57cec5SDimitry Andric                    Tok->Next->Next->is(tok::colon)))) {
14420b57cec5SDimitry Andric         // This handles a special macro in ObjC code where selectors including
14430b57cec5SDimitry Andric         // the colon are passed as macro arguments.
14445ffd83dbSDimitry Andric         Tok->setType(TT_ObjCMethodExpr);
14450b57cec5SDimitry Andric       }
14460b57cec5SDimitry Andric       break;
14470b57cec5SDimitry Andric     case tok::pipe:
14480b57cec5SDimitry Andric     case tok::amp:
14490b57cec5SDimitry Andric       // | and & in declarations/type expressions represent union and
14500b57cec5SDimitry Andric       // intersection types, respectively.
14510eae32dcSDimitry Andric       if (Style.isJavaScript() && !Contexts.back().IsExpression)
14525ffd83dbSDimitry Andric         Tok->setType(TT_JsTypeOperator);
14530b57cec5SDimitry Andric       break;
14540b57cec5SDimitry Andric     case tok::kw_if:
14550fca6ea1SDimitry Andric       if (Style.isTableGen()) {
14560fca6ea1SDimitry Andric         // In TableGen it has the form 'if' <value> 'then'.
14570fca6ea1SDimitry Andric         if (!parseTableGenValue())
14580fca6ea1SDimitry Andric           return false;
14590fca6ea1SDimitry Andric         if (CurrentToken && CurrentToken->is(Keywords.kw_then))
14600fca6ea1SDimitry Andric           next(); // skip then
14610fca6ea1SDimitry Andric         break;
14620fca6ea1SDimitry Andric       }
146381ad6265SDimitry Andric       if (CurrentToken &&
146481ad6265SDimitry Andric           CurrentToken->isOneOf(tok::kw_constexpr, tok::identifier)) {
14650b57cec5SDimitry Andric         next();
146681ad6265SDimitry Andric       }
1467bdd1243dSDimitry Andric       [[fallthrough]];
146881ad6265SDimitry Andric     case tok::kw_while:
14690b57cec5SDimitry Andric       if (CurrentToken && CurrentToken->is(tok::l_paren)) {
14700b57cec5SDimitry Andric         next();
14710b57cec5SDimitry Andric         if (!parseParens(/*LookForDecls=*/true))
14720b57cec5SDimitry Andric           return false;
14730b57cec5SDimitry Andric       }
14740b57cec5SDimitry Andric       break;
14750b57cec5SDimitry Andric     case tok::kw_for:
14760eae32dcSDimitry Andric       if (Style.isJavaScript()) {
14770b57cec5SDimitry Andric         // x.for and {for: ...}
14780b57cec5SDimitry Andric         if ((Tok->Previous && Tok->Previous->is(tok::period)) ||
147981ad6265SDimitry Andric             (Tok->Next && Tok->Next->is(tok::colon))) {
14800b57cec5SDimitry Andric           break;
148181ad6265SDimitry Andric         }
14820b57cec5SDimitry Andric         // JS' for await ( ...
14830b57cec5SDimitry Andric         if (CurrentToken && CurrentToken->is(Keywords.kw_await))
14840b57cec5SDimitry Andric           next();
14850b57cec5SDimitry Andric       }
14860fca6ea1SDimitry Andric       if (IsCpp && CurrentToken && CurrentToken->is(tok::kw_co_await))
14874824e7fdSDimitry Andric         next();
14880b57cec5SDimitry Andric       Contexts.back().ColonIsForRangeExpr = true;
148981ad6265SDimitry Andric       if (!CurrentToken || CurrentToken->isNot(tok::l_paren))
149081ad6265SDimitry Andric         return false;
14910b57cec5SDimitry Andric       next();
14920b57cec5SDimitry Andric       if (!parseParens())
14930b57cec5SDimitry Andric         return false;
14940b57cec5SDimitry Andric       break;
14950b57cec5SDimitry Andric     case tok::l_paren:
14960b57cec5SDimitry Andric       // When faced with 'operator()()', the kw_operator handler incorrectly
14970b57cec5SDimitry Andric       // marks the first l_paren as a OverloadedOperatorLParen. Here, we make
14980b57cec5SDimitry Andric       // the first two parens OverloadedOperators and the second l_paren an
14990b57cec5SDimitry Andric       // OverloadedOperatorLParen.
15000b57cec5SDimitry Andric       if (Tok->Previous && Tok->Previous->is(tok::r_paren) &&
15010b57cec5SDimitry Andric           Tok->Previous->MatchingParen &&
15020b57cec5SDimitry Andric           Tok->Previous->MatchingParen->is(TT_OverloadedOperatorLParen)) {
15035ffd83dbSDimitry Andric         Tok->Previous->setType(TT_OverloadedOperator);
15045ffd83dbSDimitry Andric         Tok->Previous->MatchingParen->setType(TT_OverloadedOperator);
15055ffd83dbSDimitry Andric         Tok->setType(TT_OverloadedOperatorLParen);
15060b57cec5SDimitry Andric       }
15070b57cec5SDimitry Andric 
150806c3fb27SDimitry Andric       if (Style.isVerilog()) {
150906c3fb27SDimitry Andric         // Identify the parameter list and port list in a module instantiation.
151006c3fb27SDimitry Andric         // This is still needed when we already have
151106c3fb27SDimitry Andric         // UnwrappedLineParser::parseVerilogHierarchyHeader because that
151206c3fb27SDimitry Andric         // function is only responsible for the definition, not the
151306c3fb27SDimitry Andric         // instantiation.
151406c3fb27SDimitry Andric         auto IsInstancePort = [&]() {
151506c3fb27SDimitry Andric           const FormatToken *Prev = Tok->getPreviousNonComment();
151606c3fb27SDimitry Andric           const FormatToken *PrevPrev;
151706c3fb27SDimitry Andric           // In the following example all 4 left parentheses will be treated as
151806c3fb27SDimitry Andric           // 'TT_VerilogInstancePortLParen'.
151906c3fb27SDimitry Andric           //
152006c3fb27SDimitry Andric           //   module_x instance_1(port_1); // Case A.
152106c3fb27SDimitry Andric           //   module_x #(parameter_1)      // Case B.
152206c3fb27SDimitry Andric           //       instance_2(port_1),      // Case C.
152306c3fb27SDimitry Andric           //       instance_3(port_1);      // Case D.
152406c3fb27SDimitry Andric           if (!Prev || !(PrevPrev = Prev->getPreviousNonComment()))
152506c3fb27SDimitry Andric             return false;
152606c3fb27SDimitry Andric           // Case A.
152706c3fb27SDimitry Andric           if (Keywords.isVerilogIdentifier(*Prev) &&
152806c3fb27SDimitry Andric               Keywords.isVerilogIdentifier(*PrevPrev)) {
152906c3fb27SDimitry Andric             return true;
153006c3fb27SDimitry Andric           }
153106c3fb27SDimitry Andric           // Case B.
153206c3fb27SDimitry Andric           if (Prev->is(Keywords.kw_verilogHash) &&
153306c3fb27SDimitry Andric               Keywords.isVerilogIdentifier(*PrevPrev)) {
153406c3fb27SDimitry Andric             return true;
153506c3fb27SDimitry Andric           }
153606c3fb27SDimitry Andric           // Case C.
153706c3fb27SDimitry Andric           if (Keywords.isVerilogIdentifier(*Prev) && PrevPrev->is(tok::r_paren))
153806c3fb27SDimitry Andric             return true;
153906c3fb27SDimitry Andric           // Case D.
154006c3fb27SDimitry Andric           if (Keywords.isVerilogIdentifier(*Prev) && PrevPrev->is(tok::comma)) {
154106c3fb27SDimitry Andric             const FormatToken *PrevParen = PrevPrev->getPreviousNonComment();
154206c3fb27SDimitry Andric             if (PrevParen->is(tok::r_paren) && PrevParen->MatchingParen &&
154306c3fb27SDimitry Andric                 PrevParen->MatchingParen->is(TT_VerilogInstancePortLParen)) {
154406c3fb27SDimitry Andric               return true;
154506c3fb27SDimitry Andric             }
154606c3fb27SDimitry Andric           }
154706c3fb27SDimitry Andric           return false;
154806c3fb27SDimitry Andric         };
154906c3fb27SDimitry Andric 
155006c3fb27SDimitry Andric         if (IsInstancePort())
155106c3fb27SDimitry Andric           Tok->setFinalizedType(TT_VerilogInstancePortLParen);
155206c3fb27SDimitry Andric       }
155306c3fb27SDimitry Andric 
15540b57cec5SDimitry Andric       if (!parseParens())
15550b57cec5SDimitry Andric         return false;
15560b57cec5SDimitry Andric       if (Line.MustBeDeclaration && Contexts.size() == 1 &&
15570b57cec5SDimitry Andric           !Contexts.back().IsExpression && !Line.startsWith(TT_ObjCProperty) &&
15580fca6ea1SDimitry Andric           !Line.startsWith(tok::l_paren) &&
15595f757f3fSDimitry Andric           !Tok->isOneOf(TT_TypeDeclarationParen, TT_RequiresExpressionLParen)) {
15605f757f3fSDimitry Andric         if (const auto *Previous = Tok->Previous;
15615f757f3fSDimitry Andric             !Previous ||
15625f757f3fSDimitry Andric             (!Previous->isAttribute() &&
15635f757f3fSDimitry Andric              !Previous->isOneOf(TT_RequiresClause, TT_LeadingJavaAnnotation))) {
15640b57cec5SDimitry Andric           Line.MightBeFunctionDecl = true;
15650fca6ea1SDimitry Andric           Tok->MightBeFunctionDeclParen = true;
156681ad6265SDimitry Andric         }
15675f757f3fSDimitry Andric       }
15680b57cec5SDimitry Andric       break;
15690b57cec5SDimitry Andric     case tok::l_square:
15700fca6ea1SDimitry Andric       if (Style.isTableGen())
15710fca6ea1SDimitry Andric         Tok->setType(TT_TableGenListOpener);
15720b57cec5SDimitry Andric       if (!parseSquare())
15730b57cec5SDimitry Andric         return false;
15740b57cec5SDimitry Andric       break;
15750b57cec5SDimitry Andric     case tok::l_brace:
15760b57cec5SDimitry Andric       if (Style.Language == FormatStyle::LK_TextProto) {
15770b57cec5SDimitry Andric         FormatToken *Previous = Tok->getPreviousNonComment();
15780fca6ea1SDimitry Andric         if (Previous && Previous->isNot(TT_DictLiteral))
15795ffd83dbSDimitry Andric           Previous->setType(TT_SelectorName);
15800b57cec5SDimitry Andric       }
158106c3fb27SDimitry Andric       Scopes.push_back(getScopeType(*Tok));
15820b57cec5SDimitry Andric       if (!parseBrace())
15830b57cec5SDimitry Andric         return false;
15840b57cec5SDimitry Andric       break;
15850b57cec5SDimitry Andric     case tok::less:
15860b57cec5SDimitry Andric       if (parseAngle()) {
15875ffd83dbSDimitry Andric         Tok->setType(TT_TemplateOpener);
15880b57cec5SDimitry Andric         // In TT_Proto, we must distignuish between:
15890b57cec5SDimitry Andric         //   map<key, value>
15900b57cec5SDimitry Andric         //   msg < item: data >
15910b57cec5SDimitry Andric         //   msg: < item: data >
15920b57cec5SDimitry Andric         // In TT_TextProto, map<key, value> does not occur.
15930b57cec5SDimitry Andric         if (Style.Language == FormatStyle::LK_TextProto ||
15940b57cec5SDimitry Andric             (Style.Language == FormatStyle::LK_Proto && Tok->Previous &&
15950b57cec5SDimitry Andric              Tok->Previous->isOneOf(TT_SelectorName, TT_DictLiteral))) {
15965ffd83dbSDimitry Andric           Tok->setType(TT_DictLiteral);
15970b57cec5SDimitry Andric           FormatToken *Previous = Tok->getPreviousNonComment();
15980fca6ea1SDimitry Andric           if (Previous && Previous->isNot(TT_DictLiteral))
15995ffd83dbSDimitry Andric             Previous->setType(TT_SelectorName);
16000b57cec5SDimitry Andric         }
16010fca6ea1SDimitry Andric         if (Style.isTableGen())
16020fca6ea1SDimitry Andric           Tok->setType(TT_TemplateOpener);
16030b57cec5SDimitry Andric       } else {
16045ffd83dbSDimitry Andric         Tok->setType(TT_BinaryOperator);
16050b57cec5SDimitry Andric         NonTemplateLess.insert(Tok);
16060b57cec5SDimitry Andric         CurrentToken = Tok;
16070b57cec5SDimitry Andric         next();
16080b57cec5SDimitry Andric       }
16090b57cec5SDimitry Andric       break;
16100b57cec5SDimitry Andric     case tok::r_paren:
16110b57cec5SDimitry Andric     case tok::r_square:
16120b57cec5SDimitry Andric       return false;
16130b57cec5SDimitry Andric     case tok::r_brace:
161406c3fb27SDimitry Andric       // Don't pop scope when encountering unbalanced r_brace.
161506c3fb27SDimitry Andric       if (!Scopes.empty())
161606c3fb27SDimitry Andric         Scopes.pop_back();
16170b57cec5SDimitry Andric       // Lines can start with '}'.
16180b57cec5SDimitry Andric       if (Tok->Previous)
16190b57cec5SDimitry Andric         return false;
16200b57cec5SDimitry Andric       break;
16210b57cec5SDimitry Andric     case tok::greater:
1622*5deeebd8SDimitry Andric       if (Style.Language != FormatStyle::LK_TextProto && Tok->is(TT_Unknown))
16235ffd83dbSDimitry Andric         Tok->setType(TT_BinaryOperator);
1624a7dea167SDimitry Andric       if (Tok->Previous && Tok->Previous->is(TT_TemplateCloser))
1625a7dea167SDimitry Andric         Tok->SpacesRequiredBefore = 1;
16260b57cec5SDimitry Andric       break;
16270b57cec5SDimitry Andric     case tok::kw_operator:
16285f757f3fSDimitry Andric       if (Style.isProto())
16290b57cec5SDimitry Andric         break;
16300b57cec5SDimitry Andric       while (CurrentToken &&
16310b57cec5SDimitry Andric              !CurrentToken->isOneOf(tok::l_paren, tok::semi, tok::r_paren)) {
16320b57cec5SDimitry Andric         if (CurrentToken->isOneOf(tok::star, tok::amp))
16335ffd83dbSDimitry Andric           CurrentToken->setType(TT_PointerOrReference);
163406c3fb27SDimitry Andric         auto Next = CurrentToken->getNextNonComment();
163506c3fb27SDimitry Andric         if (!Next)
163606c3fb27SDimitry Andric           break;
163706c3fb27SDimitry Andric         if (Next->is(tok::less))
163806c3fb27SDimitry Andric           next();
163906c3fb27SDimitry Andric         else
16400b57cec5SDimitry Andric           consumeToken();
1641bdd1243dSDimitry Andric         if (!CurrentToken)
16425ffd83dbSDimitry Andric           break;
164306c3fb27SDimitry Andric         auto Previous = CurrentToken->getPreviousNonComment();
164406c3fb27SDimitry Andric         assert(Previous);
164506c3fb27SDimitry Andric         if (CurrentToken->is(tok::comma) && Previous->isNot(tok::kw_operator))
164606c3fb27SDimitry Andric           break;
164706c3fb27SDimitry Andric         if (Previous->isOneOf(TT_BinaryOperator, TT_UnaryOperator, tok::comma,
164806c3fb27SDimitry Andric                               tok::star, tok::arrow, tok::amp, tok::ampamp) ||
1649bdd1243dSDimitry Andric             // User defined literal.
16505f757f3fSDimitry Andric             Previous->TokenText.starts_with("\"\"")) {
165106c3fb27SDimitry Andric           Previous->setType(TT_OverloadedOperator);
165206c3fb27SDimitry Andric           if (CurrentToken->isOneOf(tok::less, tok::greater))
165306c3fb27SDimitry Andric             break;
16540b57cec5SDimitry Andric         }
165581ad6265SDimitry Andric       }
16565ffd83dbSDimitry Andric       if (CurrentToken && CurrentToken->is(tok::l_paren))
16575ffd83dbSDimitry Andric         CurrentToken->setType(TT_OverloadedOperatorLParen);
16585ffd83dbSDimitry Andric       if (CurrentToken && CurrentToken->Previous->is(TT_BinaryOperator))
16595ffd83dbSDimitry Andric         CurrentToken->Previous->setType(TT_OverloadedOperator);
16600b57cec5SDimitry Andric       break;
16610b57cec5SDimitry Andric     case tok::question:
16620eae32dcSDimitry Andric       if (Style.isJavaScript() && Tok->Next &&
16630b57cec5SDimitry Andric           Tok->Next->isOneOf(tok::semi, tok::comma, tok::colon, tok::r_paren,
166406c3fb27SDimitry Andric                              tok::r_brace, tok::r_square)) {
16650b57cec5SDimitry Andric         // Question marks before semicolons, colons, etc. indicate optional
16660b57cec5SDimitry Andric         // types (fields, parameters), e.g.
16670b57cec5SDimitry Andric         //   function(x?: string, y?) {...}
16680b57cec5SDimitry Andric         //   class X { y?; }
16695ffd83dbSDimitry Andric         Tok->setType(TT_JsTypeOptionalQuestion);
16700b57cec5SDimitry Andric         break;
16710b57cec5SDimitry Andric       }
16720b57cec5SDimitry Andric       // Declarations cannot be conditional expressions, this can only be part
16730b57cec5SDimitry Andric       // of a type declaration.
16740b57cec5SDimitry Andric       if (Line.MustBeDeclaration && !Contexts.back().IsExpression &&
167581ad6265SDimitry Andric           Style.isJavaScript()) {
16760b57cec5SDimitry Andric         break;
167781ad6265SDimitry Andric       }
16785ffd83dbSDimitry Andric       if (Style.isCSharp()) {
16795ffd83dbSDimitry Andric         // `Type?)`, `Type?>`, `Type? name;` and `Type? name =` can only be
16805ffd83dbSDimitry Andric         // nullable types.
168106c3fb27SDimitry Andric 
168206c3fb27SDimitry Andric         // `Type?)`, `Type?>`, `Type? name;`
168306c3fb27SDimitry Andric         if (Tok->Next &&
168406c3fb27SDimitry Andric             (Tok->Next->startsSequence(tok::question, tok::r_paren) ||
168506c3fb27SDimitry Andric              Tok->Next->startsSequence(tok::question, tok::greater) ||
168606c3fb27SDimitry Andric              Tok->Next->startsSequence(tok::question, tok::identifier,
168706c3fb27SDimitry Andric                                        tok::semi))) {
168806c3fb27SDimitry Andric           Tok->setType(TT_CSharpNullable);
168906c3fb27SDimitry Andric           break;
169006c3fb27SDimitry Andric         }
169106c3fb27SDimitry Andric 
169206c3fb27SDimitry Andric         // `Type? name =`
169306c3fb27SDimitry Andric         if (Tok->Next && Tok->Next->is(tok::identifier) && Tok->Next->Next &&
169406c3fb27SDimitry Andric             Tok->Next->Next->is(tok::equal)) {
169506c3fb27SDimitry Andric           Tok->setType(TT_CSharpNullable);
169606c3fb27SDimitry Andric           break;
169706c3fb27SDimitry Andric         }
169806c3fb27SDimitry Andric 
16995ffd83dbSDimitry Andric         // Line.MustBeDeclaration will be true for `Type? name;`.
170006c3fb27SDimitry Andric         // But not
170106c3fb27SDimitry Andric         // cond ? "A" : "B";
170206c3fb27SDimitry Andric         // cond ? id : "B";
170306c3fb27SDimitry Andric         // cond ? cond2 ? "A" : "B" : "C";
170406c3fb27SDimitry Andric         if (!Contexts.back().IsExpression && Line.MustBeDeclaration &&
170506c3fb27SDimitry Andric             (!Tok->Next ||
170606c3fb27SDimitry Andric              !Tok->Next->isOneOf(tok::identifier, tok::string_literal) ||
170706c3fb27SDimitry Andric              !Tok->Next->Next ||
170806c3fb27SDimitry Andric              !Tok->Next->Next->isOneOf(tok::colon, tok::question))) {
17095ffd83dbSDimitry Andric           Tok->setType(TT_CSharpNullable);
17105ffd83dbSDimitry Andric           break;
17115ffd83dbSDimitry Andric         }
17125ffd83dbSDimitry Andric       }
17130b57cec5SDimitry Andric       parseConditional();
17140b57cec5SDimitry Andric       break;
17150b57cec5SDimitry Andric     case tok::kw_template:
17160b57cec5SDimitry Andric       parseTemplateDeclaration();
17170b57cec5SDimitry Andric       break;
17180b57cec5SDimitry Andric     case tok::comma:
171981ad6265SDimitry Andric       switch (Contexts.back().ContextType) {
172081ad6265SDimitry Andric       case Context::CtorInitializer:
17215ffd83dbSDimitry Andric         Tok->setType(TT_CtorInitializerComma);
172281ad6265SDimitry Andric         break;
172381ad6265SDimitry Andric       case Context::InheritanceList:
17245ffd83dbSDimitry Andric         Tok->setType(TT_InheritanceComma);
172581ad6265SDimitry Andric         break;
172606c3fb27SDimitry Andric       case Context::VerilogInstancePortList:
172706c3fb27SDimitry Andric         Tok->setFinalizedType(TT_VerilogInstancePortComma);
172806c3fb27SDimitry Andric         break;
172981ad6265SDimitry Andric       default:
173006c3fb27SDimitry Andric         if (Style.isVerilog() && Contexts.size() == 1 &&
173106c3fb27SDimitry Andric             Line.startsWith(Keywords.kw_assign)) {
173206c3fb27SDimitry Andric           Tok->setFinalizedType(TT_VerilogAssignComma);
173306c3fb27SDimitry Andric         } else if (Contexts.back().FirstStartOfName &&
173481ad6265SDimitry Andric                    (Contexts.size() == 1 || startsWithInitStatement(Line))) {
17350b57cec5SDimitry Andric           Contexts.back().FirstStartOfName->PartOfMultiVariableDeclStmt = true;
17360b57cec5SDimitry Andric           Line.IsMultiVariableDeclStmt = true;
17370b57cec5SDimitry Andric         }
173881ad6265SDimitry Andric         break;
173981ad6265SDimitry Andric       }
174081ad6265SDimitry Andric       if (Contexts.back().ContextType == Context::ForEachMacro)
17410b57cec5SDimitry Andric         Contexts.back().IsExpression = true;
17420b57cec5SDimitry Andric       break;
1743bdd1243dSDimitry Andric     case tok::kw_default:
1744bdd1243dSDimitry Andric       // Unindent case labels.
1745bdd1243dSDimitry Andric       if (Style.isVerilog() && Keywords.isVerilogEndOfLabel(*Tok) &&
1746bdd1243dSDimitry Andric           (Line.Level > 1 || (!Line.InPPDirective && Line.Level > 0))) {
1747bdd1243dSDimitry Andric         --Line.Level;
1748bdd1243dSDimitry Andric       }
1749bdd1243dSDimitry Andric       break;
17500b57cec5SDimitry Andric     case tok::identifier:
17510b57cec5SDimitry Andric       if (Tok->isOneOf(Keywords.kw___has_include,
17520b57cec5SDimitry Andric                        Keywords.kw___has_include_next)) {
17530b57cec5SDimitry Andric         parseHasInclude();
17540b57cec5SDimitry Andric       }
17555ffd83dbSDimitry Andric       if (Style.isCSharp() && Tok->is(Keywords.kw_where) && Tok->Next &&
17565ffd83dbSDimitry Andric           Tok->Next->isNot(tok::l_paren)) {
17575ffd83dbSDimitry Andric         Tok->setType(TT_CSharpGenericTypeConstraint);
17585ffd83dbSDimitry Andric         parseCSharpGenericTypeConstraint();
175906c3fb27SDimitry Andric         if (!Tok->getPreviousNonComment())
1760bdd1243dSDimitry Andric           Line.IsContinuation = true;
17615ffd83dbSDimitry Andric       }
17620fca6ea1SDimitry Andric       if (Style.isTableGen()) {
17630fca6ea1SDimitry Andric         if (Tok->is(Keywords.kw_assert)) {
17640fca6ea1SDimitry Andric           if (!parseTableGenValue())
17650fca6ea1SDimitry Andric             return false;
17660fca6ea1SDimitry Andric         } else if (Tok->isOneOf(Keywords.kw_def, Keywords.kw_defm) &&
17670fca6ea1SDimitry Andric                    (!Tok->Next ||
17680fca6ea1SDimitry Andric                     !Tok->Next->isOneOf(tok::colon, tok::l_brace))) {
17690fca6ea1SDimitry Andric           // The case NameValue appears.
17700fca6ea1SDimitry Andric           if (!parseTableGenValue(true))
17710fca6ea1SDimitry Andric             return false;
17720fca6ea1SDimitry Andric         }
17730fca6ea1SDimitry Andric       }
17740b57cec5SDimitry Andric       break;
177581ad6265SDimitry Andric     case tok::arrow:
17766c4b055cSDimitry Andric       if (Tok->isNot(TT_LambdaArrow) && Tok->Previous &&
17776c4b055cSDimitry Andric           Tok->Previous->is(tok::kw_noexcept)) {
177881ad6265SDimitry Andric         Tok->setType(TT_TrailingReturnArrow);
17796c4b055cSDimitry Andric       }
1780bdd1243dSDimitry Andric       break;
17810fca6ea1SDimitry Andric     case tok::equal:
17820fca6ea1SDimitry Andric       // In TableGen, there must be a value after "=";
17830fca6ea1SDimitry Andric       if (Style.isTableGen() && !parseTableGenValue())
17840fca6ea1SDimitry Andric         return false;
17850fca6ea1SDimitry Andric       break;
17860b57cec5SDimitry Andric     default:
17870b57cec5SDimitry Andric       break;
17880b57cec5SDimitry Andric     }
17890b57cec5SDimitry Andric     return true;
17900b57cec5SDimitry Andric   }
17910b57cec5SDimitry Andric 
17925ffd83dbSDimitry Andric   void parseCSharpGenericTypeConstraint() {
17935ffd83dbSDimitry Andric     int OpenAngleBracketsCount = 0;
17945ffd83dbSDimitry Andric     while (CurrentToken) {
17955ffd83dbSDimitry Andric       if (CurrentToken->is(tok::less)) {
17965ffd83dbSDimitry Andric         // parseAngle is too greedy and will consume the whole line.
17975ffd83dbSDimitry Andric         CurrentToken->setType(TT_TemplateOpener);
17985ffd83dbSDimitry Andric         ++OpenAngleBracketsCount;
17995ffd83dbSDimitry Andric         next();
18005ffd83dbSDimitry Andric       } else if (CurrentToken->is(tok::greater)) {
18015ffd83dbSDimitry Andric         CurrentToken->setType(TT_TemplateCloser);
18025ffd83dbSDimitry Andric         --OpenAngleBracketsCount;
18035ffd83dbSDimitry Andric         next();
18045ffd83dbSDimitry Andric       } else if (CurrentToken->is(tok::comma) && OpenAngleBracketsCount == 0) {
18055ffd83dbSDimitry Andric         // We allow line breaks after GenericTypeConstraintComma's
18065ffd83dbSDimitry Andric         // so do not flag commas in Generics as GenericTypeConstraintComma's.
18075ffd83dbSDimitry Andric         CurrentToken->setType(TT_CSharpGenericTypeConstraintComma);
18085ffd83dbSDimitry Andric         next();
18095ffd83dbSDimitry Andric       } else if (CurrentToken->is(Keywords.kw_where)) {
18105ffd83dbSDimitry Andric         CurrentToken->setType(TT_CSharpGenericTypeConstraint);
18115ffd83dbSDimitry Andric         next();
18125ffd83dbSDimitry Andric       } else if (CurrentToken->is(tok::colon)) {
18135ffd83dbSDimitry Andric         CurrentToken->setType(TT_CSharpGenericTypeConstraintColon);
18145ffd83dbSDimitry Andric         next();
18155ffd83dbSDimitry Andric       } else {
18165ffd83dbSDimitry Andric         next();
18175ffd83dbSDimitry Andric       }
18185ffd83dbSDimitry Andric     }
18195ffd83dbSDimitry Andric   }
18205ffd83dbSDimitry Andric 
18210b57cec5SDimitry Andric   void parseIncludeDirective() {
18220b57cec5SDimitry Andric     if (CurrentToken && CurrentToken->is(tok::less)) {
18230b57cec5SDimitry Andric       next();
18240b57cec5SDimitry Andric       while (CurrentToken) {
18250b57cec5SDimitry Andric         // Mark tokens up to the trailing line comments as implicit string
18260b57cec5SDimitry Andric         // literals.
18270b57cec5SDimitry Andric         if (CurrentToken->isNot(tok::comment) &&
18285f757f3fSDimitry Andric             !CurrentToken->TokenText.starts_with("//")) {
18295ffd83dbSDimitry Andric           CurrentToken->setType(TT_ImplicitStringLiteral);
183081ad6265SDimitry Andric         }
18310b57cec5SDimitry Andric         next();
18320b57cec5SDimitry Andric       }
18330b57cec5SDimitry Andric     }
18340b57cec5SDimitry Andric   }
18350b57cec5SDimitry Andric 
18360b57cec5SDimitry Andric   void parseWarningOrError() {
18370b57cec5SDimitry Andric     next();
18380b57cec5SDimitry Andric     // We still want to format the whitespace left of the first token of the
18390b57cec5SDimitry Andric     // warning or error.
18400b57cec5SDimitry Andric     next();
18410b57cec5SDimitry Andric     while (CurrentToken) {
18425ffd83dbSDimitry Andric       CurrentToken->setType(TT_ImplicitStringLiteral);
18430b57cec5SDimitry Andric       next();
18440b57cec5SDimitry Andric     }
18450b57cec5SDimitry Andric   }
18460b57cec5SDimitry Andric 
18470b57cec5SDimitry Andric   void parsePragma() {
18480b57cec5SDimitry Andric     next(); // Consume "pragma".
18490b57cec5SDimitry Andric     if (CurrentToken &&
185081ad6265SDimitry Andric         CurrentToken->isOneOf(Keywords.kw_mark, Keywords.kw_option,
185181ad6265SDimitry Andric                               Keywords.kw_region)) {
1852bdd1243dSDimitry Andric       bool IsMarkOrRegion =
1853bdd1243dSDimitry Andric           CurrentToken->isOneOf(Keywords.kw_mark, Keywords.kw_region);
185481ad6265SDimitry Andric       next();
18550b57cec5SDimitry Andric       next(); // Consume first token (so we fix leading whitespace).
18560b57cec5SDimitry Andric       while (CurrentToken) {
1857bdd1243dSDimitry Andric         if (IsMarkOrRegion || CurrentToken->Previous->is(TT_BinaryOperator))
18585ffd83dbSDimitry Andric           CurrentToken->setType(TT_ImplicitStringLiteral);
18590b57cec5SDimitry Andric         next();
18600b57cec5SDimitry Andric       }
18610b57cec5SDimitry Andric     }
18620b57cec5SDimitry Andric   }
18630b57cec5SDimitry Andric 
18640b57cec5SDimitry Andric   void parseHasInclude() {
18655f757f3fSDimitry Andric     if (!CurrentToken || CurrentToken->isNot(tok::l_paren))
18660b57cec5SDimitry Andric       return;
18670b57cec5SDimitry Andric     next(); // '('
18680b57cec5SDimitry Andric     parseIncludeDirective();
18690b57cec5SDimitry Andric     next(); // ')'
18700b57cec5SDimitry Andric   }
18710b57cec5SDimitry Andric 
18720b57cec5SDimitry Andric   LineType parsePreprocessorDirective() {
18730b57cec5SDimitry Andric     bool IsFirstToken = CurrentToken->IsFirst;
18740b57cec5SDimitry Andric     LineType Type = LT_PreprocessorDirective;
18750b57cec5SDimitry Andric     next();
18760b57cec5SDimitry Andric     if (!CurrentToken)
18770b57cec5SDimitry Andric       return Type;
18780b57cec5SDimitry Andric 
18790eae32dcSDimitry Andric     if (Style.isJavaScript() && IsFirstToken) {
18800b57cec5SDimitry Andric       // JavaScript files can contain shebang lines of the form:
18810b57cec5SDimitry Andric       // #!/usr/bin/env node
18820b57cec5SDimitry Andric       // Treat these like C++ #include directives.
18830b57cec5SDimitry Andric       while (CurrentToken) {
18840b57cec5SDimitry Andric         // Tokens cannot be comments here.
18855ffd83dbSDimitry Andric         CurrentToken->setType(TT_ImplicitStringLiteral);
18860b57cec5SDimitry Andric         next();
18870b57cec5SDimitry Andric       }
18880b57cec5SDimitry Andric       return LT_ImportStatement;
18890b57cec5SDimitry Andric     }
18900b57cec5SDimitry Andric 
189181ad6265SDimitry Andric     if (CurrentToken->is(tok::numeric_constant)) {
18920b57cec5SDimitry Andric       CurrentToken->SpacesRequiredBefore = 1;
18930b57cec5SDimitry Andric       return Type;
18940b57cec5SDimitry Andric     }
18950b57cec5SDimitry Andric     // Hashes in the middle of a line can lead to any strange token
18960b57cec5SDimitry Andric     // sequence.
18970b57cec5SDimitry Andric     if (!CurrentToken->Tok.getIdentifierInfo())
18980b57cec5SDimitry Andric       return Type;
189981ad6265SDimitry Andric     // In Verilog macro expansions start with a backtick just like preprocessor
190081ad6265SDimitry Andric     // directives. Thus we stop if the word is not a preprocessor directive.
190181ad6265SDimitry Andric     if (Style.isVerilog() && !Keywords.isVerilogPPDirective(*CurrentToken))
190281ad6265SDimitry Andric       return LT_Invalid;
19030b57cec5SDimitry Andric     switch (CurrentToken->Tok.getIdentifierInfo()->getPPKeywordID()) {
19040b57cec5SDimitry Andric     case tok::pp_include:
19050b57cec5SDimitry Andric     case tok::pp_include_next:
19060b57cec5SDimitry Andric     case tok::pp_import:
19070b57cec5SDimitry Andric       next();
19080b57cec5SDimitry Andric       parseIncludeDirective();
19090b57cec5SDimitry Andric       Type = LT_ImportStatement;
19100b57cec5SDimitry Andric       break;
19110b57cec5SDimitry Andric     case tok::pp_error:
19120b57cec5SDimitry Andric     case tok::pp_warning:
19130b57cec5SDimitry Andric       parseWarningOrError();
19140b57cec5SDimitry Andric       break;
19150b57cec5SDimitry Andric     case tok::pp_pragma:
19160b57cec5SDimitry Andric       parsePragma();
19170b57cec5SDimitry Andric       break;
19180b57cec5SDimitry Andric     case tok::pp_if:
19190b57cec5SDimitry Andric     case tok::pp_elif:
19200b57cec5SDimitry Andric       Contexts.back().IsExpression = true;
1921a7dea167SDimitry Andric       next();
19220fca6ea1SDimitry Andric       if (CurrentToken)
19230fca6ea1SDimitry Andric         CurrentToken->SpacesRequiredBefore = true;
19240b57cec5SDimitry Andric       parseLine();
19250b57cec5SDimitry Andric       break;
19260b57cec5SDimitry Andric     default:
19270b57cec5SDimitry Andric       break;
19280b57cec5SDimitry Andric     }
19290b57cec5SDimitry Andric     while (CurrentToken) {
19300b57cec5SDimitry Andric       FormatToken *Tok = CurrentToken;
19310b57cec5SDimitry Andric       next();
193281ad6265SDimitry Andric       if (Tok->is(tok::l_paren)) {
19330b57cec5SDimitry Andric         parseParens();
193481ad6265SDimitry Andric       } else if (Tok->isOneOf(Keywords.kw___has_include,
193581ad6265SDimitry Andric                               Keywords.kw___has_include_next)) {
19360b57cec5SDimitry Andric         parseHasInclude();
19370b57cec5SDimitry Andric       }
193881ad6265SDimitry Andric     }
19390b57cec5SDimitry Andric     return Type;
19400b57cec5SDimitry Andric   }
19410b57cec5SDimitry Andric 
19420b57cec5SDimitry Andric public:
19430b57cec5SDimitry Andric   LineType parseLine() {
1944a7dea167SDimitry Andric     if (!CurrentToken)
1945a7dea167SDimitry Andric       return LT_Invalid;
19460b57cec5SDimitry Andric     NonTemplateLess.clear();
1947bdd1243dSDimitry Andric     if (!Line.InMacroBody && CurrentToken->is(tok::hash)) {
194881ad6265SDimitry Andric       // We were not yet allowed to use C++17 optional when this was being
194981ad6265SDimitry Andric       // written. So we used LT_Invalid to mark that the line is not a
195081ad6265SDimitry Andric       // preprocessor directive.
195181ad6265SDimitry Andric       auto Type = parsePreprocessorDirective();
195281ad6265SDimitry Andric       if (Type != LT_Invalid)
195381ad6265SDimitry Andric         return Type;
195481ad6265SDimitry Andric     }
19550b57cec5SDimitry Andric 
19560b57cec5SDimitry Andric     // Directly allow to 'import <string-literal>' to support protocol buffer
19570b57cec5SDimitry Andric     // definitions (github.com/google/protobuf) or missing "#" (either way we
19580b57cec5SDimitry Andric     // should not break the line).
19590b57cec5SDimitry Andric     IdentifierInfo *Info = CurrentToken->Tok.getIdentifierInfo();
19600b57cec5SDimitry Andric     if ((Style.Language == FormatStyle::LK_Java &&
19610b57cec5SDimitry Andric          CurrentToken->is(Keywords.kw_package)) ||
1962bdd1243dSDimitry Andric         (!Style.isVerilog() && Info &&
1963bdd1243dSDimitry Andric          Info->getPPKeywordID() == tok::pp_import && CurrentToken->Next &&
19640b57cec5SDimitry Andric          CurrentToken->Next->isOneOf(tok::string_literal, tok::identifier,
19650b57cec5SDimitry Andric                                      tok::kw_static))) {
19660b57cec5SDimitry Andric       next();
19670b57cec5SDimitry Andric       parseIncludeDirective();
19680b57cec5SDimitry Andric       return LT_ImportStatement;
19690b57cec5SDimitry Andric     }
19700b57cec5SDimitry Andric 
19710b57cec5SDimitry Andric     // If this line starts and ends in '<' and '>', respectively, it is likely
19720b57cec5SDimitry Andric     // part of "#define <a/b.h>".
19730b57cec5SDimitry Andric     if (CurrentToken->is(tok::less) && Line.Last->is(tok::greater)) {
19740b57cec5SDimitry Andric       parseIncludeDirective();
19750b57cec5SDimitry Andric       return LT_ImportStatement;
19760b57cec5SDimitry Andric     }
19770b57cec5SDimitry Andric 
19780b57cec5SDimitry Andric     // In .proto files, top-level options and package statements are very
19790b57cec5SDimitry Andric     // similar to import statements and should not be line-wrapped.
19800b57cec5SDimitry Andric     if (Style.Language == FormatStyle::LK_Proto && Line.Level == 0 &&
19810b57cec5SDimitry Andric         CurrentToken->isOneOf(Keywords.kw_option, Keywords.kw_package)) {
19820b57cec5SDimitry Andric       next();
19830b57cec5SDimitry Andric       if (CurrentToken && CurrentToken->is(tok::identifier)) {
19840b57cec5SDimitry Andric         while (CurrentToken)
19850b57cec5SDimitry Andric           next();
19860b57cec5SDimitry Andric         return LT_ImportStatement;
19870b57cec5SDimitry Andric       }
19880b57cec5SDimitry Andric     }
19890b57cec5SDimitry Andric 
19900b57cec5SDimitry Andric     bool KeywordVirtualFound = false;
19910b57cec5SDimitry Andric     bool ImportStatement = false;
19920b57cec5SDimitry Andric 
19930b57cec5SDimitry Andric     // import {...} from '...';
19940eae32dcSDimitry Andric     if (Style.isJavaScript() && CurrentToken->is(Keywords.kw_import))
19950b57cec5SDimitry Andric       ImportStatement = true;
19960b57cec5SDimitry Andric 
19970b57cec5SDimitry Andric     while (CurrentToken) {
19980b57cec5SDimitry Andric       if (CurrentToken->is(tok::kw_virtual))
19990b57cec5SDimitry Andric         KeywordVirtualFound = true;
20000eae32dcSDimitry Andric       if (Style.isJavaScript()) {
20010b57cec5SDimitry Andric         // export {...} from '...';
20020b57cec5SDimitry Andric         // An export followed by "from 'some string';" is a re-export from
20030b57cec5SDimitry Andric         // another module identified by a URI and is treated as a
20040b57cec5SDimitry Andric         // LT_ImportStatement (i.e. prevent wraps on it for long URIs).
20050b57cec5SDimitry Andric         // Just "export {...};" or "export class ..." should not be treated as
20060b57cec5SDimitry Andric         // an import in this sense.
20070b57cec5SDimitry Andric         if (Line.First->is(tok::kw_export) &&
20080b57cec5SDimitry Andric             CurrentToken->is(Keywords.kw_from) && CurrentToken->Next &&
200981ad6265SDimitry Andric             CurrentToken->Next->isStringLiteral()) {
20100b57cec5SDimitry Andric           ImportStatement = true;
201181ad6265SDimitry Andric         }
20120b57cec5SDimitry Andric         if (isClosureImportStatement(*CurrentToken))
20130b57cec5SDimitry Andric           ImportStatement = true;
20140b57cec5SDimitry Andric       }
20150b57cec5SDimitry Andric       if (!consumeToken())
20160b57cec5SDimitry Andric         return LT_Invalid;
20170b57cec5SDimitry Andric     }
20180fca6ea1SDimitry Andric     if (Line.Type == LT_AccessModifier)
20190fca6ea1SDimitry Andric       return LT_AccessModifier;
20200b57cec5SDimitry Andric     if (KeywordVirtualFound)
20210b57cec5SDimitry Andric       return LT_VirtualFunctionDecl;
20220b57cec5SDimitry Andric     if (ImportStatement)
20230b57cec5SDimitry Andric       return LT_ImportStatement;
20240b57cec5SDimitry Andric 
20250b57cec5SDimitry Andric     if (Line.startsWith(TT_ObjCMethodSpecifier)) {
202681ad6265SDimitry Andric       if (Contexts.back().FirstObjCSelectorName) {
20270b57cec5SDimitry Andric         Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
20280b57cec5SDimitry Andric             Contexts.back().LongestObjCSelectorName;
202981ad6265SDimitry Andric       }
20300b57cec5SDimitry Andric       return LT_ObjCMethodDecl;
20310b57cec5SDimitry Andric     }
20320b57cec5SDimitry Andric 
203381ad6265SDimitry Andric     for (const auto &ctx : Contexts)
203481ad6265SDimitry Andric       if (ctx.ContextType == Context::StructArrayInitializer)
2035fe6060f1SDimitry Andric         return LT_ArrayOfStructInitializer;
2036fe6060f1SDimitry Andric 
20370b57cec5SDimitry Andric     return LT_Other;
20380b57cec5SDimitry Andric   }
20390b57cec5SDimitry Andric 
20400b57cec5SDimitry Andric private:
20410b57cec5SDimitry Andric   bool isClosureImportStatement(const FormatToken &Tok) {
20420b57cec5SDimitry Andric     // FIXME: Closure-library specific stuff should not be hard-coded but be
20430b57cec5SDimitry Andric     // configurable.
20440b57cec5SDimitry Andric     return Tok.TokenText == "goog" && Tok.Next && Tok.Next->is(tok::period) &&
20450b57cec5SDimitry Andric            Tok.Next->Next &&
20460b57cec5SDimitry Andric            (Tok.Next->Next->TokenText == "module" ||
20470b57cec5SDimitry Andric             Tok.Next->Next->TokenText == "provide" ||
20480b57cec5SDimitry Andric             Tok.Next->Next->TokenText == "require" ||
20490b57cec5SDimitry Andric             Tok.Next->Next->TokenText == "requireType" ||
20500b57cec5SDimitry Andric             Tok.Next->Next->TokenText == "forwardDeclare") &&
20510b57cec5SDimitry Andric            Tok.Next->Next->Next && Tok.Next->Next->Next->is(tok::l_paren);
20520b57cec5SDimitry Andric   }
20530b57cec5SDimitry Andric 
205404eeddc0SDimitry Andric   void resetTokenMetadata() {
205504eeddc0SDimitry Andric     if (!CurrentToken)
20560b57cec5SDimitry Andric       return;
20570b57cec5SDimitry Andric 
20580b57cec5SDimitry Andric     // Reset token type in case we have already looked at it and then
20590b57cec5SDimitry Andric     // recovered from an error (e.g. failure to find the matching >).
206081ad6265SDimitry Andric     if (!CurrentToken->isTypeFinalized() &&
206181ad6265SDimitry Andric         !CurrentToken->isOneOf(
2062fe6060f1SDimitry Andric             TT_LambdaLSquare, TT_LambdaLBrace, TT_AttributeMacro, TT_IfMacro,
2063e8d8bef9SDimitry Andric             TT_ForEachMacro, TT_TypenameMacro, TT_FunctionLBrace,
2064fe6060f1SDimitry Andric             TT_ImplicitStringLiteral, TT_InlineASMBrace, TT_FatArrow,
20656c4b055cSDimitry Andric             TT_LambdaArrow, TT_NamespaceMacro, TT_OverloadedOperator,
20666c4b055cSDimitry Andric             TT_RegexLiteral, TT_TemplateString, TT_ObjCStringLiteral,
20676c4b055cSDimitry Andric             TT_UntouchableMacroFunc, TT_StatementAttributeLikeMacro,
20686c4b055cSDimitry Andric             TT_FunctionLikeOrFreestandingMacro, TT_ClassLBrace, TT_EnumLBrace,
20696c4b055cSDimitry Andric             TT_RecordLBrace, TT_StructLBrace, TT_UnionLBrace, TT_RequiresClause,
207081ad6265SDimitry Andric             TT_RequiresClauseInARequiresExpression, TT_RequiresExpression,
207181ad6265SDimitry Andric             TT_RequiresExpressionLParen, TT_RequiresExpressionLBrace,
20725f757f3fSDimitry Andric             TT_BracedListLBrace)) {
20735ffd83dbSDimitry Andric       CurrentToken->setType(TT_Unknown);
207481ad6265SDimitry Andric     }
20750b57cec5SDimitry Andric     CurrentToken->Role.reset();
20760b57cec5SDimitry Andric     CurrentToken->MatchingParen = nullptr;
20770b57cec5SDimitry Andric     CurrentToken->FakeLParens.clear();
20780b57cec5SDimitry Andric     CurrentToken->FakeRParens = 0;
20790b57cec5SDimitry Andric   }
20800b57cec5SDimitry Andric 
20810b57cec5SDimitry Andric   void next() {
208204eeddc0SDimitry Andric     if (!CurrentToken)
208304eeddc0SDimitry Andric       return;
208404eeddc0SDimitry Andric 
20850b57cec5SDimitry Andric     CurrentToken->NestingLevel = Contexts.size() - 1;
20860b57cec5SDimitry Andric     CurrentToken->BindingStrength = Contexts.back().BindingStrength;
20870b57cec5SDimitry Andric     modifyContext(*CurrentToken);
20880b57cec5SDimitry Andric     determineTokenType(*CurrentToken);
20890b57cec5SDimitry Andric     CurrentToken = CurrentToken->Next;
20900b57cec5SDimitry Andric 
209104eeddc0SDimitry Andric     resetTokenMetadata();
20920b57cec5SDimitry Andric   }
20930b57cec5SDimitry Andric 
20940b57cec5SDimitry Andric   /// A struct to hold information valid in a specific context, e.g.
20950b57cec5SDimitry Andric   /// a pair of parenthesis.
20960b57cec5SDimitry Andric   struct Context {
20970b57cec5SDimitry Andric     Context(tok::TokenKind ContextKind, unsigned BindingStrength,
20980b57cec5SDimitry Andric             bool IsExpression)
20990b57cec5SDimitry Andric         : ContextKind(ContextKind), BindingStrength(BindingStrength),
21000b57cec5SDimitry Andric           IsExpression(IsExpression) {}
21010b57cec5SDimitry Andric 
21020b57cec5SDimitry Andric     tok::TokenKind ContextKind;
21030b57cec5SDimitry Andric     unsigned BindingStrength;
21040b57cec5SDimitry Andric     bool IsExpression;
21050b57cec5SDimitry Andric     unsigned LongestObjCSelectorName = 0;
21060b57cec5SDimitry Andric     bool ColonIsForRangeExpr = false;
21070b57cec5SDimitry Andric     bool ColonIsDictLiteral = false;
21080b57cec5SDimitry Andric     bool ColonIsObjCMethodExpr = false;
21090b57cec5SDimitry Andric     FormatToken *FirstObjCSelectorName = nullptr;
21100b57cec5SDimitry Andric     FormatToken *FirstStartOfName = nullptr;
21110b57cec5SDimitry Andric     bool CanBeExpression = true;
21120b57cec5SDimitry Andric     bool CaretFound = false;
21130b57cec5SDimitry Andric     bool InCpp11AttributeSpecifier = false;
21140b57cec5SDimitry Andric     bool InCSharpAttributeSpecifier = false;
211506c3fb27SDimitry Andric     bool VerilogAssignmentFound = false;
21165f757f3fSDimitry Andric     // Whether the braces may mean concatenation instead of structure or array
21175f757f3fSDimitry Andric     // literal.
21185f757f3fSDimitry Andric     bool VerilogMayBeConcatenation = false;
21190fca6ea1SDimitry Andric     bool IsTableGenDAGArg = false;
21200fca6ea1SDimitry Andric     bool IsTableGenBangOpe = false;
21210fca6ea1SDimitry Andric     bool IsTableGenCondOpe = false;
212281ad6265SDimitry Andric     enum {
212381ad6265SDimitry Andric       Unknown,
212481ad6265SDimitry Andric       // Like the part after `:` in a constructor.
212581ad6265SDimitry Andric       //   Context(...) : IsExpression(IsExpression)
212681ad6265SDimitry Andric       CtorInitializer,
212781ad6265SDimitry Andric       // Like in the parentheses in a foreach.
212881ad6265SDimitry Andric       ForEachMacro,
212981ad6265SDimitry Andric       // Like the inheritance list in a class declaration.
213081ad6265SDimitry Andric       //   class Input : public IO
213181ad6265SDimitry Andric       InheritanceList,
213281ad6265SDimitry Andric       // Like in the braced list.
213381ad6265SDimitry Andric       //   int x[] = {};
213481ad6265SDimitry Andric       StructArrayInitializer,
213581ad6265SDimitry Andric       // Like in `static_cast<int>`.
213681ad6265SDimitry Andric       TemplateArgument,
2137bdd1243dSDimitry Andric       // C11 _Generic selection.
2138bdd1243dSDimitry Andric       C11GenericSelection,
213906c3fb27SDimitry Andric       // Like in the outer parentheses in `ffnand ff1(.q());`.
214006c3fb27SDimitry Andric       VerilogInstancePortList,
214181ad6265SDimitry Andric     } ContextType = Unknown;
21420b57cec5SDimitry Andric   };
21430b57cec5SDimitry Andric 
21440b57cec5SDimitry Andric   /// Puts a new \c Context onto the stack \c Contexts for the lifetime
21450b57cec5SDimitry Andric   /// of each instance.
21460b57cec5SDimitry Andric   struct ScopedContextCreator {
21470b57cec5SDimitry Andric     AnnotatingParser &P;
21480b57cec5SDimitry Andric 
21490b57cec5SDimitry Andric     ScopedContextCreator(AnnotatingParser &P, tok::TokenKind ContextKind,
21500b57cec5SDimitry Andric                          unsigned Increase)
21510b57cec5SDimitry Andric         : P(P) {
21520b57cec5SDimitry Andric       P.Contexts.push_back(Context(ContextKind,
21530b57cec5SDimitry Andric                                    P.Contexts.back().BindingStrength + Increase,
21540b57cec5SDimitry Andric                                    P.Contexts.back().IsExpression));
21550b57cec5SDimitry Andric     }
21560b57cec5SDimitry Andric 
2157fe6060f1SDimitry Andric     ~ScopedContextCreator() {
2158fe6060f1SDimitry Andric       if (P.Style.AlignArrayOfStructures != FormatStyle::AIAS_None) {
215981ad6265SDimitry Andric         if (P.Contexts.back().ContextType == Context::StructArrayInitializer) {
2160fe6060f1SDimitry Andric           P.Contexts.pop_back();
216181ad6265SDimitry Andric           P.Contexts.back().ContextType = Context::StructArrayInitializer;
2162fe6060f1SDimitry Andric           return;
2163fe6060f1SDimitry Andric         }
2164fe6060f1SDimitry Andric       }
2165fe6060f1SDimitry Andric       P.Contexts.pop_back();
2166fe6060f1SDimitry Andric     }
21670b57cec5SDimitry Andric   };
21680b57cec5SDimitry Andric 
21690b57cec5SDimitry Andric   void modifyContext(const FormatToken &Current) {
217081ad6265SDimitry Andric     auto AssignmentStartsExpression = [&]() {
217181ad6265SDimitry Andric       if (Current.getPrecedence() != prec::Assignment)
217281ad6265SDimitry Andric         return false;
217381ad6265SDimitry Andric 
217481ad6265SDimitry Andric       if (Line.First->isOneOf(tok::kw_using, tok::kw_return))
217581ad6265SDimitry Andric         return false;
217681ad6265SDimitry Andric       if (Line.First->is(tok::kw_template)) {
217781ad6265SDimitry Andric         assert(Current.Previous);
217881ad6265SDimitry Andric         if (Current.Previous->is(tok::kw_operator)) {
217981ad6265SDimitry Andric           // `template ... operator=` cannot be an expression.
218081ad6265SDimitry Andric           return false;
218181ad6265SDimitry Andric         }
218281ad6265SDimitry Andric 
218381ad6265SDimitry Andric         // `template` keyword can start a variable template.
218481ad6265SDimitry Andric         const FormatToken *Tok = Line.First->getNextNonComment();
218581ad6265SDimitry Andric         assert(Tok); // Current token is on the same line.
218681ad6265SDimitry Andric         if (Tok->isNot(TT_TemplateOpener)) {
218781ad6265SDimitry Andric           // Explicit template instantiations do not have `<>`.
218881ad6265SDimitry Andric           return false;
218981ad6265SDimitry Andric         }
219081ad6265SDimitry Andric 
219106c3fb27SDimitry Andric         // This is the default value of a template parameter, determine if it's
219206c3fb27SDimitry Andric         // type or non-type.
219306c3fb27SDimitry Andric         if (Contexts.back().ContextKind == tok::less) {
219406c3fb27SDimitry Andric           assert(Current.Previous->Previous);
219506c3fb27SDimitry Andric           return !Current.Previous->Previous->isOneOf(tok::kw_typename,
219606c3fb27SDimitry Andric                                                       tok::kw_class);
219706c3fb27SDimitry Andric         }
219806c3fb27SDimitry Andric 
219981ad6265SDimitry Andric         Tok = Tok->MatchingParen;
220081ad6265SDimitry Andric         if (!Tok)
220181ad6265SDimitry Andric           return false;
220281ad6265SDimitry Andric         Tok = Tok->getNextNonComment();
220381ad6265SDimitry Andric         if (!Tok)
220481ad6265SDimitry Andric           return false;
220581ad6265SDimitry Andric 
2206bdd1243dSDimitry Andric         if (Tok->isOneOf(tok::kw_class, tok::kw_enum, tok::kw_struct,
2207bdd1243dSDimitry Andric                          tok::kw_using)) {
220881ad6265SDimitry Andric           return false;
220981ad6265SDimitry Andric         }
221081ad6265SDimitry Andric 
221181ad6265SDimitry Andric         return true;
221281ad6265SDimitry Andric       }
221381ad6265SDimitry Andric 
22140b57cec5SDimitry Andric       // Type aliases use `type X = ...;` in TypeScript and can be exported
22150b57cec5SDimitry Andric       // using `export type ...`.
221681ad6265SDimitry Andric       if (Style.isJavaScript() &&
22170b57cec5SDimitry Andric           (Line.startsWith(Keywords.kw_type, tok::identifier) ||
22180b57cec5SDimitry Andric            Line.startsWith(tok::kw_export, Keywords.kw_type,
221981ad6265SDimitry Andric                            tok::identifier))) {
222081ad6265SDimitry Andric         return false;
222181ad6265SDimitry Andric       }
222281ad6265SDimitry Andric 
222381ad6265SDimitry Andric       return !Current.Previous || Current.Previous->isNot(tok::kw_operator);
222481ad6265SDimitry Andric     };
222581ad6265SDimitry Andric 
222681ad6265SDimitry Andric     if (AssignmentStartsExpression()) {
22270b57cec5SDimitry Andric       Contexts.back().IsExpression = true;
22280b57cec5SDimitry Andric       if (!Line.startsWith(TT_UnaryOperator)) {
22290b57cec5SDimitry Andric         for (FormatToken *Previous = Current.Previous;
22300b57cec5SDimitry Andric              Previous && Previous->Previous &&
22310b57cec5SDimitry Andric              !Previous->Previous->isOneOf(tok::comma, tok::semi);
22320b57cec5SDimitry Andric              Previous = Previous->Previous) {
223306c3fb27SDimitry Andric           if (Previous->isOneOf(tok::r_square, tok::r_paren, tok::greater)) {
22340b57cec5SDimitry Andric             Previous = Previous->MatchingParen;
22350b57cec5SDimitry Andric             if (!Previous)
22360b57cec5SDimitry Andric               break;
22370b57cec5SDimitry Andric           }
22380b57cec5SDimitry Andric           if (Previous->opensScope())
22390b57cec5SDimitry Andric             break;
22400b57cec5SDimitry Andric           if (Previous->isOneOf(TT_BinaryOperator, TT_UnaryOperator) &&
22415f757f3fSDimitry Andric               Previous->isPointerOrReference() && Previous->Previous &&
22425f757f3fSDimitry Andric               Previous->Previous->isNot(tok::equal)) {
22435ffd83dbSDimitry Andric             Previous->setType(TT_PointerOrReference);
22440b57cec5SDimitry Andric           }
22450b57cec5SDimitry Andric         }
224681ad6265SDimitry Andric       }
22470b57cec5SDimitry Andric     } else if (Current.is(tok::lessless) &&
22485f757f3fSDimitry Andric                (!Current.Previous ||
22495f757f3fSDimitry Andric                 Current.Previous->isNot(tok::kw_operator))) {
22500b57cec5SDimitry Andric       Contexts.back().IsExpression = true;
22510b57cec5SDimitry Andric     } else if (Current.isOneOf(tok::kw_return, tok::kw_throw)) {
22520b57cec5SDimitry Andric       Contexts.back().IsExpression = true;
22530b57cec5SDimitry Andric     } else if (Current.is(TT_TrailingReturnArrow)) {
22540b57cec5SDimitry Andric       Contexts.back().IsExpression = false;
22556c4b055cSDimitry Andric     } else if (Current.isOneOf(TT_LambdaArrow, Keywords.kw_assert)) {
22560b57cec5SDimitry Andric       Contexts.back().IsExpression = Style.Language == FormatStyle::LK_Java;
22570b57cec5SDimitry Andric     } else if (Current.Previous &&
22580b57cec5SDimitry Andric                Current.Previous->is(TT_CtorInitializerColon)) {
22590b57cec5SDimitry Andric       Contexts.back().IsExpression = true;
226081ad6265SDimitry Andric       Contexts.back().ContextType = Context::CtorInitializer;
22610b57cec5SDimitry Andric     } else if (Current.Previous && Current.Previous->is(TT_InheritanceColon)) {
226281ad6265SDimitry Andric       Contexts.back().ContextType = Context::InheritanceList;
22630b57cec5SDimitry Andric     } else if (Current.isOneOf(tok::r_paren, tok::greater, tok::comma)) {
22640b57cec5SDimitry Andric       for (FormatToken *Previous = Current.Previous;
22650b57cec5SDimitry Andric            Previous && Previous->isOneOf(tok::star, tok::amp);
226681ad6265SDimitry Andric            Previous = Previous->Previous) {
22675ffd83dbSDimitry Andric         Previous->setType(TT_PointerOrReference);
226881ad6265SDimitry Andric       }
226981ad6265SDimitry Andric       if (Line.MustBeDeclaration &&
227081ad6265SDimitry Andric           Contexts.front().ContextType != Context::CtorInitializer) {
22710b57cec5SDimitry Andric         Contexts.back().IsExpression = false;
227281ad6265SDimitry Andric       }
22730b57cec5SDimitry Andric     } else if (Current.is(tok::kw_new)) {
22740b57cec5SDimitry Andric       Contexts.back().CanBeExpression = false;
2275480093f4SDimitry Andric     } else if (Current.is(tok::semi) ||
2276480093f4SDimitry Andric                (Current.is(tok::exclaim) && Current.Previous &&
22775f757f3fSDimitry Andric                 Current.Previous->isNot(tok::kw_operator))) {
22780b57cec5SDimitry Andric       // This should be the condition or increment in a for-loop.
2279480093f4SDimitry Andric       // But not operator !() (can't use TT_OverloadedOperator here as its not
2280480093f4SDimitry Andric       // been annotated yet).
22810b57cec5SDimitry Andric       Contexts.back().IsExpression = true;
22820b57cec5SDimitry Andric     }
22830b57cec5SDimitry Andric   }
22840b57cec5SDimitry Andric 
2285480093f4SDimitry Andric   static FormatToken *untilMatchingParen(FormatToken *Current) {
2286480093f4SDimitry Andric     // Used when `MatchingParen` is not yet established.
2287480093f4SDimitry Andric     int ParenLevel = 0;
2288480093f4SDimitry Andric     while (Current) {
2289480093f4SDimitry Andric       if (Current->is(tok::l_paren))
229004eeddc0SDimitry Andric         ++ParenLevel;
2291480093f4SDimitry Andric       if (Current->is(tok::r_paren))
229204eeddc0SDimitry Andric         --ParenLevel;
2293480093f4SDimitry Andric       if (ParenLevel < 1)
2294480093f4SDimitry Andric         break;
2295480093f4SDimitry Andric       Current = Current->Next;
2296480093f4SDimitry Andric     }
2297480093f4SDimitry Andric     return Current;
2298480093f4SDimitry Andric   }
2299480093f4SDimitry Andric 
2300480093f4SDimitry Andric   static bool isDeductionGuide(FormatToken &Current) {
2301480093f4SDimitry Andric     // Look for a deduction guide template<T> A(...) -> A<...>;
2302480093f4SDimitry Andric     if (Current.Previous && Current.Previous->is(tok::r_paren) &&
2303480093f4SDimitry Andric         Current.startsSequence(tok::arrow, tok::identifier, tok::less)) {
2304480093f4SDimitry Andric       // Find the TemplateCloser.
2305480093f4SDimitry Andric       FormatToken *TemplateCloser = Current.Next->Next;
2306480093f4SDimitry Andric       int NestingLevel = 0;
2307480093f4SDimitry Andric       while (TemplateCloser) {
2308480093f4SDimitry Andric         // Skip over an expressions in parens  A<(3 < 2)>;
2309480093f4SDimitry Andric         if (TemplateCloser->is(tok::l_paren)) {
2310480093f4SDimitry Andric           // No Matching Paren yet so skip to matching paren
2311480093f4SDimitry Andric           TemplateCloser = untilMatchingParen(TemplateCloser);
23124824e7fdSDimitry Andric           if (!TemplateCloser)
23134824e7fdSDimitry Andric             break;
2314480093f4SDimitry Andric         }
2315480093f4SDimitry Andric         if (TemplateCloser->is(tok::less))
231604eeddc0SDimitry Andric           ++NestingLevel;
2317480093f4SDimitry Andric         if (TemplateCloser->is(tok::greater))
231804eeddc0SDimitry Andric           --NestingLevel;
2319480093f4SDimitry Andric         if (NestingLevel < 1)
2320480093f4SDimitry Andric           break;
2321480093f4SDimitry Andric         TemplateCloser = TemplateCloser->Next;
2322480093f4SDimitry Andric       }
2323480093f4SDimitry Andric       // Assuming we have found the end of the template ensure its followed
2324480093f4SDimitry Andric       // with a semi-colon.
2325480093f4SDimitry Andric       if (TemplateCloser && TemplateCloser->Next &&
2326480093f4SDimitry Andric           TemplateCloser->Next->is(tok::semi) &&
2327480093f4SDimitry Andric           Current.Previous->MatchingParen) {
2328480093f4SDimitry Andric         // Determine if the identifier `A` prior to the A<..>; is the same as
2329480093f4SDimitry Andric         // prior to the A(..)
2330480093f4SDimitry Andric         FormatToken *LeadingIdentifier =
2331480093f4SDimitry Andric             Current.Previous->MatchingParen->Previous;
2332480093f4SDimitry Andric 
2333bdd1243dSDimitry Andric         return LeadingIdentifier &&
233481ad6265SDimitry Andric                LeadingIdentifier->TokenText == Current.Next->TokenText;
2335480093f4SDimitry Andric       }
2336480093f4SDimitry Andric     }
2337480093f4SDimitry Andric     return false;
2338480093f4SDimitry Andric   }
2339480093f4SDimitry Andric 
23400b57cec5SDimitry Andric   void determineTokenType(FormatToken &Current) {
23415f757f3fSDimitry Andric     if (Current.isNot(TT_Unknown)) {
23420b57cec5SDimitry Andric       // The token type is already known.
23430b57cec5SDimitry Andric       return;
234481ad6265SDimitry Andric     }
23450b57cec5SDimitry Andric 
23460eae32dcSDimitry Andric     if ((Style.isJavaScript() || Style.isCSharp()) &&
2347fe6060f1SDimitry Andric         Current.is(tok::exclaim)) {
2348fe6060f1SDimitry Andric       if (Current.Previous) {
2349fe6060f1SDimitry Andric         bool IsIdentifier =
23500eae32dcSDimitry Andric             Style.isJavaScript()
23510fca6ea1SDimitry Andric                 ? Keywords.isJavaScriptIdentifier(
2352fe6060f1SDimitry Andric                       *Current.Previous, /* AcceptIdentifierName= */ true)
2353fe6060f1SDimitry Andric                 : Current.Previous->is(tok::identifier);
2354fe6060f1SDimitry Andric         if (IsIdentifier ||
23555ffd83dbSDimitry Andric             Current.Previous->isOneOf(
235681ad6265SDimitry Andric                 tok::kw_default, tok::kw_namespace, tok::r_paren, tok::r_square,
235781ad6265SDimitry Andric                 tok::r_brace, tok::kw_false, tok::kw_true, Keywords.kw_type,
235881ad6265SDimitry Andric                 Keywords.kw_get, Keywords.kw_init, Keywords.kw_set) ||
2359fe6060f1SDimitry Andric             Current.Previous->Tok.isLiteral()) {
2360fe6060f1SDimitry Andric           Current.setType(TT_NonNullAssertion);
23610b57cec5SDimitry Andric           return;
23620b57cec5SDimitry Andric         }
2363fe6060f1SDimitry Andric       }
23640b57cec5SDimitry Andric       if (Current.Next &&
23650b57cec5SDimitry Andric           Current.Next->isOneOf(TT_BinaryOperator, Keywords.kw_as)) {
2366fe6060f1SDimitry Andric         Current.setType(TT_NonNullAssertion);
23670b57cec5SDimitry Andric         return;
23680b57cec5SDimitry Andric       }
23690b57cec5SDimitry Andric     }
23700b57cec5SDimitry Andric 
23710b57cec5SDimitry Andric     // Line.MightBeFunctionDecl can only be true after the parentheses of a
23720b57cec5SDimitry Andric     // function declaration have been found. In this case, 'Current' is a
23730b57cec5SDimitry Andric     // trailing token of this declaration and thus cannot be a name.
23740fca6ea1SDimitry Andric     if ((Style.isJavaScript() || Style.Language == FormatStyle::LK_Java) &&
23750fca6ea1SDimitry Andric         Current.is(Keywords.kw_instanceof)) {
23765ffd83dbSDimitry Andric       Current.setType(TT_BinaryOperator);
23770b57cec5SDimitry Andric     } else if (isStartOfName(Current) &&
23780b57cec5SDimitry Andric                (!Line.MightBeFunctionDecl || Current.NestingLevel != 0)) {
23790b57cec5SDimitry Andric       Contexts.back().FirstStartOfName = &Current;
23805ffd83dbSDimitry Andric       Current.setType(TT_StartOfName);
23810b57cec5SDimitry Andric     } else if (Current.is(tok::semi)) {
23820b57cec5SDimitry Andric       // Reset FirstStartOfName after finding a semicolon so that a for loop
23830b57cec5SDimitry Andric       // with multiple increment statements is not confused with a for loop
23840b57cec5SDimitry Andric       // having multiple variable declarations.
23850b57cec5SDimitry Andric       Contexts.back().FirstStartOfName = nullptr;
23860b57cec5SDimitry Andric     } else if (Current.isOneOf(tok::kw_auto, tok::kw___auto_type)) {
23870b57cec5SDimitry Andric       AutoFound = true;
23880b57cec5SDimitry Andric     } else if (Current.is(tok::arrow) &&
23890b57cec5SDimitry Andric                Style.Language == FormatStyle::LK_Java) {
23906c4b055cSDimitry Andric       Current.setType(TT_LambdaArrow);
23915f757f3fSDimitry Andric     } else if (Current.is(tok::arrow) && Style.isVerilog()) {
23925f757f3fSDimitry Andric       // The implication operator.
23935f757f3fSDimitry Andric       Current.setType(TT_BinaryOperator);
239406c3fb27SDimitry Andric     } else if (Current.is(tok::arrow) && AutoFound &&
23955f757f3fSDimitry Andric                Line.MightBeFunctionDecl && Current.NestingLevel == 0 &&
23960eae32dcSDimitry Andric                !Current.Previous->isOneOf(tok::kw_operator, tok::identifier)) {
2397a7dea167SDimitry Andric       // not auto operator->() -> xxx;
23985ffd83dbSDimitry Andric       Current.setType(TT_TrailingReturnArrow);
2399e8d8bef9SDimitry Andric     } else if (Current.is(tok::arrow) && Current.Previous &&
2400e8d8bef9SDimitry Andric                Current.Previous->is(tok::r_brace)) {
2401349cc55cSDimitry Andric       // Concept implicit conversion constraint needs to be treated like
2402e8d8bef9SDimitry Andric       // a trailing return type  ... } -> <type>.
2403e8d8bef9SDimitry Andric       Current.setType(TT_TrailingReturnArrow);
2404480093f4SDimitry Andric     } else if (isDeductionGuide(Current)) {
2405480093f4SDimitry Andric       // Deduction guides trailing arrow " A(...) -> A<T>;".
24065ffd83dbSDimitry Andric       Current.setType(TT_TrailingReturnArrow);
24075f757f3fSDimitry Andric     } else if (Current.isPointerOrReference()) {
24085ffd83dbSDimitry Andric       Current.setType(determineStarAmpUsage(
24095ffd83dbSDimitry Andric           Current,
24105ffd83dbSDimitry Andric           Contexts.back().CanBeExpression && Contexts.back().IsExpression,
241181ad6265SDimitry Andric           Contexts.back().ContextType == Context::TemplateArgument));
2412bdd1243dSDimitry Andric     } else if (Current.isOneOf(tok::minus, tok::plus, tok::caret) ||
2413bdd1243dSDimitry Andric                (Style.isVerilog() && Current.is(tok::pipe))) {
24145ffd83dbSDimitry Andric       Current.setType(determinePlusMinusCaretUsage(Current));
24150b57cec5SDimitry Andric       if (Current.is(TT_UnaryOperator) && Current.is(tok::caret))
24160b57cec5SDimitry Andric         Contexts.back().CaretFound = true;
24170b57cec5SDimitry Andric     } else if (Current.isOneOf(tok::minusminus, tok::plusplus)) {
24185ffd83dbSDimitry Andric       Current.setType(determineIncrementUsage(Current));
24190b57cec5SDimitry Andric     } else if (Current.isOneOf(tok::exclaim, tok::tilde)) {
24205ffd83dbSDimitry Andric       Current.setType(TT_UnaryOperator);
24210b57cec5SDimitry Andric     } else if (Current.is(tok::question)) {
24220eae32dcSDimitry Andric       if (Style.isJavaScript() && Line.MustBeDeclaration &&
24230eae32dcSDimitry Andric           !Contexts.back().IsExpression) {
24240b57cec5SDimitry Andric         // In JavaScript, `interface X { foo?(): bar; }` is an optional method
24250b57cec5SDimitry Andric         // on the interface, not a ternary expression.
24265ffd83dbSDimitry Andric         Current.setType(TT_JsTypeOptionalQuestion);
24270fca6ea1SDimitry Andric       } else if (Style.isTableGen()) {
24280fca6ea1SDimitry Andric         // In TableGen, '?' is just an identifier like token.
24290fca6ea1SDimitry Andric         Current.setType(TT_Unknown);
24300b57cec5SDimitry Andric       } else {
24315ffd83dbSDimitry Andric         Current.setType(TT_ConditionalExpr);
24320b57cec5SDimitry Andric       }
24330b57cec5SDimitry Andric     } else if (Current.isBinaryOperator() &&
24340b57cec5SDimitry Andric                (!Current.Previous || Current.Previous->isNot(tok::l_square)) &&
24355f757f3fSDimitry Andric                (Current.isNot(tok::greater) &&
24360b57cec5SDimitry Andric                 Style.Language != FormatStyle::LK_TextProto)) {
243706c3fb27SDimitry Andric       if (Style.isVerilog()) {
243806c3fb27SDimitry Andric         if (Current.is(tok::lessequal) && Contexts.size() == 1 &&
243906c3fb27SDimitry Andric             !Contexts.back().VerilogAssignmentFound) {
244006c3fb27SDimitry Andric           // In Verilog `<=` is assignment if in its own statement. It is a
244106c3fb27SDimitry Andric           // statement instead of an expression, that is it can not be chained.
244206c3fb27SDimitry Andric           Current.ForcedPrecedence = prec::Assignment;
244306c3fb27SDimitry Andric           Current.setFinalizedType(TT_BinaryOperator);
244406c3fb27SDimitry Andric         }
244506c3fb27SDimitry Andric         if (Current.getPrecedence() == prec::Assignment)
244606c3fb27SDimitry Andric           Contexts.back().VerilogAssignmentFound = true;
244706c3fb27SDimitry Andric       }
24485ffd83dbSDimitry Andric       Current.setType(TT_BinaryOperator);
24490b57cec5SDimitry Andric     } else if (Current.is(tok::comment)) {
24505f757f3fSDimitry Andric       if (Current.TokenText.starts_with("/*")) {
24515f757f3fSDimitry Andric         if (Current.TokenText.ends_with("*/")) {
24525ffd83dbSDimitry Andric           Current.setType(TT_BlockComment);
245381ad6265SDimitry Andric         } else {
24540b57cec5SDimitry Andric           // The lexer has for some reason determined a comment here. But we
24550b57cec5SDimitry Andric           // cannot really handle it, if it isn't properly terminated.
24560b57cec5SDimitry Andric           Current.Tok.setKind(tok::unknown);
245781ad6265SDimitry Andric         }
24580b57cec5SDimitry Andric       } else {
24595ffd83dbSDimitry Andric         Current.setType(TT_LineComment);
24600b57cec5SDimitry Andric       }
24615f757f3fSDimitry Andric     } else if (Current.is(tok::string_literal)) {
24625f757f3fSDimitry Andric       if (Style.isVerilog() && Contexts.back().VerilogMayBeConcatenation &&
24635f757f3fSDimitry Andric           Current.getPreviousNonComment() &&
24645f757f3fSDimitry Andric           Current.getPreviousNonComment()->isOneOf(tok::comma, tok::l_brace) &&
24655f757f3fSDimitry Andric           Current.getNextNonComment() &&
24665f757f3fSDimitry Andric           Current.getNextNonComment()->isOneOf(tok::comma, tok::r_brace)) {
24675f757f3fSDimitry Andric         Current.setType(TT_StringInConcatenation);
24685f757f3fSDimitry Andric       }
246981ad6265SDimitry Andric     } else if (Current.is(tok::l_paren)) {
247081ad6265SDimitry Andric       if (lParenStartsCppCast(Current))
247181ad6265SDimitry Andric         Current.setType(TT_CppCastLParen);
24720b57cec5SDimitry Andric     } else if (Current.is(tok::r_paren)) {
24730b57cec5SDimitry Andric       if (rParenEndsCast(Current))
24745ffd83dbSDimitry Andric         Current.setType(TT_CastRParen);
24750b57cec5SDimitry Andric       if (Current.MatchingParen && Current.Next &&
24760b57cec5SDimitry Andric           !Current.Next->isBinaryOperator() &&
24770fca6ea1SDimitry Andric           !Current.Next->isOneOf(
24780fca6ea1SDimitry Andric               tok::semi, tok::colon, tok::l_brace, tok::l_paren, tok::comma,
24790fca6ea1SDimitry Andric               tok::period, tok::arrow, tok::coloncolon, tok::kw_noexcept)) {
24805f757f3fSDimitry Andric         if (FormatToken *AfterParen = Current.MatchingParen->Next;
24815f757f3fSDimitry Andric             AfterParen && AfterParen->isNot(tok::caret)) {
24825f757f3fSDimitry Andric           // Make sure this isn't the return type of an Obj-C block declaration.
24835f757f3fSDimitry Andric           if (FormatToken *BeforeParen = Current.MatchingParen->Previous;
24845f757f3fSDimitry Andric               BeforeParen && BeforeParen->is(tok::identifier) &&
24855f757f3fSDimitry Andric               BeforeParen->isNot(TT_TypenameMacro) &&
24860b57cec5SDimitry Andric               BeforeParen->TokenText == BeforeParen->TokenText.upper() &&
24870b57cec5SDimitry Andric               (!BeforeParen->Previous ||
24885f757f3fSDimitry Andric                BeforeParen->Previous->ClosesTemplateDeclaration ||
24895f757f3fSDimitry Andric                BeforeParen->Previous->ClosesRequiresClause)) {
24905ffd83dbSDimitry Andric             Current.setType(TT_FunctionAnnotationRParen);
24910b57cec5SDimitry Andric           }
24920b57cec5SDimitry Andric         }
249381ad6265SDimitry Andric       }
24940eae32dcSDimitry Andric     } else if (Current.is(tok::at) && Current.Next && !Style.isJavaScript() &&
24950b57cec5SDimitry Andric                Style.Language != FormatStyle::LK_Java) {
24960b57cec5SDimitry Andric       // In Java & JavaScript, "@..." is a decorator or annotation. In ObjC, it
24970b57cec5SDimitry Andric       // marks declarations and properties that need special formatting.
24980b57cec5SDimitry Andric       switch (Current.Next->Tok.getObjCKeywordID()) {
24990b57cec5SDimitry Andric       case tok::objc_interface:
25000b57cec5SDimitry Andric       case tok::objc_implementation:
25010b57cec5SDimitry Andric       case tok::objc_protocol:
25025ffd83dbSDimitry Andric         Current.setType(TT_ObjCDecl);
25030b57cec5SDimitry Andric         break;
25040b57cec5SDimitry Andric       case tok::objc_property:
25055ffd83dbSDimitry Andric         Current.setType(TT_ObjCProperty);
25060b57cec5SDimitry Andric         break;
25070b57cec5SDimitry Andric       default:
25080b57cec5SDimitry Andric         break;
25090b57cec5SDimitry Andric       }
25100b57cec5SDimitry Andric     } else if (Current.is(tok::period)) {
25110b57cec5SDimitry Andric       FormatToken *PreviousNoComment = Current.getPreviousNonComment();
25120b57cec5SDimitry Andric       if (PreviousNoComment &&
251381ad6265SDimitry Andric           PreviousNoComment->isOneOf(tok::comma, tok::l_brace)) {
25145ffd83dbSDimitry Andric         Current.setType(TT_DesignatedInitializerPeriod);
251581ad6265SDimitry Andric       } else if (Style.Language == FormatStyle::LK_Java && Current.Previous &&
25160b57cec5SDimitry Andric                  Current.Previous->isOneOf(TT_JavaAnnotation,
25170b57cec5SDimitry Andric                                            TT_LeadingJavaAnnotation)) {
25185ffd83dbSDimitry Andric         Current.setType(Current.Previous->getType());
25190b57cec5SDimitry Andric       }
25200b57cec5SDimitry Andric     } else if (canBeObjCSelectorComponent(Current) &&
25210b57cec5SDimitry Andric                // FIXME(bug 36976): ObjC return types shouldn't use
25220b57cec5SDimitry Andric                // TT_CastRParen.
25230b57cec5SDimitry Andric                Current.Previous && Current.Previous->is(TT_CastRParen) &&
25240b57cec5SDimitry Andric                Current.Previous->MatchingParen &&
25250b57cec5SDimitry Andric                Current.Previous->MatchingParen->Previous &&
25260b57cec5SDimitry Andric                Current.Previous->MatchingParen->Previous->is(
25270b57cec5SDimitry Andric                    TT_ObjCMethodSpecifier)) {
25280b57cec5SDimitry Andric       // This is the first part of an Objective-C selector name. (If there's no
25290b57cec5SDimitry Andric       // colon after this, this is the only place which annotates the identifier
25300b57cec5SDimitry Andric       // as a selector.)
25315ffd83dbSDimitry Andric       Current.setType(TT_SelectorName);
2532e8d8bef9SDimitry Andric     } else if (Current.isOneOf(tok::identifier, tok::kw_const, tok::kw_noexcept,
2533e8d8bef9SDimitry Andric                                tok::kw_requires) &&
25340b57cec5SDimitry Andric                Current.Previous &&
2535bdd1243dSDimitry Andric                !Current.Previous->isOneOf(tok::equal, tok::at,
2536bdd1243dSDimitry Andric                                           TT_CtorInitializerComma,
2537bdd1243dSDimitry Andric                                           TT_CtorInitializerColon) &&
25380b57cec5SDimitry Andric                Line.MightBeFunctionDecl && Contexts.size() == 1) {
25390b57cec5SDimitry Andric       // Line.MightBeFunctionDecl can only be true after the parentheses of a
25400b57cec5SDimitry Andric       // function declaration have been found.
25415ffd83dbSDimitry Andric       Current.setType(TT_TrailingAnnotation);
25420b57cec5SDimitry Andric     } else if ((Style.Language == FormatStyle::LK_Java ||
25430eae32dcSDimitry Andric                 Style.isJavaScript()) &&
25440b57cec5SDimitry Andric                Current.Previous) {
25450b57cec5SDimitry Andric       if (Current.Previous->is(tok::at) &&
25460b57cec5SDimitry Andric           Current.isNot(Keywords.kw_interface)) {
25470b57cec5SDimitry Andric         const FormatToken &AtToken = *Current.Previous;
25480b57cec5SDimitry Andric         const FormatToken *Previous = AtToken.getPreviousNonComment();
25490b57cec5SDimitry Andric         if (!Previous || Previous->is(TT_LeadingJavaAnnotation))
25505ffd83dbSDimitry Andric           Current.setType(TT_LeadingJavaAnnotation);
25510b57cec5SDimitry Andric         else
25525ffd83dbSDimitry Andric           Current.setType(TT_JavaAnnotation);
25530b57cec5SDimitry Andric       } else if (Current.Previous->is(tok::period) &&
25540b57cec5SDimitry Andric                  Current.Previous->isOneOf(TT_JavaAnnotation,
25550b57cec5SDimitry Andric                                            TT_LeadingJavaAnnotation)) {
25565ffd83dbSDimitry Andric         Current.setType(Current.Previous->getType());
25570b57cec5SDimitry Andric       }
25580b57cec5SDimitry Andric     }
25590b57cec5SDimitry Andric   }
25600b57cec5SDimitry Andric 
25610b57cec5SDimitry Andric   /// Take a guess at whether \p Tok starts a name of a function or
25620b57cec5SDimitry Andric   /// variable declaration.
25630b57cec5SDimitry Andric   ///
25640b57cec5SDimitry Andric   /// This is a heuristic based on whether \p Tok is an identifier following
25650b57cec5SDimitry Andric   /// something that is likely a type.
25660b57cec5SDimitry Andric   bool isStartOfName(const FormatToken &Tok) {
256706c3fb27SDimitry Andric     // Handled in ExpressionParser for Verilog.
256806c3fb27SDimitry Andric     if (Style.isVerilog())
256906c3fb27SDimitry Andric       return false;
257006c3fb27SDimitry Andric 
25710b57cec5SDimitry Andric     if (Tok.isNot(tok::identifier) || !Tok.Previous)
25720b57cec5SDimitry Andric       return false;
25730b57cec5SDimitry Andric 
25745f757f3fSDimitry Andric     if (const auto *NextNonComment = Tok.getNextNonComment();
25755f757f3fSDimitry Andric         (!NextNonComment && !Line.InMacroBody) ||
25765f757f3fSDimitry Andric         (NextNonComment &&
25775f757f3fSDimitry Andric          (NextNonComment->isPointerOrReference() ||
25787a6dacacSDimitry Andric           NextNonComment->is(tok::string_literal) ||
25797a6dacacSDimitry Andric           (Line.InPragmaDirective && NextNonComment->is(tok::identifier))))) {
25805f757f3fSDimitry Andric       return false;
25815f757f3fSDimitry Andric     }
25825f757f3fSDimitry Andric 
25830b57cec5SDimitry Andric     if (Tok.Previous->isOneOf(TT_LeadingJavaAnnotation, Keywords.kw_instanceof,
258481ad6265SDimitry Andric                               Keywords.kw_as)) {
25850b57cec5SDimitry Andric       return false;
258681ad6265SDimitry Andric     }
25870eae32dcSDimitry Andric     if (Style.isJavaScript() && Tok.Previous->is(Keywords.kw_in))
25880b57cec5SDimitry Andric       return false;
25890b57cec5SDimitry Andric 
25900b57cec5SDimitry Andric     // Skip "const" as it does not have an influence on whether this is a name.
25910b57cec5SDimitry Andric     FormatToken *PreviousNotConst = Tok.getPreviousNonComment();
25920eae32dcSDimitry Andric 
25930eae32dcSDimitry Andric     // For javascript const can be like "let" or "var"
25940eae32dcSDimitry Andric     if (!Style.isJavaScript())
25950b57cec5SDimitry Andric       while (PreviousNotConst && PreviousNotConst->is(tok::kw_const))
25960b57cec5SDimitry Andric         PreviousNotConst = PreviousNotConst->getPreviousNonComment();
25970b57cec5SDimitry Andric 
25980b57cec5SDimitry Andric     if (!PreviousNotConst)
25990b57cec5SDimitry Andric       return false;
26000b57cec5SDimitry Andric 
260181ad6265SDimitry Andric     if (PreviousNotConst->ClosesRequiresClause)
260281ad6265SDimitry Andric       return false;
260381ad6265SDimitry Andric 
26047a6dacacSDimitry Andric     if (Style.isTableGen()) {
26057a6dacacSDimitry Andric       // keywords such as let and def* defines names.
26067a6dacacSDimitry Andric       if (Keywords.isTableGenDefinition(*PreviousNotConst))
26077a6dacacSDimitry Andric         return true;
26080fca6ea1SDimitry Andric       // Otherwise C++ style declarations is available only inside the brace.
26090fca6ea1SDimitry Andric       if (Contexts.back().ContextKind != tok::l_brace)
26100fca6ea1SDimitry Andric         return false;
26117a6dacacSDimitry Andric     }
26127a6dacacSDimitry Andric 
26130b57cec5SDimitry Andric     bool IsPPKeyword = PreviousNotConst->is(tok::identifier) &&
26140b57cec5SDimitry Andric                        PreviousNotConst->Previous &&
26150b57cec5SDimitry Andric                        PreviousNotConst->Previous->is(tok::hash);
26160b57cec5SDimitry Andric 
261781ad6265SDimitry Andric     if (PreviousNotConst->is(TT_TemplateCloser)) {
26180b57cec5SDimitry Andric       return PreviousNotConst && PreviousNotConst->MatchingParen &&
26190b57cec5SDimitry Andric              PreviousNotConst->MatchingParen->Previous &&
26200b57cec5SDimitry Andric              PreviousNotConst->MatchingParen->Previous->isNot(tok::period) &&
26210b57cec5SDimitry Andric              PreviousNotConst->MatchingParen->Previous->isNot(tok::kw_template);
262281ad6265SDimitry Andric     }
26230b57cec5SDimitry Andric 
26245f757f3fSDimitry Andric     if ((PreviousNotConst->is(tok::r_paren) &&
26255f757f3fSDimitry Andric          PreviousNotConst->is(TT_TypeDeclarationParen)) ||
26265f757f3fSDimitry Andric         PreviousNotConst->is(TT_AttributeRParen)) {
26270b57cec5SDimitry Andric       return true;
262881ad6265SDimitry Andric     }
26290b57cec5SDimitry Andric 
26300eae32dcSDimitry Andric     // If is a preprocess keyword like #define.
26310eae32dcSDimitry Andric     if (IsPPKeyword)
26320eae32dcSDimitry Andric       return false;
26330eae32dcSDimitry Andric 
26340eae32dcSDimitry Andric     // int a or auto a.
26350fca6ea1SDimitry Andric     if (PreviousNotConst->isOneOf(tok::identifier, tok::kw_auto) &&
26360fca6ea1SDimitry Andric         PreviousNotConst->isNot(TT_StatementAttributeLikeMacro)) {
26370eae32dcSDimitry Andric       return true;
26380fca6ea1SDimitry Andric     }
26390eae32dcSDimitry Andric 
26400eae32dcSDimitry Andric     // *a or &a or &&a.
26410eae32dcSDimitry Andric     if (PreviousNotConst->is(TT_PointerOrReference))
26420eae32dcSDimitry Andric       return true;
26430eae32dcSDimitry Andric 
26440eae32dcSDimitry Andric     // MyClass a;
26450fca6ea1SDimitry Andric     if (PreviousNotConst->isTypeName(LangOpts))
26460eae32dcSDimitry Andric       return true;
26470eae32dcSDimitry Andric 
2648bdd1243dSDimitry Andric     // type[] a in Java
2649bdd1243dSDimitry Andric     if (Style.Language == FormatStyle::LK_Java &&
2650bdd1243dSDimitry Andric         PreviousNotConst->is(tok::r_square)) {
2651bdd1243dSDimitry Andric       return true;
2652bdd1243dSDimitry Andric     }
2653bdd1243dSDimitry Andric 
26540eae32dcSDimitry Andric     // const a = in JavaScript.
265581ad6265SDimitry Andric     return Style.isJavaScript() && PreviousNotConst->is(tok::kw_const);
265681ad6265SDimitry Andric   }
265781ad6265SDimitry Andric 
265881ad6265SDimitry Andric   /// Determine whether '(' is starting a C++ cast.
265981ad6265SDimitry Andric   bool lParenStartsCppCast(const FormatToken &Tok) {
266081ad6265SDimitry Andric     // C-style casts are only used in C++.
26610fca6ea1SDimitry Andric     if (!IsCpp)
266281ad6265SDimitry Andric       return false;
266381ad6265SDimitry Andric 
266481ad6265SDimitry Andric     FormatToken *LeftOfParens = Tok.getPreviousNonComment();
266581ad6265SDimitry Andric     if (LeftOfParens && LeftOfParens->is(TT_TemplateCloser) &&
266681ad6265SDimitry Andric         LeftOfParens->MatchingParen) {
266781ad6265SDimitry Andric       auto *Prev = LeftOfParens->MatchingParen->getPreviousNonComment();
266881ad6265SDimitry Andric       if (Prev &&
266981ad6265SDimitry Andric           Prev->isOneOf(tok::kw_const_cast, tok::kw_dynamic_cast,
267081ad6265SDimitry Andric                         tok::kw_reinterpret_cast, tok::kw_static_cast)) {
267181ad6265SDimitry Andric         // FIXME: Maybe we should handle identifiers ending with "_cast",
267281ad6265SDimitry Andric         // e.g. any_cast?
267381ad6265SDimitry Andric         return true;
267481ad6265SDimitry Andric       }
267581ad6265SDimitry Andric     }
267681ad6265SDimitry Andric     return false;
26770b57cec5SDimitry Andric   }
26780b57cec5SDimitry Andric 
26790b57cec5SDimitry Andric   /// Determine whether ')' is ending a cast.
26800b57cec5SDimitry Andric   bool rParenEndsCast(const FormatToken &Tok) {
26810fca6ea1SDimitry Andric     assert(Tok.is(tok::r_paren));
26820fca6ea1SDimitry Andric 
26830fca6ea1SDimitry Andric     if (!Tok.MatchingParen || !Tok.Previous)
26840b57cec5SDimitry Andric       return false;
26850fca6ea1SDimitry Andric 
26860fca6ea1SDimitry Andric     // C-style casts are only used in C++, C# and Java.
26870fca6ea1SDimitry Andric     if (!IsCpp && !Style.isCSharp() && Style.Language != FormatStyle::LK_Java)
26880fca6ea1SDimitry Andric       return false;
26890fca6ea1SDimitry Andric 
26900fca6ea1SDimitry Andric     const auto *LParen = Tok.MatchingParen;
26910fca6ea1SDimitry Andric     const auto *BeforeRParen = Tok.Previous;
26920fca6ea1SDimitry Andric     const auto *AfterRParen = Tok.Next;
26930b57cec5SDimitry Andric 
26940b57cec5SDimitry Andric     // Empty parens aren't casts and there are no casts at the end of the line.
26950fca6ea1SDimitry Andric     if (BeforeRParen == LParen || !AfterRParen)
26960b57cec5SDimitry Andric       return false;
26970b57cec5SDimitry Andric 
26980fca6ea1SDimitry Andric     if (LParen->is(TT_OverloadedOperatorLParen))
2699bdd1243dSDimitry Andric       return false;
2700bdd1243dSDimitry Andric 
27010fca6ea1SDimitry Andric     auto *LeftOfParens = LParen->getPreviousNonComment();
27020b57cec5SDimitry Andric     if (LeftOfParens) {
270304eeddc0SDimitry Andric       // If there is a closing parenthesis left of the current
270404eeddc0SDimitry Andric       // parentheses, look past it as these might be chained casts.
270504eeddc0SDimitry Andric       if (LeftOfParens->is(tok::r_paren) &&
270604eeddc0SDimitry Andric           LeftOfParens->isNot(TT_CastRParen)) {
27070b57cec5SDimitry Andric         if (!LeftOfParens->MatchingParen ||
270881ad6265SDimitry Andric             !LeftOfParens->MatchingParen->Previous) {
27090b57cec5SDimitry Andric           return false;
271081ad6265SDimitry Andric         }
27110b57cec5SDimitry Andric         LeftOfParens = LeftOfParens->MatchingParen->Previous;
27120b57cec5SDimitry Andric       }
27130b57cec5SDimitry Andric 
271481ad6265SDimitry Andric       if (LeftOfParens->is(tok::r_square)) {
271581ad6265SDimitry Andric         //   delete[] (void *)ptr;
271681ad6265SDimitry Andric         auto MayBeArrayDelete = [](FormatToken *Tok) -> FormatToken * {
271781ad6265SDimitry Andric           if (Tok->isNot(tok::r_square))
271881ad6265SDimitry Andric             return nullptr;
271981ad6265SDimitry Andric 
272081ad6265SDimitry Andric           Tok = Tok->getPreviousNonComment();
272181ad6265SDimitry Andric           if (!Tok || Tok->isNot(tok::l_square))
272281ad6265SDimitry Andric             return nullptr;
272381ad6265SDimitry Andric 
272481ad6265SDimitry Andric           Tok = Tok->getPreviousNonComment();
272581ad6265SDimitry Andric           if (!Tok || Tok->isNot(tok::kw_delete))
272681ad6265SDimitry Andric             return nullptr;
272781ad6265SDimitry Andric           return Tok;
272881ad6265SDimitry Andric         };
272981ad6265SDimitry Andric         if (FormatToken *MaybeDelete = MayBeArrayDelete(LeftOfParens))
273081ad6265SDimitry Andric           LeftOfParens = MaybeDelete;
273181ad6265SDimitry Andric       }
273281ad6265SDimitry Andric 
273304eeddc0SDimitry Andric       // The Condition directly below this one will see the operator arguments
273404eeddc0SDimitry Andric       // as a (void *foo) cast.
273504eeddc0SDimitry Andric       //   void operator delete(void *foo) ATTRIB;
273604eeddc0SDimitry Andric       if (LeftOfParens->Tok.getIdentifierInfo() && LeftOfParens->Previous &&
273781ad6265SDimitry Andric           LeftOfParens->Previous->is(tok::kw_operator)) {
273804eeddc0SDimitry Andric         return false;
273981ad6265SDimitry Andric       }
274004eeddc0SDimitry Andric 
27410b57cec5SDimitry Andric       // If there is an identifier (or with a few exceptions a keyword) right
27420b57cec5SDimitry Andric       // before the parentheses, this is unlikely to be a cast.
27430b57cec5SDimitry Andric       if (LeftOfParens->Tok.getIdentifierInfo() &&
27440b57cec5SDimitry Andric           !LeftOfParens->isOneOf(Keywords.kw_in, tok::kw_return, tok::kw_case,
2745bdd1243dSDimitry Andric                                  tok::kw_delete, tok::kw_throw)) {
27460b57cec5SDimitry Andric         return false;
274781ad6265SDimitry Andric       }
27480b57cec5SDimitry Andric 
27490b57cec5SDimitry Andric       // Certain other tokens right before the parentheses are also signals that
27500b57cec5SDimitry Andric       // this cannot be a cast.
27510b57cec5SDimitry Andric       if (LeftOfParens->isOneOf(tok::at, tok::r_square, TT_OverloadedOperator,
275281ad6265SDimitry Andric                                 TT_TemplateCloser, tok::ellipsis)) {
27530b57cec5SDimitry Andric         return false;
27540b57cec5SDimitry Andric       }
275581ad6265SDimitry Andric     }
27560b57cec5SDimitry Andric 
27570fca6ea1SDimitry Andric     if (AfterRParen->is(tok::question) ||
27580fca6ea1SDimitry Andric         (AfterRParen->is(tok::ampamp) && !BeforeRParen->isTypeName(LangOpts))) {
27590b57cec5SDimitry Andric       return false;
27600fca6ea1SDimitry Andric     }
27610b57cec5SDimitry Andric 
27625ffd83dbSDimitry Andric     // `foreach((A a, B b) in someList)` should not be seen as a cast.
27630fca6ea1SDimitry Andric     if (AfterRParen->is(Keywords.kw_in) && Style.isCSharp())
27645ffd83dbSDimitry Andric       return false;
27655ffd83dbSDimitry Andric 
2766a7dea167SDimitry Andric     // Functions which end with decorations like volatile, noexcept are unlikely
2767a7dea167SDimitry Andric     // to be casts.
27680fca6ea1SDimitry Andric     if (AfterRParen->isOneOf(tok::kw_noexcept, tok::kw_volatile, tok::kw_const,
2769e8d8bef9SDimitry Andric                              tok::kw_requires, tok::kw_throw, tok::arrow,
2770e8d8bef9SDimitry Andric                              Keywords.kw_override, Keywords.kw_final) ||
27710fca6ea1SDimitry Andric         isCppAttribute(IsCpp, *AfterRParen)) {
2772a7dea167SDimitry Andric       return false;
277381ad6265SDimitry Andric     }
2774a7dea167SDimitry Andric 
27750b57cec5SDimitry Andric     // As Java has no function types, a "(" after the ")" likely means that this
27760b57cec5SDimitry Andric     // is a cast.
27770fca6ea1SDimitry Andric     if (Style.Language == FormatStyle::LK_Java && AfterRParen->is(tok::l_paren))
27780b57cec5SDimitry Andric       return true;
27790b57cec5SDimitry Andric 
27800b57cec5SDimitry Andric     // If a (non-string) literal follows, this is likely a cast.
27810fca6ea1SDimitry Andric     if (AfterRParen->isOneOf(tok::kw_sizeof, tok::kw_alignof) ||
27820fca6ea1SDimitry Andric         (AfterRParen->Tok.isLiteral() &&
27830fca6ea1SDimitry Andric          AfterRParen->isNot(tok::string_literal))) {
27840b57cec5SDimitry Andric       return true;
278581ad6265SDimitry Andric     }
27860b57cec5SDimitry Andric 
27870b57cec5SDimitry Andric     // Heuristically try to determine whether the parentheses contain a type.
27880fca6ea1SDimitry Andric     auto IsQualifiedPointerOrReference = [](const FormatToken *T,
27890fca6ea1SDimitry Andric                                             const LangOptions &LangOpts) {
2790e8d8bef9SDimitry Andric       // This is used to handle cases such as x = (foo *const)&y;
27910fca6ea1SDimitry Andric       assert(!T->isTypeName(LangOpts) && "Should have already been checked");
2792e8d8bef9SDimitry Andric       // Strip trailing qualifiers such as const or volatile when checking
2793e8d8bef9SDimitry Andric       // whether the parens could be a cast to a pointer/reference type.
2794e8d8bef9SDimitry Andric       while (T) {
27955f757f3fSDimitry Andric         if (T->is(TT_AttributeRParen)) {
2796e8d8bef9SDimitry Andric           // Handle `x = (foo *__attribute__((foo)))&v;`:
27975f757f3fSDimitry Andric           assert(T->is(tok::r_paren));
27985f757f3fSDimitry Andric           assert(T->MatchingParen);
27995f757f3fSDimitry Andric           assert(T->MatchingParen->is(tok::l_paren));
28005f757f3fSDimitry Andric           assert(T->MatchingParen->is(TT_AttributeLParen));
28015f757f3fSDimitry Andric           if (const auto *Tok = T->MatchingParen->Previous;
28025f757f3fSDimitry Andric               Tok && Tok->isAttribute()) {
28035f757f3fSDimitry Andric             T = Tok->Previous;
2804e8d8bef9SDimitry Andric             continue;
2805e8d8bef9SDimitry Andric           }
2806e8d8bef9SDimitry Andric         } else if (T->is(TT_AttributeSquare)) {
2807e8d8bef9SDimitry Andric           // Handle `x = (foo *[[clang::foo]])&v;`:
2808e8d8bef9SDimitry Andric           if (T->MatchingParen && T->MatchingParen->Previous) {
2809e8d8bef9SDimitry Andric             T = T->MatchingParen->Previous;
2810e8d8bef9SDimitry Andric             continue;
2811e8d8bef9SDimitry Andric           }
2812e8d8bef9SDimitry Andric         } else if (T->canBePointerOrReferenceQualifier()) {
2813e8d8bef9SDimitry Andric           T = T->Previous;
2814e8d8bef9SDimitry Andric           continue;
2815e8d8bef9SDimitry Andric         }
2816e8d8bef9SDimitry Andric         break;
2817e8d8bef9SDimitry Andric       }
2818e8d8bef9SDimitry Andric       return T && T->is(TT_PointerOrReference);
2819e8d8bef9SDimitry Andric     };
28200b57cec5SDimitry Andric     bool ParensAreType =
28210fca6ea1SDimitry Andric         BeforeRParen->isOneOf(TT_TemplateCloser, TT_TypeDeclarationParen) ||
28220fca6ea1SDimitry Andric         BeforeRParen->isTypeName(LangOpts) ||
28230fca6ea1SDimitry Andric         IsQualifiedPointerOrReference(BeforeRParen, LangOpts);
28240b57cec5SDimitry Andric     bool ParensCouldEndDecl =
28250fca6ea1SDimitry Andric         AfterRParen->isOneOf(tok::equal, tok::semi, tok::l_brace, tok::greater);
28260b57cec5SDimitry Andric     if (ParensAreType && !ParensCouldEndDecl)
28270b57cec5SDimitry Andric       return true;
28280b57cec5SDimitry Andric 
28290b57cec5SDimitry Andric     // At this point, we heuristically assume that there are no casts at the
28300b57cec5SDimitry Andric     // start of the line. We assume that we have found most cases where there
28310b57cec5SDimitry Andric     // are by the logic above, e.g. "(void)x;".
28320b57cec5SDimitry Andric     if (!LeftOfParens)
28330b57cec5SDimitry Andric       return false;
28340b57cec5SDimitry Andric 
28350b57cec5SDimitry Andric     // Certain token types inside the parentheses mean that this can't be a
28360b57cec5SDimitry Andric     // cast.
28370fca6ea1SDimitry Andric     for (const auto *Token = LParen->Next; Token != &Tok; Token = Token->Next)
28380b57cec5SDimitry Andric       if (Token->is(TT_BinaryOperator))
28390b57cec5SDimitry Andric         return false;
28400b57cec5SDimitry Andric 
28410b57cec5SDimitry Andric     // If the following token is an identifier or 'this', this is a cast. All
28420b57cec5SDimitry Andric     // cases where this can be something else are handled above.
28430fca6ea1SDimitry Andric     if (AfterRParen->isOneOf(tok::identifier, tok::kw_this))
28440b57cec5SDimitry Andric       return true;
28450b57cec5SDimitry Andric 
284623408297SDimitry Andric     // Look for a cast `( x ) (`.
28470fca6ea1SDimitry Andric     if (AfterRParen->is(tok::l_paren) && BeforeRParen->Previous) {
28480fca6ea1SDimitry Andric       if (BeforeRParen->is(tok::identifier) &&
28490fca6ea1SDimitry Andric           BeforeRParen->Previous->is(tok::l_paren)) {
2850e8d8bef9SDimitry Andric         return true;
285123408297SDimitry Andric       }
285281ad6265SDimitry Andric     }
2853e8d8bef9SDimitry Andric 
28540fca6ea1SDimitry Andric     if (!AfterRParen->Next)
28550b57cec5SDimitry Andric       return false;
28560b57cec5SDimitry Andric 
28570fca6ea1SDimitry Andric     if (AfterRParen->is(tok::l_brace) &&
28580fca6ea1SDimitry Andric         AfterRParen->getBlockKind() == BK_BracedInit) {
28590fca6ea1SDimitry Andric       return true;
28600fca6ea1SDimitry Andric     }
28610fca6ea1SDimitry Andric 
28620b57cec5SDimitry Andric     // If the next token after the parenthesis is a unary operator, assume
28630b57cec5SDimitry Andric     // that this is cast, unless there are unexpected tokens inside the
28640b57cec5SDimitry Andric     // parenthesis.
28650fca6ea1SDimitry Andric     const bool NextIsAmpOrStar = AfterRParen->isOneOf(tok::amp, tok::star);
28660fca6ea1SDimitry Andric     if (!(AfterRParen->isUnaryOperator() || NextIsAmpOrStar) ||
28670fca6ea1SDimitry Andric         AfterRParen->is(tok::plus) ||
28680fca6ea1SDimitry Andric         !AfterRParen->Next->isOneOf(tok::identifier, tok::numeric_constant)) {
28690b57cec5SDimitry Andric       return false;
287081ad6265SDimitry Andric     }
28710fca6ea1SDimitry Andric 
287206c3fb27SDimitry Andric     if (NextIsAmpOrStar &&
28730fca6ea1SDimitry Andric         (AfterRParen->Next->is(tok::numeric_constant) || Line.InPPDirective)) {
287406c3fb27SDimitry Andric       return false;
287506c3fb27SDimitry Andric     }
28760fca6ea1SDimitry Andric 
28770fca6ea1SDimitry Andric     if (Line.InPPDirective && AfterRParen->is(tok::minus))
2878b3edf446SDimitry Andric       return false;
28790fca6ea1SDimitry Andric 
28800b57cec5SDimitry Andric     // Search for unexpected tokens.
288162987288SDimitry Andric     for (auto *Prev = BeforeRParen; Prev != LParen; Prev = Prev->Previous) {
288262987288SDimitry Andric       if (Prev->is(tok::r_paren)) {
28836c4b055cSDimitry Andric         if (Prev->is(TT_CastRParen))
28846c4b055cSDimitry Andric           return false;
288562987288SDimitry Andric         Prev = Prev->MatchingParen;
288662987288SDimitry Andric         if (!Prev)
288762987288SDimitry Andric           return false;
288862987288SDimitry Andric         if (Prev->is(TT_FunctionTypeLParen))
288962987288SDimitry Andric           break;
289062987288SDimitry Andric         continue;
289162987288SDimitry Andric       }
28920b57cec5SDimitry Andric       if (!Prev->isOneOf(tok::kw_const, tok::identifier, tok::coloncolon))
28930b57cec5SDimitry Andric         return false;
289462987288SDimitry Andric     }
28950fca6ea1SDimitry Andric 
28960b57cec5SDimitry Andric     return true;
28970b57cec5SDimitry Andric   }
28980b57cec5SDimitry Andric 
289981ad6265SDimitry Andric   /// Returns true if the token is used as a unary operator.
290081ad6265SDimitry Andric   bool determineUnaryOperatorByUsage(const FormatToken &Tok) {
290181ad6265SDimitry Andric     const FormatToken *PrevToken = Tok.getPreviousNonComment();
290281ad6265SDimitry Andric     if (!PrevToken)
290381ad6265SDimitry Andric       return true;
290481ad6265SDimitry Andric 
290581ad6265SDimitry Andric     // These keywords are deliberately not included here because they may
290681ad6265SDimitry Andric     // precede only one of unary star/amp and plus/minus but not both.  They are
290781ad6265SDimitry Andric     // either included in determineStarAmpUsage or determinePlusMinusCaretUsage.
290881ad6265SDimitry Andric     //
290981ad6265SDimitry Andric     // @ - It may be followed by a unary `-` in Objective-C literals. We don't
291081ad6265SDimitry Andric     //   know how they can be followed by a star or amp.
291181ad6265SDimitry Andric     if (PrevToken->isOneOf(
291281ad6265SDimitry Andric             TT_ConditionalExpr, tok::l_paren, tok::comma, tok::colon, tok::semi,
291381ad6265SDimitry Andric             tok::equal, tok::question, tok::l_square, tok::l_brace,
291481ad6265SDimitry Andric             tok::kw_case, tok::kw_co_await, tok::kw_co_return, tok::kw_co_yield,
291581ad6265SDimitry Andric             tok::kw_delete, tok::kw_return, tok::kw_throw)) {
291681ad6265SDimitry Andric       return true;
291781ad6265SDimitry Andric     }
291881ad6265SDimitry Andric 
291981ad6265SDimitry Andric     // We put sizeof here instead of only in determineStarAmpUsage. In the cases
292081ad6265SDimitry Andric     // where the unary `+` operator is overloaded, it is reasonable to write
292181ad6265SDimitry Andric     // things like `sizeof +x`. Like commit 446d6ec996c6c3.
292281ad6265SDimitry Andric     if (PrevToken->is(tok::kw_sizeof))
292381ad6265SDimitry Andric       return true;
292481ad6265SDimitry Andric 
292581ad6265SDimitry Andric     // A sequence of leading unary operators.
292681ad6265SDimitry Andric     if (PrevToken->isOneOf(TT_CastRParen, TT_UnaryOperator))
292781ad6265SDimitry Andric       return true;
292881ad6265SDimitry Andric 
292981ad6265SDimitry Andric     // There can't be two consecutive binary operators.
293081ad6265SDimitry Andric     if (PrevToken->is(TT_BinaryOperator))
293181ad6265SDimitry Andric       return true;
293281ad6265SDimitry Andric 
293381ad6265SDimitry Andric     return false;
293481ad6265SDimitry Andric   }
293581ad6265SDimitry Andric 
29360b57cec5SDimitry Andric   /// Return the type of the given token assuming it is * or &.
29370b57cec5SDimitry Andric   TokenType determineStarAmpUsage(const FormatToken &Tok, bool IsExpression,
29380b57cec5SDimitry Andric                                   bool InTemplateArgument) {
29390eae32dcSDimitry Andric     if (Style.isJavaScript())
29400b57cec5SDimitry Andric       return TT_BinaryOperator;
29410b57cec5SDimitry Andric 
29425ffd83dbSDimitry Andric     // && in C# must be a binary operator.
29435ffd83dbSDimitry Andric     if (Style.isCSharp() && Tok.is(tok::ampamp))
29445ffd83dbSDimitry Andric       return TT_BinaryOperator;
29455ffd83dbSDimitry Andric 
294606c3fb27SDimitry Andric     if (Style.isVerilog()) {
294706c3fb27SDimitry Andric       // In Verilog, `*` can only be a binary operator.  `&` can be either unary
294806c3fb27SDimitry Andric       // or binary.  `*` also includes `*>` in module path declarations in
294906c3fb27SDimitry Andric       // specify blocks because merged tokens take the type of the first one by
295006c3fb27SDimitry Andric       // default.
295106c3fb27SDimitry Andric       if (Tok.is(tok::star))
295206c3fb27SDimitry Andric         return TT_BinaryOperator;
295306c3fb27SDimitry Andric       return determineUnaryOperatorByUsage(Tok) ? TT_UnaryOperator
295406c3fb27SDimitry Andric                                                 : TT_BinaryOperator;
295506c3fb27SDimitry Andric     }
295606c3fb27SDimitry Andric 
29570b57cec5SDimitry Andric     const FormatToken *PrevToken = Tok.getPreviousNonComment();
29580b57cec5SDimitry Andric     if (!PrevToken)
29590b57cec5SDimitry Andric       return TT_UnaryOperator;
296006c3fb27SDimitry Andric     if (PrevToken->is(TT_TypeName))
296106c3fb27SDimitry Andric       return TT_PointerOrReference;
29620fca6ea1SDimitry Andric     if (PrevToken->isOneOf(tok::kw_new, tok::kw_delete) && Tok.is(tok::ampamp))
29630fca6ea1SDimitry Andric       return TT_BinaryOperator;
29640b57cec5SDimitry Andric 
29650b57cec5SDimitry Andric     const FormatToken *NextToken = Tok.getNextNonComment();
296681ad6265SDimitry Andric 
296781ad6265SDimitry Andric     if (InTemplateArgument && NextToken && NextToken->is(tok::kw_noexcept))
296881ad6265SDimitry Andric       return TT_BinaryOperator;
296981ad6265SDimitry Andric 
29700b57cec5SDimitry Andric     if (!NextToken ||
29715f757f3fSDimitry Andric         NextToken->isOneOf(tok::arrow, tok::equal, tok::comma, tok::r_paren,
29725f757f3fSDimitry Andric                            TT_RequiresClause) ||
29735f757f3fSDimitry Andric         (NextToken->is(tok::kw_noexcept) && !IsExpression) ||
2974e8d8bef9SDimitry Andric         NextToken->canBePointerOrReferenceQualifier() ||
297581ad6265SDimitry Andric         (NextToken->is(tok::l_brace) && !NextToken->getNextNonComment())) {
29760b57cec5SDimitry Andric       return TT_PointerOrReference;
297781ad6265SDimitry Andric     }
29780b57cec5SDimitry Andric 
29790b57cec5SDimitry Andric     if (PrevToken->is(tok::coloncolon))
29800b57cec5SDimitry Andric       return TT_PointerOrReference;
29810b57cec5SDimitry Andric 
2982e8d8bef9SDimitry Andric     if (PrevToken->is(tok::r_paren) && PrevToken->is(TT_TypeDeclarationParen))
2983e8d8bef9SDimitry Andric       return TT_PointerOrReference;
2984e8d8bef9SDimitry Andric 
298581ad6265SDimitry Andric     if (determineUnaryOperatorByUsage(Tok))
29860b57cec5SDimitry Andric       return TT_UnaryOperator;
29870b57cec5SDimitry Andric 
29880b57cec5SDimitry Andric     if (NextToken->is(tok::l_square) && NextToken->isNot(TT_LambdaLSquare))
29890b57cec5SDimitry Andric       return TT_PointerOrReference;
29900b57cec5SDimitry Andric     if (NextToken->is(tok::kw_operator) && !IsExpression)
29910b57cec5SDimitry Andric       return TT_PointerOrReference;
29920b57cec5SDimitry Andric     if (NextToken->isOneOf(tok::comma, tok::semi))
29930b57cec5SDimitry Andric       return TT_PointerOrReference;
29940b57cec5SDimitry Andric 
299581ad6265SDimitry Andric     // After right braces, star tokens are likely to be pointers to struct,
299681ad6265SDimitry Andric     // union, or class.
299781ad6265SDimitry Andric     //   struct {} *ptr;
2998fcaf7f86SDimitry Andric     // This by itself is not sufficient to distinguish from multiplication
2999fcaf7f86SDimitry Andric     // following a brace-initialized expression, as in:
3000fcaf7f86SDimitry Andric     // int i = int{42} * 2;
3001fcaf7f86SDimitry Andric     // In the struct case, the part of the struct declaration until the `{` and
3002fcaf7f86SDimitry Andric     // the `}` are put on separate unwrapped lines; in the brace-initialized
3003fcaf7f86SDimitry Andric     // case, the matching `{` is on the same unwrapped line, so check for the
3004fcaf7f86SDimitry Andric     // presence of the matching brace to distinguish between those.
3005fcaf7f86SDimitry Andric     if (PrevToken->is(tok::r_brace) && Tok.is(tok::star) &&
3006bdd1243dSDimitry Andric         !PrevToken->MatchingParen) {
300781ad6265SDimitry Andric       return TT_PointerOrReference;
3008bdd1243dSDimitry Andric     }
3009bdd1243dSDimitry Andric 
3010bdd1243dSDimitry Andric     if (PrevToken->endsSequence(tok::r_square, tok::l_square, tok::kw_delete))
3011bdd1243dSDimitry Andric       return TT_UnaryOperator;
301281ad6265SDimitry Andric 
30130b57cec5SDimitry Andric     if (PrevToken->Tok.isLiteral() ||
30140b57cec5SDimitry Andric         PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::kw_true,
301581ad6265SDimitry Andric                            tok::kw_false, tok::r_brace)) {
301681ad6265SDimitry Andric       return TT_BinaryOperator;
301781ad6265SDimitry Andric     }
301881ad6265SDimitry Andric 
301981ad6265SDimitry Andric     const FormatToken *NextNonParen = NextToken;
302081ad6265SDimitry Andric     while (NextNonParen && NextNonParen->is(tok::l_paren))
302181ad6265SDimitry Andric       NextNonParen = NextNonParen->getNextNonComment();
302281ad6265SDimitry Andric     if (NextNonParen && (NextNonParen->Tok.isLiteral() ||
302381ad6265SDimitry Andric                          NextNonParen->isOneOf(tok::kw_true, tok::kw_false) ||
302481ad6265SDimitry Andric                          NextNonParen->isUnaryOperator())) {
302581ad6265SDimitry Andric       return TT_BinaryOperator;
302681ad6265SDimitry Andric     }
302781ad6265SDimitry Andric 
302881ad6265SDimitry Andric     // If we know we're in a template argument, there are no named declarations.
302981ad6265SDimitry Andric     // Thus, having an identifier on the right-hand side indicates a binary
303081ad6265SDimitry Andric     // operator.
303181ad6265SDimitry Andric     if (InTemplateArgument && NextToken->Tok.isAnyIdentifier())
30320b57cec5SDimitry Andric       return TT_BinaryOperator;
30330b57cec5SDimitry Andric 
30345f757f3fSDimitry Andric     // "&&" followed by "(", "*", or "&" is quite unlikely to be two successive
30355f757f3fSDimitry Andric     // unary "&".
30365f757f3fSDimitry Andric     if (Tok.is(tok::ampamp) &&
30375f757f3fSDimitry Andric         NextToken->isOneOf(tok::l_paren, tok::star, tok::amp)) {
30380b57cec5SDimitry Andric       return TT_BinaryOperator;
30395f757f3fSDimitry Andric     }
30400b57cec5SDimitry Andric 
30410b57cec5SDimitry Andric     // This catches some cases where evaluation order is used as control flow:
30420b57cec5SDimitry Andric     //   aaa && aaa->f();
30435ffd83dbSDimitry Andric     if (NextToken->Tok.isAnyIdentifier()) {
30440b57cec5SDimitry Andric       const FormatToken *NextNextToken = NextToken->getNextNonComment();
30450b57cec5SDimitry Andric       if (NextNextToken && NextNextToken->is(tok::arrow))
30460b57cec5SDimitry Andric         return TT_BinaryOperator;
30475ffd83dbSDimitry Andric     }
30480b57cec5SDimitry Andric 
30490b57cec5SDimitry Andric     // It is very unlikely that we are going to find a pointer or reference type
30500b57cec5SDimitry Andric     // definition on the RHS of an assignment.
30510b57cec5SDimitry Andric     if (IsExpression && !Contexts.back().CaretFound)
30520b57cec5SDimitry Andric       return TT_BinaryOperator;
30530b57cec5SDimitry Andric 
305406c3fb27SDimitry Andric     // Opeartors at class scope are likely pointer or reference members.
305506c3fb27SDimitry Andric     if (!Scopes.empty() && Scopes.back() == ST_Class)
305606c3fb27SDimitry Andric       return TT_PointerOrReference;
305706c3fb27SDimitry Andric 
305806c3fb27SDimitry Andric     // Tokens that indicate member access or chained operator& use.
305906c3fb27SDimitry Andric     auto IsChainedOperatorAmpOrMember = [](const FormatToken *token) {
306006c3fb27SDimitry Andric       return !token || token->isOneOf(tok::amp, tok::period, tok::arrow,
306106c3fb27SDimitry Andric                                       tok::arrowstar, tok::periodstar);
306206c3fb27SDimitry Andric     };
306306c3fb27SDimitry Andric 
306406c3fb27SDimitry Andric     // It's more likely that & represents operator& than an uninitialized
306506c3fb27SDimitry Andric     // reference.
306606c3fb27SDimitry Andric     if (Tok.is(tok::amp) && PrevToken && PrevToken->Tok.isAnyIdentifier() &&
306706c3fb27SDimitry Andric         IsChainedOperatorAmpOrMember(PrevToken->getPreviousNonComment()) &&
306806c3fb27SDimitry Andric         NextToken && NextToken->Tok.isAnyIdentifier()) {
306906c3fb27SDimitry Andric       if (auto NextNext = NextToken->getNextNonComment();
307006c3fb27SDimitry Andric           NextNext &&
307106c3fb27SDimitry Andric           (IsChainedOperatorAmpOrMember(NextNext) || NextNext->is(tok::semi))) {
307206c3fb27SDimitry Andric         return TT_BinaryOperator;
307306c3fb27SDimitry Andric       }
307406c3fb27SDimitry Andric     }
307506c3fb27SDimitry Andric 
30760b57cec5SDimitry Andric     return TT_PointerOrReference;
30770b57cec5SDimitry Andric   }
30780b57cec5SDimitry Andric 
30790b57cec5SDimitry Andric   TokenType determinePlusMinusCaretUsage(const FormatToken &Tok) {
308081ad6265SDimitry Andric     if (determineUnaryOperatorByUsage(Tok))
308181ad6265SDimitry Andric       return TT_UnaryOperator;
308281ad6265SDimitry Andric 
30830b57cec5SDimitry Andric     const FormatToken *PrevToken = Tok.getPreviousNonComment();
30840b57cec5SDimitry Andric     if (!PrevToken)
30850b57cec5SDimitry Andric       return TT_UnaryOperator;
30860b57cec5SDimitry Andric 
308781ad6265SDimitry Andric     if (PrevToken->is(tok::at))
30880b57cec5SDimitry Andric       return TT_UnaryOperator;
30890b57cec5SDimitry Andric 
30900b57cec5SDimitry Andric     // Fall back to marking the token as binary operator.
30910b57cec5SDimitry Andric     return TT_BinaryOperator;
30920b57cec5SDimitry Andric   }
30930b57cec5SDimitry Andric 
30940b57cec5SDimitry Andric   /// Determine whether ++/-- are pre- or post-increments/-decrements.
30950b57cec5SDimitry Andric   TokenType determineIncrementUsage(const FormatToken &Tok) {
30960b57cec5SDimitry Andric     const FormatToken *PrevToken = Tok.getPreviousNonComment();
30970b57cec5SDimitry Andric     if (!PrevToken || PrevToken->is(TT_CastRParen))
30980b57cec5SDimitry Andric       return TT_UnaryOperator;
30990b57cec5SDimitry Andric     if (PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::identifier))
31000b57cec5SDimitry Andric       return TT_TrailingUnaryOperator;
31010b57cec5SDimitry Andric 
31020b57cec5SDimitry Andric     return TT_UnaryOperator;
31030b57cec5SDimitry Andric   }
31040b57cec5SDimitry Andric 
31050b57cec5SDimitry Andric   SmallVector<Context, 8> Contexts;
31060b57cec5SDimitry Andric 
31070b57cec5SDimitry Andric   const FormatStyle &Style;
31080b57cec5SDimitry Andric   AnnotatedLine &Line;
31090b57cec5SDimitry Andric   FormatToken *CurrentToken;
31100b57cec5SDimitry Andric   bool AutoFound;
31110fca6ea1SDimitry Andric   bool IsCpp;
31120fca6ea1SDimitry Andric   LangOptions LangOpts;
31130b57cec5SDimitry Andric   const AdditionalKeywords &Keywords;
31140b57cec5SDimitry Andric 
311506c3fb27SDimitry Andric   SmallVector<ScopeType> &Scopes;
311606c3fb27SDimitry Andric 
31170b57cec5SDimitry Andric   // Set of "<" tokens that do not open a template parameter list. If parseAngle
31180b57cec5SDimitry Andric   // determines that a specific token can't be a template opener, it will make
31190b57cec5SDimitry Andric   // same decision irrespective of the decisions for tokens leading up to it.
31200b57cec5SDimitry Andric   // Store this information to prevent this from causing exponential runtime.
31210b57cec5SDimitry Andric   llvm::SmallPtrSet<FormatToken *, 16> NonTemplateLess;
31220fca6ea1SDimitry Andric 
31230fca6ea1SDimitry Andric   int TemplateDeclarationDepth;
31240b57cec5SDimitry Andric };
31250b57cec5SDimitry Andric 
31260b57cec5SDimitry Andric static const int PrecedenceUnaryOperator = prec::PointerToMember + 1;
31270b57cec5SDimitry Andric static const int PrecedenceArrowAndPeriod = prec::PointerToMember + 2;
31280b57cec5SDimitry Andric 
31290b57cec5SDimitry Andric /// Parses binary expressions by inserting fake parenthesis based on
31300b57cec5SDimitry Andric /// operator precedence.
31310b57cec5SDimitry Andric class ExpressionParser {
31320b57cec5SDimitry Andric public:
31330b57cec5SDimitry Andric   ExpressionParser(const FormatStyle &Style, const AdditionalKeywords &Keywords,
31340b57cec5SDimitry Andric                    AnnotatedLine &Line)
313581ad6265SDimitry Andric       : Style(Style), Keywords(Keywords), Line(Line), Current(Line.First) {}
31360b57cec5SDimitry Andric 
31370b57cec5SDimitry Andric   /// Parse expressions with the given operator precedence.
31380b57cec5SDimitry Andric   void parse(int Precedence = 0) {
31390b57cec5SDimitry Andric     // Skip 'return' and ObjC selector colons as they are not part of a binary
31400b57cec5SDimitry Andric     // expression.
31410b57cec5SDimitry Andric     while (Current && (Current->is(tok::kw_return) ||
31420b57cec5SDimitry Andric                        (Current->is(tok::colon) &&
314381ad6265SDimitry Andric                         Current->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)))) {
31440b57cec5SDimitry Andric       next();
314581ad6265SDimitry Andric     }
31460b57cec5SDimitry Andric 
31470b57cec5SDimitry Andric     if (!Current || Precedence > PrecedenceArrowAndPeriod)
31480b57cec5SDimitry Andric       return;
31490b57cec5SDimitry Andric 
31500b57cec5SDimitry Andric     // Conditional expressions need to be parsed separately for proper nesting.
31510b57cec5SDimitry Andric     if (Precedence == prec::Conditional) {
31520b57cec5SDimitry Andric       parseConditionalExpr();
31530b57cec5SDimitry Andric       return;
31540b57cec5SDimitry Andric     }
31550b57cec5SDimitry Andric 
31560b57cec5SDimitry Andric     // Parse unary operators, which all have a higher precedence than binary
31570b57cec5SDimitry Andric     // operators.
31580b57cec5SDimitry Andric     if (Precedence == PrecedenceUnaryOperator) {
31590b57cec5SDimitry Andric       parseUnaryOperator();
31600b57cec5SDimitry Andric       return;
31610b57cec5SDimitry Andric     }
31620b57cec5SDimitry Andric 
31630b57cec5SDimitry Andric     FormatToken *Start = Current;
31640b57cec5SDimitry Andric     FormatToken *LatestOperator = nullptr;
31650b57cec5SDimitry Andric     unsigned OperatorIndex = 0;
316606c3fb27SDimitry Andric     // The first name of the current type in a port list.
316706c3fb27SDimitry Andric     FormatToken *VerilogFirstOfType = nullptr;
31680b57cec5SDimitry Andric 
31690b57cec5SDimitry Andric     while (Current) {
317006c3fb27SDimitry Andric       // In Verilog ports in a module header that don't have a type take the
317106c3fb27SDimitry Andric       // type of the previous one.  For example,
317206c3fb27SDimitry Andric       //   module a(output b,
317306c3fb27SDimitry Andric       //                   c,
317406c3fb27SDimitry Andric       //            output d);
317506c3fb27SDimitry Andric       // In this case there need to be fake parentheses around b and c.
317606c3fb27SDimitry Andric       if (Style.isVerilog() && Precedence == prec::Comma) {
317706c3fb27SDimitry Andric         VerilogFirstOfType =
317806c3fb27SDimitry Andric             verilogGroupDecl(VerilogFirstOfType, LatestOperator);
317906c3fb27SDimitry Andric       }
318006c3fb27SDimitry Andric 
31810b57cec5SDimitry Andric       // Consume operators with higher precedence.
31820b57cec5SDimitry Andric       parse(Precedence + 1);
31830b57cec5SDimitry Andric 
31840b57cec5SDimitry Andric       int CurrentPrecedence = getCurrentPrecedence();
31850b57cec5SDimitry Andric 
31860eae32dcSDimitry Andric       if (Precedence == CurrentPrecedence && Current &&
31870eae32dcSDimitry Andric           Current->is(TT_SelectorName)) {
31880b57cec5SDimitry Andric         if (LatestOperator)
31890b57cec5SDimitry Andric           addFakeParenthesis(Start, prec::Level(Precedence));
31900b57cec5SDimitry Andric         Start = Current;
31910b57cec5SDimitry Andric       }
31920b57cec5SDimitry Andric 
31935f757f3fSDimitry Andric       if ((Style.isCSharp() || Style.isJavaScript() ||
31945f757f3fSDimitry Andric            Style.Language == FormatStyle::LK_Java) &&
31955f757f3fSDimitry Andric           Precedence == prec::Additive && Current) {
31965f757f3fSDimitry Andric         // A string can be broken without parentheses around it when it is
31975f757f3fSDimitry Andric         // already in a sequence of strings joined by `+` signs.
31985f757f3fSDimitry Andric         FormatToken *Prev = Current->getPreviousNonComment();
31995f757f3fSDimitry Andric         if (Prev && Prev->is(tok::string_literal) &&
32005f757f3fSDimitry Andric             (Prev == Start || Prev->endsSequence(tok::string_literal, tok::plus,
32015f757f3fSDimitry Andric                                                  TT_StringInConcatenation))) {
32025f757f3fSDimitry Andric           Prev->setType(TT_StringInConcatenation);
32035f757f3fSDimitry Andric         }
32045f757f3fSDimitry Andric       }
32055f757f3fSDimitry Andric 
320606c3fb27SDimitry Andric       // At the end of the line or when an operator with lower precedence is
32070b57cec5SDimitry Andric       // found, insert fake parenthesis and return.
32080b57cec5SDimitry Andric       if (!Current ||
32090b57cec5SDimitry Andric           (Current->closesScope() &&
32100b57cec5SDimitry Andric            (Current->MatchingParen || Current->is(TT_TemplateString))) ||
32110b57cec5SDimitry Andric           (CurrentPrecedence != -1 && CurrentPrecedence < Precedence) ||
32120b57cec5SDimitry Andric           (CurrentPrecedence == prec::Conditional &&
32130b57cec5SDimitry Andric            Precedence == prec::Assignment && Current->is(tok::colon))) {
32140b57cec5SDimitry Andric         break;
32150b57cec5SDimitry Andric       }
32160b57cec5SDimitry Andric 
32170b57cec5SDimitry Andric       // Consume scopes: (), [], <> and {}
321881ad6265SDimitry Andric       // In addition to that we handle require clauses as scope, so that the
321981ad6265SDimitry Andric       // constraints in that are correctly indented.
322081ad6265SDimitry Andric       if (Current->opensScope() ||
322181ad6265SDimitry Andric           Current->isOneOf(TT_RequiresClause,
322281ad6265SDimitry Andric                            TT_RequiresClauseInARequiresExpression)) {
32230b57cec5SDimitry Andric         // In fragment of a JavaScript template string can look like '}..${' and
32240b57cec5SDimitry Andric         // thus close a scope and open a new one at the same time.
32250b57cec5SDimitry Andric         while (Current && (!Current->closesScope() || Current->opensScope())) {
32260b57cec5SDimitry Andric           next();
32270b57cec5SDimitry Andric           parse();
32280b57cec5SDimitry Andric         }
32290b57cec5SDimitry Andric         next();
32300b57cec5SDimitry Andric       } else {
32310b57cec5SDimitry Andric         // Operator found.
32320b57cec5SDimitry Andric         if (CurrentPrecedence == Precedence) {
32330b57cec5SDimitry Andric           if (LatestOperator)
32340b57cec5SDimitry Andric             LatestOperator->NextOperator = Current;
32350b57cec5SDimitry Andric           LatestOperator = Current;
32360b57cec5SDimitry Andric           Current->OperatorIndex = OperatorIndex;
32370b57cec5SDimitry Andric           ++OperatorIndex;
32380b57cec5SDimitry Andric         }
32390b57cec5SDimitry Andric         next(/*SkipPastLeadingComments=*/Precedence > 0);
32400b57cec5SDimitry Andric       }
32410b57cec5SDimitry Andric     }
32420b57cec5SDimitry Andric 
324306c3fb27SDimitry Andric     // Group variables of the same type.
324406c3fb27SDimitry Andric     if (Style.isVerilog() && Precedence == prec::Comma && VerilogFirstOfType)
324506c3fb27SDimitry Andric       addFakeParenthesis(VerilogFirstOfType, prec::Comma);
324606c3fb27SDimitry Andric 
32470b57cec5SDimitry Andric     if (LatestOperator && (Current || Precedence > 0)) {
324881ad6265SDimitry Andric       // The requires clauses do not neccessarily end in a semicolon or a brace,
324981ad6265SDimitry Andric       // but just go over to struct/class or a function declaration, we need to
325081ad6265SDimitry Andric       // intervene so that the fake right paren is inserted correctly.
325181ad6265SDimitry Andric       auto End =
325281ad6265SDimitry Andric           (Start->Previous &&
325381ad6265SDimitry Andric            Start->Previous->isOneOf(TT_RequiresClause,
325481ad6265SDimitry Andric                                     TT_RequiresClauseInARequiresExpression))
325581ad6265SDimitry Andric               ? [this]() {
325681ad6265SDimitry Andric                   auto Ret = Current ? Current : Line.Last;
325781ad6265SDimitry Andric                   while (!Ret->ClosesRequiresClause && Ret->Previous)
325881ad6265SDimitry Andric                     Ret = Ret->Previous;
325981ad6265SDimitry Andric                   return Ret;
326081ad6265SDimitry Andric                 }()
326181ad6265SDimitry Andric               : nullptr;
326281ad6265SDimitry Andric 
32630b57cec5SDimitry Andric       if (Precedence == PrecedenceArrowAndPeriod) {
32640b57cec5SDimitry Andric         // Call expressions don't have a binary operator precedence.
326581ad6265SDimitry Andric         addFakeParenthesis(Start, prec::Unknown, End);
32660b57cec5SDimitry Andric       } else {
326781ad6265SDimitry Andric         addFakeParenthesis(Start, prec::Level(Precedence), End);
32680b57cec5SDimitry Andric       }
32690b57cec5SDimitry Andric     }
32700b57cec5SDimitry Andric   }
32710b57cec5SDimitry Andric 
32720b57cec5SDimitry Andric private:
32730b57cec5SDimitry Andric   /// Gets the precedence (+1) of the given token for binary operators
32740b57cec5SDimitry Andric   /// and other tokens that we treat like binary operators.
32750b57cec5SDimitry Andric   int getCurrentPrecedence() {
32760b57cec5SDimitry Andric     if (Current) {
32770b57cec5SDimitry Andric       const FormatToken *NextNonComment = Current->getNextNonComment();
32780b57cec5SDimitry Andric       if (Current->is(TT_ConditionalExpr))
32790b57cec5SDimitry Andric         return prec::Conditional;
32800b57cec5SDimitry Andric       if (NextNonComment && Current->is(TT_SelectorName) &&
32810b57cec5SDimitry Andric           (NextNonComment->isOneOf(TT_DictLiteral, TT_JsTypeColon) ||
32825f757f3fSDimitry Andric            (Style.isProto() && NextNonComment->is(tok::less)))) {
32830b57cec5SDimitry Andric         return prec::Assignment;
328481ad6265SDimitry Andric       }
32850b57cec5SDimitry Andric       if (Current->is(TT_JsComputedPropertyName))
32860b57cec5SDimitry Andric         return prec::Assignment;
32876c4b055cSDimitry Andric       if (Current->is(TT_LambdaArrow))
32880b57cec5SDimitry Andric         return prec::Comma;
3289fe6060f1SDimitry Andric       if (Current->is(TT_FatArrow))
32900b57cec5SDimitry Andric         return prec::Assignment;
32910b57cec5SDimitry Andric       if (Current->isOneOf(tok::semi, TT_InlineASMColon, TT_SelectorName) ||
32920b57cec5SDimitry Andric           (Current->is(tok::comment) && NextNonComment &&
329381ad6265SDimitry Andric            NextNonComment->is(TT_SelectorName))) {
32940b57cec5SDimitry Andric         return 0;
329581ad6265SDimitry Andric       }
32960b57cec5SDimitry Andric       if (Current->is(TT_RangeBasedForLoopColon))
32970b57cec5SDimitry Andric         return prec::Comma;
32980eae32dcSDimitry Andric       if ((Style.Language == FormatStyle::LK_Java || Style.isJavaScript()) &&
329981ad6265SDimitry Andric           Current->is(Keywords.kw_instanceof)) {
33000b57cec5SDimitry Andric         return prec::Relational;
330181ad6265SDimitry Andric       }
33020eae32dcSDimitry Andric       if (Style.isJavaScript() &&
330381ad6265SDimitry Andric           Current->isOneOf(Keywords.kw_in, Keywords.kw_as)) {
33040b57cec5SDimitry Andric         return prec::Relational;
330581ad6265SDimitry Andric       }
33060b57cec5SDimitry Andric       if (Current->is(TT_BinaryOperator) || Current->is(tok::comma))
33070b57cec5SDimitry Andric         return Current->getPrecedence();
3308bdd1243dSDimitry Andric       if (Current->isOneOf(tok::period, tok::arrow) &&
3309bdd1243dSDimitry Andric           Current->isNot(TT_TrailingReturnArrow)) {
33100b57cec5SDimitry Andric         return PrecedenceArrowAndPeriod;
3311bdd1243dSDimitry Andric       }
33120eae32dcSDimitry Andric       if ((Style.Language == FormatStyle::LK_Java || Style.isJavaScript()) &&
33130b57cec5SDimitry Andric           Current->isOneOf(Keywords.kw_extends, Keywords.kw_implements,
331481ad6265SDimitry Andric                            Keywords.kw_throws)) {
33150b57cec5SDimitry Andric         return 0;
33160b57cec5SDimitry Andric       }
3317bdd1243dSDimitry Andric       // In Verilog case labels are not on separate lines straight out of
3318bdd1243dSDimitry Andric       // UnwrappedLineParser. The colon is not part of an expression.
3319bdd1243dSDimitry Andric       if (Style.isVerilog() && Current->is(tok::colon))
3320bdd1243dSDimitry Andric         return 0;
332181ad6265SDimitry Andric     }
33220b57cec5SDimitry Andric     return -1;
33230b57cec5SDimitry Andric   }
33240b57cec5SDimitry Andric 
332581ad6265SDimitry Andric   void addFakeParenthesis(FormatToken *Start, prec::Level Precedence,
332681ad6265SDimitry Andric                           FormatToken *End = nullptr) {
3327297eecfbSDimitry Andric     // Do not assign fake parenthesis to tokens that are part of an
3328297eecfbSDimitry Andric     // unexpanded macro call. The line within the macro call contains
3329297eecfbSDimitry Andric     // the parenthesis and commas, and we will not find operators within
3330297eecfbSDimitry Andric     // that structure.
3331297eecfbSDimitry Andric     if (Start->MacroParent)
3332297eecfbSDimitry Andric       return;
3333297eecfbSDimitry Andric 
33340b57cec5SDimitry Andric     Start->FakeLParens.push_back(Precedence);
33350b57cec5SDimitry Andric     if (Precedence > prec::Unknown)
33360b57cec5SDimitry Andric       Start->StartsBinaryExpression = true;
333781ad6265SDimitry Andric     if (!End && Current)
333881ad6265SDimitry Andric       End = Current->getPreviousNonComment();
333981ad6265SDimitry Andric     if (End) {
334081ad6265SDimitry Andric       ++End->FakeRParens;
33410b57cec5SDimitry Andric       if (Precedence > prec::Unknown)
334281ad6265SDimitry Andric         End->EndsBinaryExpression = true;
33430b57cec5SDimitry Andric     }
33440b57cec5SDimitry Andric   }
33450b57cec5SDimitry Andric 
33460b57cec5SDimitry Andric   /// Parse unary operator expressions and surround them with fake
33470b57cec5SDimitry Andric   /// parentheses if appropriate.
33480b57cec5SDimitry Andric   void parseUnaryOperator() {
33490b57cec5SDimitry Andric     llvm::SmallVector<FormatToken *, 2> Tokens;
33500b57cec5SDimitry Andric     while (Current && Current->is(TT_UnaryOperator)) {
33510b57cec5SDimitry Andric       Tokens.push_back(Current);
33520b57cec5SDimitry Andric       next();
33530b57cec5SDimitry Andric     }
33540b57cec5SDimitry Andric     parse(PrecedenceArrowAndPeriod);
335581ad6265SDimitry Andric     for (FormatToken *Token : llvm::reverse(Tokens)) {
33560b57cec5SDimitry Andric       // The actual precedence doesn't matter.
33570b57cec5SDimitry Andric       addFakeParenthesis(Token, prec::Unknown);
33580b57cec5SDimitry Andric     }
335981ad6265SDimitry Andric   }
33600b57cec5SDimitry Andric 
33610b57cec5SDimitry Andric   void parseConditionalExpr() {
336281ad6265SDimitry Andric     while (Current && Current->isTrailingComment())
33630b57cec5SDimitry Andric       next();
33640b57cec5SDimitry Andric     FormatToken *Start = Current;
33650b57cec5SDimitry Andric     parse(prec::LogicalOr);
33665f757f3fSDimitry Andric     if (!Current || Current->isNot(tok::question))
33670b57cec5SDimitry Andric       return;
33680b57cec5SDimitry Andric     next();
33690b57cec5SDimitry Andric     parse(prec::Assignment);
33700b57cec5SDimitry Andric     if (!Current || Current->isNot(TT_ConditionalExpr))
33710b57cec5SDimitry Andric       return;
33720b57cec5SDimitry Andric     next();
33730b57cec5SDimitry Andric     parse(prec::Assignment);
33740b57cec5SDimitry Andric     addFakeParenthesis(Start, prec::Conditional);
33750b57cec5SDimitry Andric   }
33760b57cec5SDimitry Andric 
33770b57cec5SDimitry Andric   void next(bool SkipPastLeadingComments = true) {
33780b57cec5SDimitry Andric     if (Current)
33790b57cec5SDimitry Andric       Current = Current->Next;
33800b57cec5SDimitry Andric     while (Current &&
33810b57cec5SDimitry Andric            (Current->NewlinesBefore == 0 || SkipPastLeadingComments) &&
338281ad6265SDimitry Andric            Current->isTrailingComment()) {
33830b57cec5SDimitry Andric       Current = Current->Next;
33840b57cec5SDimitry Andric     }
338581ad6265SDimitry Andric   }
33860b57cec5SDimitry Andric 
338706c3fb27SDimitry Andric   // Add fake parenthesis around declarations of the same type for example in a
338806c3fb27SDimitry Andric   // module prototype. Return the first port / variable of the current type.
338906c3fb27SDimitry Andric   FormatToken *verilogGroupDecl(FormatToken *FirstOfType,
339006c3fb27SDimitry Andric                                 FormatToken *PreviousComma) {
339106c3fb27SDimitry Andric     if (!Current)
339206c3fb27SDimitry Andric       return nullptr;
339306c3fb27SDimitry Andric 
339406c3fb27SDimitry Andric     FormatToken *Start = Current;
339506c3fb27SDimitry Andric 
339606c3fb27SDimitry Andric     // Skip attributes.
339706c3fb27SDimitry Andric     while (Start->startsSequence(tok::l_paren, tok::star)) {
339806c3fb27SDimitry Andric       if (!(Start = Start->MatchingParen) ||
339906c3fb27SDimitry Andric           !(Start = Start->getNextNonComment())) {
340006c3fb27SDimitry Andric         return nullptr;
340106c3fb27SDimitry Andric       }
340206c3fb27SDimitry Andric     }
340306c3fb27SDimitry Andric 
340406c3fb27SDimitry Andric     FormatToken *Tok = Start;
340506c3fb27SDimitry Andric 
340606c3fb27SDimitry Andric     if (Tok->is(Keywords.kw_assign))
340706c3fb27SDimitry Andric       Tok = Tok->getNextNonComment();
340806c3fb27SDimitry Andric 
340906c3fb27SDimitry Andric     // Skip any type qualifiers to find the first identifier. It may be either a
341006c3fb27SDimitry Andric     // new type name or a variable name. There can be several type qualifiers
341106c3fb27SDimitry Andric     // preceding a variable name, and we can not tell them apart by looking at
341206c3fb27SDimitry Andric     // the word alone since a macro can be defined as either a type qualifier or
341306c3fb27SDimitry Andric     // a variable name. Thus we use the last word before the dimensions instead
341406c3fb27SDimitry Andric     // of the first word as the candidate for the variable or type name.
341506c3fb27SDimitry Andric     FormatToken *First = nullptr;
341606c3fb27SDimitry Andric     while (Tok) {
341706c3fb27SDimitry Andric       FormatToken *Next = Tok->getNextNonComment();
341806c3fb27SDimitry Andric 
341906c3fb27SDimitry Andric       if (Tok->is(tok::hash)) {
342006c3fb27SDimitry Andric         // Start of a macro expansion.
342106c3fb27SDimitry Andric         First = Tok;
342206c3fb27SDimitry Andric         Tok = Next;
342306c3fb27SDimitry Andric         if (Tok)
342406c3fb27SDimitry Andric           Tok = Tok->getNextNonComment();
342506c3fb27SDimitry Andric       } else if (Tok->is(tok::hashhash)) {
342606c3fb27SDimitry Andric         // Concatenation. Skip.
342706c3fb27SDimitry Andric         Tok = Next;
342806c3fb27SDimitry Andric         if (Tok)
342906c3fb27SDimitry Andric           Tok = Tok->getNextNonComment();
343006c3fb27SDimitry Andric       } else if (Keywords.isVerilogQualifier(*Tok) ||
343106c3fb27SDimitry Andric                  Keywords.isVerilogIdentifier(*Tok)) {
343206c3fb27SDimitry Andric         First = Tok;
343306c3fb27SDimitry Andric         Tok = Next;
343406c3fb27SDimitry Andric         // The name may have dots like `interface_foo.modport_foo`.
343506c3fb27SDimitry Andric         while (Tok && Tok->isOneOf(tok::period, tok::coloncolon) &&
343606c3fb27SDimitry Andric                (Tok = Tok->getNextNonComment())) {
343706c3fb27SDimitry Andric           if (Keywords.isVerilogIdentifier(*Tok))
343806c3fb27SDimitry Andric             Tok = Tok->getNextNonComment();
343906c3fb27SDimitry Andric         }
344006c3fb27SDimitry Andric       } else if (!Next) {
344106c3fb27SDimitry Andric         Tok = nullptr;
344206c3fb27SDimitry Andric       } else if (Tok->is(tok::l_paren)) {
344306c3fb27SDimitry Andric         // Make sure the parenthesized list is a drive strength. Otherwise the
344406c3fb27SDimitry Andric         // statement may be a module instantiation in which case we have already
344506c3fb27SDimitry Andric         // found the instance name.
344606c3fb27SDimitry Andric         if (Next->isOneOf(
344706c3fb27SDimitry Andric                 Keywords.kw_highz0, Keywords.kw_highz1, Keywords.kw_large,
344806c3fb27SDimitry Andric                 Keywords.kw_medium, Keywords.kw_pull0, Keywords.kw_pull1,
344906c3fb27SDimitry Andric                 Keywords.kw_small, Keywords.kw_strong0, Keywords.kw_strong1,
345006c3fb27SDimitry Andric                 Keywords.kw_supply0, Keywords.kw_supply1, Keywords.kw_weak0,
345106c3fb27SDimitry Andric                 Keywords.kw_weak1)) {
345206c3fb27SDimitry Andric           Tok->setType(TT_VerilogStrength);
345306c3fb27SDimitry Andric           Tok = Tok->MatchingParen;
345406c3fb27SDimitry Andric           if (Tok) {
345506c3fb27SDimitry Andric             Tok->setType(TT_VerilogStrength);
345606c3fb27SDimitry Andric             Tok = Tok->getNextNonComment();
345706c3fb27SDimitry Andric           }
345806c3fb27SDimitry Andric         } else {
345906c3fb27SDimitry Andric           break;
346006c3fb27SDimitry Andric         }
34610fca6ea1SDimitry Andric       } else if (Tok->is(Keywords.kw_verilogHash)) {
34620fca6ea1SDimitry Andric         // Delay control.
346306c3fb27SDimitry Andric         if (Next->is(tok::l_paren))
346406c3fb27SDimitry Andric           Next = Next->MatchingParen;
346506c3fb27SDimitry Andric         if (Next)
346606c3fb27SDimitry Andric           Tok = Next->getNextNonComment();
346706c3fb27SDimitry Andric       } else {
346806c3fb27SDimitry Andric         break;
346906c3fb27SDimitry Andric       }
347006c3fb27SDimitry Andric     }
347106c3fb27SDimitry Andric 
347206c3fb27SDimitry Andric     // Find the second identifier. If it exists it will be the name.
347306c3fb27SDimitry Andric     FormatToken *Second = nullptr;
347406c3fb27SDimitry Andric     // Dimensions.
347506c3fb27SDimitry Andric     while (Tok && Tok->is(tok::l_square) && (Tok = Tok->MatchingParen))
347606c3fb27SDimitry Andric       Tok = Tok->getNextNonComment();
347706c3fb27SDimitry Andric     if (Tok && (Tok->is(tok::hash) || Keywords.isVerilogIdentifier(*Tok)))
347806c3fb27SDimitry Andric       Second = Tok;
347906c3fb27SDimitry Andric 
348006c3fb27SDimitry Andric     // If the second identifier doesn't exist and there are qualifiers, the type
348106c3fb27SDimitry Andric     // is implied.
348206c3fb27SDimitry Andric     FormatToken *TypedName = nullptr;
348306c3fb27SDimitry Andric     if (Second) {
348406c3fb27SDimitry Andric       TypedName = Second;
348506c3fb27SDimitry Andric       if (First && First->is(TT_Unknown))
348606c3fb27SDimitry Andric         First->setType(TT_VerilogDimensionedTypeName);
348706c3fb27SDimitry Andric     } else if (First != Start) {
348806c3fb27SDimitry Andric       // If 'First' is null, then this isn't a declaration, 'TypedName' gets set
348906c3fb27SDimitry Andric       // to null as intended.
349006c3fb27SDimitry Andric       TypedName = First;
349106c3fb27SDimitry Andric     }
349206c3fb27SDimitry Andric 
349306c3fb27SDimitry Andric     if (TypedName) {
349406c3fb27SDimitry Andric       // This is a declaration with a new type.
349506c3fb27SDimitry Andric       if (TypedName->is(TT_Unknown))
349606c3fb27SDimitry Andric         TypedName->setType(TT_StartOfName);
349706c3fb27SDimitry Andric       // Group variables of the previous type.
349806c3fb27SDimitry Andric       if (FirstOfType && PreviousComma) {
349906c3fb27SDimitry Andric         PreviousComma->setType(TT_VerilogTypeComma);
350006c3fb27SDimitry Andric         addFakeParenthesis(FirstOfType, prec::Comma, PreviousComma->Previous);
350106c3fb27SDimitry Andric       }
350206c3fb27SDimitry Andric 
350306c3fb27SDimitry Andric       FirstOfType = TypedName;
350406c3fb27SDimitry Andric 
350506c3fb27SDimitry Andric       // Don't let higher precedence handle the qualifiers. For example if we
350606c3fb27SDimitry Andric       // have:
350706c3fb27SDimitry Andric       //    parameter x = 0
350806c3fb27SDimitry Andric       // We skip `parameter` here. This way the fake parentheses for the
350906c3fb27SDimitry Andric       // assignment will be around `x = 0`.
351006c3fb27SDimitry Andric       while (Current && Current != FirstOfType) {
351106c3fb27SDimitry Andric         if (Current->opensScope()) {
351206c3fb27SDimitry Andric           next();
351306c3fb27SDimitry Andric           parse();
351406c3fb27SDimitry Andric         }
351506c3fb27SDimitry Andric         next();
351606c3fb27SDimitry Andric       }
351706c3fb27SDimitry Andric     }
351806c3fb27SDimitry Andric 
351906c3fb27SDimitry Andric     return FirstOfType;
352006c3fb27SDimitry Andric   }
352106c3fb27SDimitry Andric 
35220b57cec5SDimitry Andric   const FormatStyle &Style;
35230b57cec5SDimitry Andric   const AdditionalKeywords &Keywords;
352481ad6265SDimitry Andric   const AnnotatedLine &Line;
35250b57cec5SDimitry Andric   FormatToken *Current;
35260b57cec5SDimitry Andric };
35270b57cec5SDimitry Andric 
35280b57cec5SDimitry Andric } // end anonymous namespace
35290b57cec5SDimitry Andric 
35300b57cec5SDimitry Andric void TokenAnnotator::setCommentLineLevels(
353181ad6265SDimitry Andric     SmallVectorImpl<AnnotatedLine *> &Lines) const {
35320b57cec5SDimitry Andric   const AnnotatedLine *NextNonCommentLine = nullptr;
353304eeddc0SDimitry Andric   for (AnnotatedLine *Line : llvm::reverse(Lines)) {
353404eeddc0SDimitry Andric     assert(Line->First);
35350b57cec5SDimitry Andric 
35360b57cec5SDimitry Andric     // If the comment is currently aligned with the line immediately following
35370b57cec5SDimitry Andric     // it, that's probably intentional and we should keep it.
35385c16e71dSDimitry Andric     if (NextNonCommentLine && NextNonCommentLine->First->NewlinesBefore < 2 &&
35395c16e71dSDimitry Andric         Line->isComment() && !isClangFormatOff(Line->First->TokenText) &&
35400b57cec5SDimitry Andric         NextNonCommentLine->First->OriginalColumn ==
354104eeddc0SDimitry Andric             Line->First->OriginalColumn) {
3542bdd1243dSDimitry Andric       const bool PPDirectiveOrImportStmt =
3543bdd1243dSDimitry Andric           NextNonCommentLine->Type == LT_PreprocessorDirective ||
3544bdd1243dSDimitry Andric           NextNonCommentLine->Type == LT_ImportStatement;
3545bdd1243dSDimitry Andric       if (PPDirectiveOrImportStmt)
3546bdd1243dSDimitry Andric         Line->Type = LT_CommentAbovePPDirective;
35470b57cec5SDimitry Andric       // Align comments for preprocessor lines with the # in column 0 if
35480b57cec5SDimitry Andric       // preprocessor lines are not indented. Otherwise, align with the next
35490b57cec5SDimitry Andric       // line.
3550bdd1243dSDimitry Andric       Line->Level = Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash &&
3551bdd1243dSDimitry Andric                             PPDirectiveOrImportStmt
35520b57cec5SDimitry Andric                         ? 0
35530b57cec5SDimitry Andric                         : NextNonCommentLine->Level;
35540b57cec5SDimitry Andric     } else {
355504eeddc0SDimitry Andric       NextNonCommentLine = Line->First->isNot(tok::r_brace) ? Line : nullptr;
35560b57cec5SDimitry Andric     }
35570b57cec5SDimitry Andric 
355804eeddc0SDimitry Andric     setCommentLineLevels(Line->Children);
35590b57cec5SDimitry Andric   }
35600b57cec5SDimitry Andric }
35610b57cec5SDimitry Andric 
35620b57cec5SDimitry Andric static unsigned maxNestingDepth(const AnnotatedLine &Line) {
35630b57cec5SDimitry Andric   unsigned Result = 0;
356406c3fb27SDimitry Andric   for (const auto *Tok = Line.First; Tok; Tok = Tok->Next)
35650b57cec5SDimitry Andric     Result = std::max(Result, Tok->NestingLevel);
35660b57cec5SDimitry Andric   return Result;
35670b57cec5SDimitry Andric }
35680b57cec5SDimitry Andric 
35695f757f3fSDimitry Andric // Returns the name of a function with no return type, e.g. a constructor or
35705f757f3fSDimitry Andric // destructor.
35710fca6ea1SDimitry Andric static FormatToken *getFunctionName(const AnnotatedLine &Line,
35720fca6ea1SDimitry Andric                                     FormatToken *&OpeningParen) {
35735f757f3fSDimitry Andric   for (FormatToken *Tok = Line.getFirstNonComment(), *Name = nullptr; Tok;
35745f757f3fSDimitry Andric        Tok = Tok->getNextNonComment()) {
35755f757f3fSDimitry Andric     // Skip C++11 attributes both before and after the function name.
35765f757f3fSDimitry Andric     if (Tok->is(tok::l_square) && Tok->is(TT_AttributeSquare)) {
35775f757f3fSDimitry Andric       Tok = Tok->MatchingParen;
35785f757f3fSDimitry Andric       if (!Tok)
35795f757f3fSDimitry Andric         break;
35805f757f3fSDimitry Andric       continue;
35815f757f3fSDimitry Andric     }
35820eae32dcSDimitry Andric 
35835f757f3fSDimitry Andric     // Make sure the name is followed by a pair of parentheses.
35845f757f3fSDimitry Andric     if (Name) {
35850fca6ea1SDimitry Andric       if (Tok->is(tok::l_paren) && Tok->isNot(TT_FunctionTypeLParen) &&
35860fca6ea1SDimitry Andric           Tok->MatchingParen) {
35870fca6ea1SDimitry Andric         OpeningParen = Tok;
35880fca6ea1SDimitry Andric         return Name;
35890fca6ea1SDimitry Andric       }
35900fca6ea1SDimitry Andric       return nullptr;
35915f757f3fSDimitry Andric     }
35925f757f3fSDimitry Andric 
35935f757f3fSDimitry Andric     // Skip keywords that may precede the constructor/destructor name.
35945f757f3fSDimitry Andric     if (Tok->isOneOf(tok::kw_friend, tok::kw_inline, tok::kw_virtual,
35955f757f3fSDimitry Andric                      tok::kw_constexpr, tok::kw_consteval, tok::kw_explicit)) {
35965f757f3fSDimitry Andric       continue;
35975f757f3fSDimitry Andric     }
35985f757f3fSDimitry Andric 
35995f757f3fSDimitry Andric     // A qualified name may start from the global namespace.
36005f757f3fSDimitry Andric     if (Tok->is(tok::coloncolon)) {
36015f757f3fSDimitry Andric       Tok = Tok->Next;
36025f757f3fSDimitry Andric       if (!Tok)
36035f757f3fSDimitry Andric         break;
36045f757f3fSDimitry Andric     }
36055f757f3fSDimitry Andric 
36065f757f3fSDimitry Andric     // Skip to the unqualified part of the name.
36075f757f3fSDimitry Andric     while (Tok->startsSequence(tok::identifier, tok::coloncolon)) {
36085f757f3fSDimitry Andric       assert(Tok->Next);
36095f757f3fSDimitry Andric       Tok = Tok->Next->Next;
36105f757f3fSDimitry Andric       if (!Tok)
36115f757f3fSDimitry Andric         return nullptr;
36125f757f3fSDimitry Andric     }
36135f757f3fSDimitry Andric 
36145f757f3fSDimitry Andric     // Skip the `~` if a destructor name.
36155f757f3fSDimitry Andric     if (Tok->is(tok::tilde)) {
36165f757f3fSDimitry Andric       Tok = Tok->Next;
36175f757f3fSDimitry Andric       if (!Tok)
36185f757f3fSDimitry Andric         break;
36195f757f3fSDimitry Andric     }
36205f757f3fSDimitry Andric 
36215f757f3fSDimitry Andric     // Make sure the name is not already annotated, e.g. as NamespaceMacro.
36225f757f3fSDimitry Andric     if (Tok->isNot(tok::identifier) || Tok->isNot(TT_Unknown))
36235f757f3fSDimitry Andric       break;
36245f757f3fSDimitry Andric 
36255f757f3fSDimitry Andric     Name = Tok;
36265f757f3fSDimitry Andric   }
36275f757f3fSDimitry Andric 
36285f757f3fSDimitry Andric   return nullptr;
36295f757f3fSDimitry Andric }
36305f757f3fSDimitry Andric 
36315f757f3fSDimitry Andric // Checks if Tok is a constructor/destructor name qualified by its class name.
36325f757f3fSDimitry Andric static bool isCtorOrDtorName(const FormatToken *Tok) {
36335f757f3fSDimitry Andric   assert(Tok && Tok->is(tok::identifier));
36345f757f3fSDimitry Andric   const auto *Prev = Tok->Previous;
36355f757f3fSDimitry Andric 
36365f757f3fSDimitry Andric   if (Prev && Prev->is(tok::tilde))
36375f757f3fSDimitry Andric     Prev = Prev->Previous;
36385f757f3fSDimitry Andric 
36395f757f3fSDimitry Andric   if (!Prev || !Prev->endsSequence(tok::coloncolon, tok::identifier))
36405f757f3fSDimitry Andric     return false;
36415f757f3fSDimitry Andric 
36425f757f3fSDimitry Andric   assert(Prev->Previous);
36435f757f3fSDimitry Andric   return Prev->Previous->TokenText == Tok->TokenText;
36445f757f3fSDimitry Andric }
36455f757f3fSDimitry Andric 
36465f757f3fSDimitry Andric void TokenAnnotator::annotate(AnnotatedLine &Line) {
364706c3fb27SDimitry Andric   AnnotatingParser Parser(Style, Line, Keywords, Scopes);
36480b57cec5SDimitry Andric   Line.Type = Parser.parseLine();
36490b57cec5SDimitry Andric 
36505f757f3fSDimitry Andric   for (auto &Child : Line.Children)
36515f757f3fSDimitry Andric     annotate(*Child);
36525f757f3fSDimitry Andric 
36530b57cec5SDimitry Andric   // With very deep nesting, ExpressionParser uses lots of stack and the
36540b57cec5SDimitry Andric   // formatting algorithm is very slow. We're not going to do a good job here
36550b57cec5SDimitry Andric   // anyway - it's probably generated code being formatted by mistake.
36560b57cec5SDimitry Andric   // Just skip the whole line.
36570b57cec5SDimitry Andric   if (maxNestingDepth(Line) > 50)
36580b57cec5SDimitry Andric     Line.Type = LT_Invalid;
36590b57cec5SDimitry Andric 
36600b57cec5SDimitry Andric   if (Line.Type == LT_Invalid)
36610b57cec5SDimitry Andric     return;
36620b57cec5SDimitry Andric 
36630b57cec5SDimitry Andric   ExpressionParser ExprParser(Style, Keywords, Line);
36640b57cec5SDimitry Andric   ExprParser.parse();
36650b57cec5SDimitry Andric 
36660fca6ea1SDimitry Andric   if (IsCpp) {
36670fca6ea1SDimitry Andric     FormatToken *OpeningParen = nullptr;
36680fca6ea1SDimitry Andric     auto *Tok = getFunctionName(Line, OpeningParen);
36695f757f3fSDimitry Andric     if (Tok && ((!Scopes.empty() && Scopes.back() == ST_Class) ||
36705f757f3fSDimitry Andric                 Line.endsWith(TT_FunctionLBrace) || isCtorOrDtorName(Tok))) {
36715f757f3fSDimitry Andric       Tok->setFinalizedType(TT_CtorDtorDeclName);
36720fca6ea1SDimitry Andric       assert(OpeningParen);
36730fca6ea1SDimitry Andric       OpeningParen->setFinalizedType(TT_FunctionDeclarationLParen);
36745f757f3fSDimitry Andric     }
36755f757f3fSDimitry Andric   }
36765f757f3fSDimitry Andric 
36770b57cec5SDimitry Andric   if (Line.startsWith(TT_ObjCMethodSpecifier))
36780b57cec5SDimitry Andric     Line.Type = LT_ObjCMethodDecl;
36790b57cec5SDimitry Andric   else if (Line.startsWith(TT_ObjCDecl))
36800b57cec5SDimitry Andric     Line.Type = LT_ObjCDecl;
36810b57cec5SDimitry Andric   else if (Line.startsWith(TT_ObjCProperty))
36820b57cec5SDimitry Andric     Line.Type = LT_ObjCProperty;
36830b57cec5SDimitry Andric 
36845f757f3fSDimitry Andric   auto *First = Line.First;
36855f757f3fSDimitry Andric   First->SpacesRequiredBefore = 1;
36865f757f3fSDimitry Andric   First->CanBreakBefore = First->MustBreakBefore;
36870b57cec5SDimitry Andric }
36880b57cec5SDimitry Andric 
36890b57cec5SDimitry Andric // This function heuristically determines whether 'Current' starts the name of a
36900b57cec5SDimitry Andric // function declaration.
36910fca6ea1SDimitry Andric static bool isFunctionDeclarationName(const LangOptions &LangOpts,
36920fca6ea1SDimitry Andric                                       const FormatToken &Current,
36935f757f3fSDimitry Andric                                       const AnnotatedLine &Line,
36945f757f3fSDimitry Andric                                       FormatToken *&ClosingParen) {
369506c3fb27SDimitry Andric   assert(Current.Previous);
36965f757f3fSDimitry Andric 
36975f757f3fSDimitry Andric   if (Current.is(TT_FunctionDeclarationName))
36985f757f3fSDimitry Andric     return true;
36995f757f3fSDimitry Andric 
370006c3fb27SDimitry Andric   if (!Current.Tok.getIdentifierInfo())
370106c3fb27SDimitry Andric     return false;
370206c3fb27SDimitry Andric 
37030fca6ea1SDimitry Andric   const auto &Previous = *Current.Previous;
37040fca6ea1SDimitry Andric 
37050fca6ea1SDimitry Andric   if (const auto *PrevPrev = Previous.Previous;
37060fca6ea1SDimitry Andric       PrevPrev && PrevPrev->is(TT_ObjCDecl)) {
37070fca6ea1SDimitry Andric     return false;
37080fca6ea1SDimitry Andric   }
37090fca6ea1SDimitry Andric 
37100fca6ea1SDimitry Andric   auto skipOperatorName =
37110fca6ea1SDimitry Andric       [&LangOpts](const FormatToken *Next) -> const FormatToken * {
37120b57cec5SDimitry Andric     for (; Next; Next = Next->Next) {
37130b57cec5SDimitry Andric       if (Next->is(TT_OverloadedOperatorLParen))
37140b57cec5SDimitry Andric         return Next;
37150b57cec5SDimitry Andric       if (Next->is(TT_OverloadedOperator))
37160b57cec5SDimitry Andric         continue;
37170b57cec5SDimitry Andric       if (Next->isOneOf(tok::kw_new, tok::kw_delete)) {
37180b57cec5SDimitry Andric         // For 'new[]' and 'delete[]'.
3719480093f4SDimitry Andric         if (Next->Next &&
372081ad6265SDimitry Andric             Next->Next->startsSequence(tok::l_square, tok::r_square)) {
37210b57cec5SDimitry Andric           Next = Next->Next->Next;
372281ad6265SDimitry Andric         }
37230b57cec5SDimitry Andric         continue;
37240b57cec5SDimitry Andric       }
3725480093f4SDimitry Andric       if (Next->startsSequence(tok::l_square, tok::r_square)) {
3726480093f4SDimitry Andric         // For operator[]().
3727480093f4SDimitry Andric         Next = Next->Next;
3728480093f4SDimitry Andric         continue;
3729480093f4SDimitry Andric       }
37300fca6ea1SDimitry Andric       if ((Next->isTypeName(LangOpts) || Next->is(tok::identifier)) &&
37315f757f3fSDimitry Andric           Next->Next && Next->Next->isPointerOrReference()) {
3732480093f4SDimitry Andric         // For operator void*(), operator char*(), operator Foo*().
3733480093f4SDimitry Andric         Next = Next->Next;
3734480093f4SDimitry Andric         continue;
3735480093f4SDimitry Andric       }
3736d65cd7a5SDimitry Andric       if (Next->is(TT_TemplateOpener) && Next->MatchingParen) {
3737d65cd7a5SDimitry Andric         Next = Next->MatchingParen;
3738d65cd7a5SDimitry Andric         continue;
3739d65cd7a5SDimitry Andric       }
37400b57cec5SDimitry Andric 
37410b57cec5SDimitry Andric       break;
37420b57cec5SDimitry Andric     }
37430b57cec5SDimitry Andric     return nullptr;
37440b57cec5SDimitry Andric   };
37450b57cec5SDimitry Andric 
37460fca6ea1SDimitry Andric   const auto *Next = Current.Next;
37470fca6ea1SDimitry Andric   const bool IsCpp = LangOpts.CXXOperatorNames;
37480fca6ea1SDimitry Andric 
37490b57cec5SDimitry Andric   // Find parentheses of parameter list.
37500b57cec5SDimitry Andric   if (Current.is(tok::kw_operator)) {
37510fca6ea1SDimitry Andric     if (Previous.Tok.getIdentifierInfo() &&
37520fca6ea1SDimitry Andric         !Previous.isOneOf(tok::kw_return, tok::kw_co_return)) {
375306c3fb27SDimitry Andric       return true;
375406c3fb27SDimitry Andric     }
37550fca6ea1SDimitry Andric     if (Previous.is(tok::r_paren) && Previous.is(TT_TypeDeclarationParen)) {
37560fca6ea1SDimitry Andric       assert(Previous.MatchingParen);
37570fca6ea1SDimitry Andric       assert(Previous.MatchingParen->is(tok::l_paren));
37580fca6ea1SDimitry Andric       assert(Previous.MatchingParen->is(TT_TypeDeclarationParen));
3759b121cb00SDimitry Andric       return true;
3760b121cb00SDimitry Andric     }
37610fca6ea1SDimitry Andric     if (!Previous.isPointerOrReference() && Previous.isNot(TT_TemplateCloser))
37620b57cec5SDimitry Andric       return false;
37630b57cec5SDimitry Andric     Next = skipOperatorName(Next);
37640b57cec5SDimitry Andric   } else {
37655f757f3fSDimitry Andric     if (Current.isNot(TT_StartOfName) || Current.NestingLevel != 0)
37660b57cec5SDimitry Andric       return false;
37670b57cec5SDimitry Andric     for (; Next; Next = Next->Next) {
3768bdd1243dSDimitry Andric       if (Next->is(TT_TemplateOpener) && Next->MatchingParen) {
37690b57cec5SDimitry Andric         Next = Next->MatchingParen;
37700b57cec5SDimitry Andric       } else if (Next->is(tok::coloncolon)) {
37710b57cec5SDimitry Andric         Next = Next->Next;
37720b57cec5SDimitry Andric         if (!Next)
37730b57cec5SDimitry Andric           return false;
37740b57cec5SDimitry Andric         if (Next->is(tok::kw_operator)) {
37750b57cec5SDimitry Andric           Next = skipOperatorName(Next->Next);
37760b57cec5SDimitry Andric           break;
37770b57cec5SDimitry Andric         }
37785f757f3fSDimitry Andric         if (Next->isNot(tok::identifier))
37790b57cec5SDimitry Andric           return false;
3780bdd1243dSDimitry Andric       } else if (isCppAttribute(IsCpp, *Next)) {
3781bdd1243dSDimitry Andric         Next = Next->MatchingParen;
3782bdd1243dSDimitry Andric         if (!Next)
3783bdd1243dSDimitry Andric           return false;
37840b57cec5SDimitry Andric       } else if (Next->is(tok::l_paren)) {
37850b57cec5SDimitry Andric         break;
37860b57cec5SDimitry Andric       } else {
37870b57cec5SDimitry Andric         return false;
37880b57cec5SDimitry Andric       }
37890b57cec5SDimitry Andric     }
37900b57cec5SDimitry Andric   }
37910b57cec5SDimitry Andric 
37920b57cec5SDimitry Andric   // Check whether parameter list can belong to a function declaration.
37935f757f3fSDimitry Andric   if (!Next || Next->isNot(tok::l_paren) || !Next->MatchingParen)
37940b57cec5SDimitry Andric     return false;
37955f757f3fSDimitry Andric   ClosingParen = Next->MatchingParen;
37965f757f3fSDimitry Andric   assert(ClosingParen->is(tok::r_paren));
3797349cc55cSDimitry Andric   // If the lines ends with "{", this is likely a function definition.
37980b57cec5SDimitry Andric   if (Line.Last->is(tok::l_brace))
37990b57cec5SDimitry Andric     return true;
38005f757f3fSDimitry Andric   if (Next->Next == ClosingParen)
38010b57cec5SDimitry Andric     return true; // Empty parentheses.
38020b57cec5SDimitry Andric   // If there is an &/&& after the r_paren, this is likely a function.
38035f757f3fSDimitry Andric   if (ClosingParen->Next && ClosingParen->Next->is(TT_PointerOrReference))
38040b57cec5SDimitry Andric     return true;
38058c6f6c0cSDimitry Andric 
38068c6f6c0cSDimitry Andric   // Check for K&R C function definitions (and C++ function definitions with
38078c6f6c0cSDimitry Andric   // unnamed parameters), e.g.:
3808fe6060f1SDimitry Andric   //   int f(i)
3809fe6060f1SDimitry Andric   //   {
3810fe6060f1SDimitry Andric   //     return i + 1;
3811fe6060f1SDimitry Andric   //   }
38128c6f6c0cSDimitry Andric   //   bool g(size_t = 0, bool b = false)
38138c6f6c0cSDimitry Andric   //   {
38148c6f6c0cSDimitry Andric   //     return !b;
38158c6f6c0cSDimitry Andric   //   }
38168c6f6c0cSDimitry Andric   if (IsCpp && Next->Next && Next->Next->is(tok::identifier) &&
381781ad6265SDimitry Andric       !Line.endsWith(tok::semi)) {
3818fe6060f1SDimitry Andric     return true;
381981ad6265SDimitry Andric   }
38208c6f6c0cSDimitry Andric 
38215f757f3fSDimitry Andric   for (const FormatToken *Tok = Next->Next; Tok && Tok != ClosingParen;
38220b57cec5SDimitry Andric        Tok = Tok->Next) {
3823e8d8bef9SDimitry Andric     if (Tok->is(TT_TypeDeclarationParen))
3824e8d8bef9SDimitry Andric       return true;
38250b57cec5SDimitry Andric     if (Tok->isOneOf(tok::l_paren, TT_TemplateOpener) && Tok->MatchingParen) {
38260b57cec5SDimitry Andric       Tok = Tok->MatchingParen;
38270b57cec5SDimitry Andric       continue;
38280b57cec5SDimitry Andric     }
38290fca6ea1SDimitry Andric     if (Tok->is(tok::kw_const) || Tok->isTypeName(LangOpts) ||
38300fca6ea1SDimitry Andric         Tok->isOneOf(TT_PointerOrReference, TT_StartOfName, tok::ellipsis)) {
38310b57cec5SDimitry Andric       return true;
383281ad6265SDimitry Andric     }
38335f757f3fSDimitry Andric     if (Tok->isOneOf(tok::l_brace, TT_ObjCMethodExpr) || Tok->Tok.isLiteral())
38340b57cec5SDimitry Andric       return false;
38350b57cec5SDimitry Andric   }
38360b57cec5SDimitry Andric   return false;
38370b57cec5SDimitry Andric }
38380b57cec5SDimitry Andric 
38390b57cec5SDimitry Andric bool TokenAnnotator::mustBreakForReturnType(const AnnotatedLine &Line) const {
38400b57cec5SDimitry Andric   assert(Line.MightBeFunctionDecl);
38410b57cec5SDimitry Andric 
38420fca6ea1SDimitry Andric   if ((Style.BreakAfterReturnType == FormatStyle::RTBS_TopLevel ||
38430fca6ea1SDimitry Andric        Style.BreakAfterReturnType == FormatStyle::RTBS_TopLevelDefinitions) &&
384481ad6265SDimitry Andric       Line.Level > 0) {
38450b57cec5SDimitry Andric     return false;
384681ad6265SDimitry Andric   }
38470b57cec5SDimitry Andric 
38480fca6ea1SDimitry Andric   switch (Style.BreakAfterReturnType) {
38490b57cec5SDimitry Andric   case FormatStyle::RTBS_None:
38500fca6ea1SDimitry Andric   case FormatStyle::RTBS_Automatic:
38510fca6ea1SDimitry Andric   case FormatStyle::RTBS_ExceptShortType:
38520b57cec5SDimitry Andric     return false;
38530b57cec5SDimitry Andric   case FormatStyle::RTBS_All:
38540b57cec5SDimitry Andric   case FormatStyle::RTBS_TopLevel:
38550b57cec5SDimitry Andric     return true;
38560b57cec5SDimitry Andric   case FormatStyle::RTBS_AllDefinitions:
38570b57cec5SDimitry Andric   case FormatStyle::RTBS_TopLevelDefinitions:
38580b57cec5SDimitry Andric     return Line.mightBeFunctionDefinition();
38590b57cec5SDimitry Andric   }
38600b57cec5SDimitry Andric 
38610b57cec5SDimitry Andric   return false;
38620b57cec5SDimitry Andric }
38630b57cec5SDimitry Andric 
386481ad6265SDimitry Andric void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) const {
386504eeddc0SDimitry Andric   for (AnnotatedLine *ChildLine : Line.Children)
386604eeddc0SDimitry Andric     calculateFormattingInformation(*ChildLine);
38670b57cec5SDimitry Andric 
3868dfa39133SDimitry Andric   auto *First = Line.First;
3869dfa39133SDimitry Andric   First->TotalLength = First->IsMultiline
3870dfa39133SDimitry Andric                            ? Style.ColumnLimit
3871dfa39133SDimitry Andric                            : Line.FirstStartColumn + First->ColumnWidth;
3872dfa39133SDimitry Andric   FormatToken *Current = First->Next;
38730b57cec5SDimitry Andric   bool InFunctionDecl = Line.MightBeFunctionDecl;
3874fe6060f1SDimitry Andric   bool AlignArrayOfStructures =
3875fe6060f1SDimitry Andric       (Style.AlignArrayOfStructures != FormatStyle::AIAS_None &&
3876fe6060f1SDimitry Andric        Line.Type == LT_ArrayOfStructInitializer);
3877fe6060f1SDimitry Andric   if (AlignArrayOfStructures)
3878fe6060f1SDimitry Andric     calculateArrayInitializerColumnList(Line);
3879fe6060f1SDimitry Andric 
38805f757f3fSDimitry Andric   bool SeenName = false;
388106c3fb27SDimitry Andric   bool LineIsFunctionDeclaration = false;
38825f757f3fSDimitry Andric   FormatToken *ClosingParen = nullptr;
38835f757f3fSDimitry Andric   FormatToken *AfterLastAttribute = nullptr;
38845f757f3fSDimitry Andric 
38855f757f3fSDimitry Andric   for (auto *Tok = Current; Tok; Tok = Tok->Next) {
38865f757f3fSDimitry Andric     if (Tok->is(TT_StartOfName))
38875f757f3fSDimitry Andric       SeenName = true;
3888bdd1243dSDimitry Andric     if (Tok->Previous->EndsCppAttributeGroup)
3889bdd1243dSDimitry Andric       AfterLastAttribute = Tok;
38905f757f3fSDimitry Andric     if (const bool IsCtorOrDtor = Tok->is(TT_CtorDtorDeclName);
38915f757f3fSDimitry Andric         IsCtorOrDtor ||
38920fca6ea1SDimitry Andric         isFunctionDeclarationName(LangOpts, *Tok, Line, ClosingParen)) {
3893dfa39133SDimitry Andric       if (!IsCtorOrDtor)
38945f757f3fSDimitry Andric         Tok->setFinalizedType(TT_FunctionDeclarationName);
3895dfa39133SDimitry Andric       LineIsFunctionDeclaration = true;
38965f757f3fSDimitry Andric       SeenName = true;
38970fca6ea1SDimitry Andric       if (ClosingParen) {
38980fca6ea1SDimitry Andric         auto *OpeningParen = ClosingParen->MatchingParen;
38990fca6ea1SDimitry Andric         assert(OpeningParen);
39000fca6ea1SDimitry Andric         if (OpeningParen->is(TT_Unknown))
39010fca6ea1SDimitry Andric           OpeningParen->setType(TT_FunctionDeclarationLParen);
39020fca6ea1SDimitry Andric       }
39035f757f3fSDimitry Andric       break;
39045f757f3fSDimitry Andric     }
3905bdd1243dSDimitry Andric   }
3906bdd1243dSDimitry Andric 
3907dfa39133SDimitry Andric   if (IsCpp && (LineIsFunctionDeclaration || First->is(TT_CtorDtorDeclName)) &&
39085f757f3fSDimitry Andric       Line.endsWith(tok::semi, tok::r_brace)) {
39095f757f3fSDimitry Andric     auto *Tok = Line.Last->Previous;
39105f757f3fSDimitry Andric     while (Tok->isNot(tok::r_brace))
39115f757f3fSDimitry Andric       Tok = Tok->Previous;
39125f757f3fSDimitry Andric     if (auto *LBrace = Tok->MatchingParen; LBrace) {
39135f757f3fSDimitry Andric       assert(LBrace->is(tok::l_brace));
39145f757f3fSDimitry Andric       Tok->setBlockKind(BK_Block);
39155f757f3fSDimitry Andric       LBrace->setBlockKind(BK_Block);
39165f757f3fSDimitry Andric       LBrace->setFinalizedType(TT_FunctionLBrace);
39175f757f3fSDimitry Andric     }
39185f757f3fSDimitry Andric   }
39195f757f3fSDimitry Andric 
39205f757f3fSDimitry Andric   if (IsCpp && SeenName && AfterLastAttribute &&
39215f757f3fSDimitry Andric       mustBreakAfterAttributes(*AfterLastAttribute, Style)) {
39225f757f3fSDimitry Andric     AfterLastAttribute->MustBreakBefore = true;
39235f757f3fSDimitry Andric     if (LineIsFunctionDeclaration)
39245f757f3fSDimitry Andric       Line.ReturnTypeWrapped = true;
39255f757f3fSDimitry Andric   }
39265f757f3fSDimitry Andric 
39275f757f3fSDimitry Andric   if (IsCpp) {
39285f757f3fSDimitry Andric     if (!LineIsFunctionDeclaration) {
392906c3fb27SDimitry Andric       // Annotate */&/&& in `operator` function calls as binary operators.
3930dfa39133SDimitry Andric       for (const auto *Tok = First; Tok; Tok = Tok->Next) {
393106c3fb27SDimitry Andric         if (Tok->isNot(tok::kw_operator))
393206c3fb27SDimitry Andric           continue;
393306c3fb27SDimitry Andric         do {
393406c3fb27SDimitry Andric           Tok = Tok->Next;
393506c3fb27SDimitry Andric         } while (Tok && Tok->isNot(TT_OverloadedOperatorLParen));
39360fca6ea1SDimitry Andric         if (!Tok || !Tok->MatchingParen)
393706c3fb27SDimitry Andric           break;
393806c3fb27SDimitry Andric         const auto *LeftParen = Tok;
393906c3fb27SDimitry Andric         for (Tok = Tok->Next; Tok && Tok != LeftParen->MatchingParen;
394006c3fb27SDimitry Andric              Tok = Tok->Next) {
394106c3fb27SDimitry Andric           if (Tok->isNot(tok::identifier))
394206c3fb27SDimitry Andric             continue;
394306c3fb27SDimitry Andric           auto *Next = Tok->Next;
394406c3fb27SDimitry Andric           const bool NextIsBinaryOperator =
39455f757f3fSDimitry Andric               Next && Next->isPointerOrReference() && Next->Next &&
39465f757f3fSDimitry Andric               Next->Next->is(tok::identifier);
394706c3fb27SDimitry Andric           if (!NextIsBinaryOperator)
394806c3fb27SDimitry Andric             continue;
394906c3fb27SDimitry Andric           Next->setType(TT_BinaryOperator);
395006c3fb27SDimitry Andric           Tok = Next;
395106c3fb27SDimitry Andric         }
395206c3fb27SDimitry Andric       }
39535f757f3fSDimitry Andric     } else if (ClosingParen) {
39545f757f3fSDimitry Andric       for (auto *Tok = ClosingParen->Next; Tok; Tok = Tok->Next) {
39555678d1d9SDimitry Andric         if (Tok->is(TT_CtorInitializerColon))
39565678d1d9SDimitry Andric           break;
39575f757f3fSDimitry Andric         if (Tok->is(tok::arrow)) {
39585f757f3fSDimitry Andric           Tok->setType(TT_TrailingReturnArrow);
39595f757f3fSDimitry Andric           break;
39605f757f3fSDimitry Andric         }
39615f757f3fSDimitry Andric         if (Tok->isNot(TT_TrailingAnnotation))
39625f757f3fSDimitry Andric           continue;
39635f757f3fSDimitry Andric         const auto *Next = Tok->Next;
39645f757f3fSDimitry Andric         if (!Next || Next->isNot(tok::l_paren))
39655f757f3fSDimitry Andric           continue;
39665f757f3fSDimitry Andric         Tok = Next->MatchingParen;
39675f757f3fSDimitry Andric         if (!Tok)
39685f757f3fSDimitry Andric           break;
39695f757f3fSDimitry Andric       }
39705f757f3fSDimitry Andric     }
397106c3fb27SDimitry Andric   }
397206c3fb27SDimitry Andric 
39730b57cec5SDimitry Andric   while (Current) {
397404eeddc0SDimitry Andric     const FormatToken *Prev = Current->Previous;
39750b57cec5SDimitry Andric     if (Current->is(TT_LineComment)) {
397681ad6265SDimitry Andric       if (Prev->is(BK_BracedInit) && Prev->opensScope()) {
3977a7dea167SDimitry Andric         Current->SpacesRequiredBefore =
397806c3fb27SDimitry Andric             (Style.Cpp11BracedListStyle && !Style.SpacesInParensOptions.Other)
397906c3fb27SDimitry Andric                 ? 0
398006c3fb27SDimitry Andric                 : 1;
398106c3fb27SDimitry Andric       } else if (Prev->is(TT_VerilogMultiLineListLParen)) {
398206c3fb27SDimitry Andric         Current->SpacesRequiredBefore = 0;
398381ad6265SDimitry Andric       } else {
39840b57cec5SDimitry Andric         Current->SpacesRequiredBefore = Style.SpacesBeforeTrailingComments;
398581ad6265SDimitry Andric       }
39860b57cec5SDimitry Andric 
39870b57cec5SDimitry Andric       // If we find a trailing comment, iterate backwards to determine whether
39880b57cec5SDimitry Andric       // it seems to relate to a specific parameter. If so, break before that
39890b57cec5SDimitry Andric       // parameter to avoid changing the comment's meaning. E.g. don't move 'b'
39900b57cec5SDimitry Andric       // to the previous line in:
39910b57cec5SDimitry Andric       //   SomeFunction(a,
39920b57cec5SDimitry Andric       //                b, // comment
39930b57cec5SDimitry Andric       //                c);
39940b57cec5SDimitry Andric       if (!Current->HasUnescapedNewline) {
39950b57cec5SDimitry Andric         for (FormatToken *Parameter = Current->Previous; Parameter;
39960b57cec5SDimitry Andric              Parameter = Parameter->Previous) {
39970b57cec5SDimitry Andric           if (Parameter->isOneOf(tok::comment, tok::r_brace))
39980b57cec5SDimitry Andric             break;
39990b57cec5SDimitry Andric           if (Parameter->Previous && Parameter->Previous->is(tok::comma)) {
40005f757f3fSDimitry Andric             if (Parameter->Previous->isNot(TT_CtorInitializerComma) &&
400181ad6265SDimitry Andric                 Parameter->HasUnescapedNewline) {
40020b57cec5SDimitry Andric               Parameter->MustBreakBefore = true;
400381ad6265SDimitry Andric             }
40040b57cec5SDimitry Andric             break;
40050b57cec5SDimitry Andric           }
40060b57cec5SDimitry Andric         }
40070b57cec5SDimitry Andric       }
40085f757f3fSDimitry Andric     } else if (!Current->Finalized && Current->SpacesRequiredBefore == 0 &&
40090b57cec5SDimitry Andric                spaceRequiredBefore(Line, *Current)) {
40100b57cec5SDimitry Andric       Current->SpacesRequiredBefore = 1;
40110b57cec5SDimitry Andric     }
40120b57cec5SDimitry Andric 
401381ad6265SDimitry Andric     const auto &Children = Prev->Children;
401481ad6265SDimitry Andric     if (!Children.empty() && Children.back()->Last->is(TT_LineComment)) {
401581ad6265SDimitry Andric       Current->MustBreakBefore = true;
401681ad6265SDimitry Andric     } else {
40170b57cec5SDimitry Andric       Current->MustBreakBefore =
40180b57cec5SDimitry Andric           Current->MustBreakBefore || mustBreakBefore(Line, *Current);
40190b57cec5SDimitry Andric       if (!Current->MustBreakBefore && InFunctionDecl &&
402081ad6265SDimitry Andric           Current->is(TT_FunctionDeclarationName)) {
40210b57cec5SDimitry Andric         Current->MustBreakBefore = mustBreakForReturnType(Line);
402281ad6265SDimitry Andric       }
402381ad6265SDimitry Andric     }
40240b57cec5SDimitry Andric 
40250b57cec5SDimitry Andric     Current->CanBreakBefore =
40260b57cec5SDimitry Andric         Current->MustBreakBefore || canBreakBefore(Line, *Current);
40270b57cec5SDimitry Andric     unsigned ChildSize = 0;
402804eeddc0SDimitry Andric     if (Prev->Children.size() == 1) {
402904eeddc0SDimitry Andric       FormatToken &LastOfChild = *Prev->Children[0]->Last;
40300b57cec5SDimitry Andric       ChildSize = LastOfChild.isTrailingComment() ? Style.ColumnLimit
40310b57cec5SDimitry Andric                                                   : LastOfChild.TotalLength + 1;
40320b57cec5SDimitry Andric     }
40330b57cec5SDimitry Andric     if (Current->MustBreakBefore || Prev->Children.size() > 1 ||
40340b57cec5SDimitry Andric         (Prev->Children.size() == 1 &&
40350b57cec5SDimitry Andric          Prev->Children[0]->First->MustBreakBefore) ||
403681ad6265SDimitry Andric         Current->IsMultiline) {
40370b57cec5SDimitry Andric       Current->TotalLength = Prev->TotalLength + Style.ColumnLimit;
403881ad6265SDimitry Andric     } else {
40390b57cec5SDimitry Andric       Current->TotalLength = Prev->TotalLength + Current->ColumnWidth +
40400b57cec5SDimitry Andric                              ChildSize + Current->SpacesRequiredBefore;
404181ad6265SDimitry Andric     }
40420b57cec5SDimitry Andric 
40430b57cec5SDimitry Andric     if (Current->is(TT_CtorInitializerColon))
40440b57cec5SDimitry Andric       InFunctionDecl = false;
40450b57cec5SDimitry Andric 
40460b57cec5SDimitry Andric     // FIXME: Only calculate this if CanBreakBefore is true once static
40470b57cec5SDimitry Andric     // initializers etc. are sorted out.
40480b57cec5SDimitry Andric     // FIXME: Move magic numbers to a better place.
40490b57cec5SDimitry Andric 
40500b57cec5SDimitry Andric     // Reduce penalty for aligning ObjC method arguments using the colon
40510b57cec5SDimitry Andric     // alignment as this is the canonical way (still prefer fitting everything
40520b57cec5SDimitry Andric     // into one line if possible). Trying to fit a whole expression into one
40530b57cec5SDimitry Andric     // line should not force other line breaks (e.g. when ObjC method
40540b57cec5SDimitry Andric     // expression is a part of other expression).
40550b57cec5SDimitry Andric     Current->SplitPenalty = splitPenalty(Line, *Current, InFunctionDecl);
40560b57cec5SDimitry Andric     if (Style.Language == FormatStyle::LK_ObjC &&
40570b57cec5SDimitry Andric         Current->is(TT_SelectorName) && Current->ParameterIndex > 0) {
40580b57cec5SDimitry Andric       if (Current->ParameterIndex == 1)
40590b57cec5SDimitry Andric         Current->SplitPenalty += 5 * Current->BindingStrength;
40600b57cec5SDimitry Andric     } else {
40610b57cec5SDimitry Andric       Current->SplitPenalty += 20 * Current->BindingStrength;
40620b57cec5SDimitry Andric     }
40630b57cec5SDimitry Andric 
40640b57cec5SDimitry Andric     Current = Current->Next;
40650b57cec5SDimitry Andric   }
40660b57cec5SDimitry Andric 
40670b57cec5SDimitry Andric   calculateUnbreakableTailLengths(Line);
40680b57cec5SDimitry Andric   unsigned IndentLevel = Line.Level;
4069dfa39133SDimitry Andric   for (Current = First; Current; Current = Current->Next) {
40700b57cec5SDimitry Andric     if (Current->Role)
40710b57cec5SDimitry Andric       Current->Role->precomputeFormattingInfos(Current);
40720b57cec5SDimitry Andric     if (Current->MatchingParen &&
40734824e7fdSDimitry Andric         Current->MatchingParen->opensBlockOrBlockTypeList(Style) &&
40744824e7fdSDimitry Andric         IndentLevel > 0) {
40750b57cec5SDimitry Andric       --IndentLevel;
40760b57cec5SDimitry Andric     }
40770b57cec5SDimitry Andric     Current->IndentLevel = IndentLevel;
40780b57cec5SDimitry Andric     if (Current->opensBlockOrBlockTypeList(Style))
40790b57cec5SDimitry Andric       ++IndentLevel;
40800b57cec5SDimitry Andric   }
40810b57cec5SDimitry Andric 
40820b57cec5SDimitry Andric   LLVM_DEBUG({ printDebugInfo(Line); });
40830b57cec5SDimitry Andric }
40840b57cec5SDimitry Andric 
408581ad6265SDimitry Andric void TokenAnnotator::calculateUnbreakableTailLengths(
408681ad6265SDimitry Andric     AnnotatedLine &Line) const {
40870b57cec5SDimitry Andric   unsigned UnbreakableTailLength = 0;
40880b57cec5SDimitry Andric   FormatToken *Current = Line.Last;
40890b57cec5SDimitry Andric   while (Current) {
40900b57cec5SDimitry Andric     Current->UnbreakableTailLength = UnbreakableTailLength;
40910b57cec5SDimitry Andric     if (Current->CanBreakBefore ||
40920b57cec5SDimitry Andric         Current->isOneOf(tok::comment, tok::string_literal)) {
40930b57cec5SDimitry Andric       UnbreakableTailLength = 0;
40940b57cec5SDimitry Andric     } else {
40950b57cec5SDimitry Andric       UnbreakableTailLength +=
40960b57cec5SDimitry Andric           Current->ColumnWidth + Current->SpacesRequiredBefore;
40970b57cec5SDimitry Andric     }
40980b57cec5SDimitry Andric     Current = Current->Previous;
40990b57cec5SDimitry Andric   }
41000b57cec5SDimitry Andric }
41010b57cec5SDimitry Andric 
410281ad6265SDimitry Andric void TokenAnnotator::calculateArrayInitializerColumnList(
410381ad6265SDimitry Andric     AnnotatedLine &Line) const {
410481ad6265SDimitry Andric   if (Line.First == Line.Last)
4105fe6060f1SDimitry Andric     return;
4106fe6060f1SDimitry Andric   auto *CurrentToken = Line.First;
4107fe6060f1SDimitry Andric   CurrentToken->ArrayInitializerLineStart = true;
4108fe6060f1SDimitry Andric   unsigned Depth = 0;
410906c3fb27SDimitry Andric   while (CurrentToken && CurrentToken != Line.Last) {
4110fe6060f1SDimitry Andric     if (CurrentToken->is(tok::l_brace)) {
4111fe6060f1SDimitry Andric       CurrentToken->IsArrayInitializer = true;
411206c3fb27SDimitry Andric       if (CurrentToken->Next)
4113fe6060f1SDimitry Andric         CurrentToken->Next->MustBreakBefore = true;
4114fe6060f1SDimitry Andric       CurrentToken =
4115fe6060f1SDimitry Andric           calculateInitializerColumnList(Line, CurrentToken->Next, Depth + 1);
4116fe6060f1SDimitry Andric     } else {
4117fe6060f1SDimitry Andric       CurrentToken = CurrentToken->Next;
4118fe6060f1SDimitry Andric     }
4119fe6060f1SDimitry Andric   }
4120fe6060f1SDimitry Andric }
4121fe6060f1SDimitry Andric 
4122fe6060f1SDimitry Andric FormatToken *TokenAnnotator::calculateInitializerColumnList(
412381ad6265SDimitry Andric     AnnotatedLine &Line, FormatToken *CurrentToken, unsigned Depth) const {
412406c3fb27SDimitry Andric   while (CurrentToken && CurrentToken != Line.Last) {
4125fe6060f1SDimitry Andric     if (CurrentToken->is(tok::l_brace))
4126fe6060f1SDimitry Andric       ++Depth;
4127fe6060f1SDimitry Andric     else if (CurrentToken->is(tok::r_brace))
4128fe6060f1SDimitry Andric       --Depth;
4129fe6060f1SDimitry Andric     if (Depth == 2 && CurrentToken->isOneOf(tok::l_brace, tok::comma)) {
4130fe6060f1SDimitry Andric       CurrentToken = CurrentToken->Next;
413106c3fb27SDimitry Andric       if (!CurrentToken)
4132fe6060f1SDimitry Andric         break;
4133fe6060f1SDimitry Andric       CurrentToken->StartsColumn = true;
4134fe6060f1SDimitry Andric       CurrentToken = CurrentToken->Previous;
4135fe6060f1SDimitry Andric     }
4136fe6060f1SDimitry Andric     CurrentToken = CurrentToken->Next;
4137fe6060f1SDimitry Andric   }
4138fe6060f1SDimitry Andric   return CurrentToken;
4139fe6060f1SDimitry Andric }
4140fe6060f1SDimitry Andric 
41410b57cec5SDimitry Andric unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line,
41420b57cec5SDimitry Andric                                       const FormatToken &Tok,
414381ad6265SDimitry Andric                                       bool InFunctionDecl) const {
41440b57cec5SDimitry Andric   const FormatToken &Left = *Tok.Previous;
41450b57cec5SDimitry Andric   const FormatToken &Right = Tok;
41460b57cec5SDimitry Andric 
41470b57cec5SDimitry Andric   if (Left.is(tok::semi))
41480b57cec5SDimitry Andric     return 0;
41490b57cec5SDimitry Andric 
4150bdd1243dSDimitry Andric   // Language specific handling.
41510b57cec5SDimitry Andric   if (Style.Language == FormatStyle::LK_Java) {
41520b57cec5SDimitry Andric     if (Right.isOneOf(Keywords.kw_extends, Keywords.kw_throws))
41530b57cec5SDimitry Andric       return 1;
41540b57cec5SDimitry Andric     if (Right.is(Keywords.kw_implements))
41550b57cec5SDimitry Andric       return 2;
41560b57cec5SDimitry Andric     if (Left.is(tok::comma) && Left.NestingLevel == 0)
41570b57cec5SDimitry Andric       return 3;
41580eae32dcSDimitry Andric   } else if (Style.isJavaScript()) {
41590b57cec5SDimitry Andric     if (Right.is(Keywords.kw_function) && Left.isNot(tok::comma))
41600b57cec5SDimitry Andric       return 100;
41610b57cec5SDimitry Andric     if (Left.is(TT_JsTypeColon))
41620b57cec5SDimitry Andric       return 35;
41635f757f3fSDimitry Andric     if ((Left.is(TT_TemplateString) && Left.TokenText.ends_with("${")) ||
41645f757f3fSDimitry Andric         (Right.is(TT_TemplateString) && Right.TokenText.starts_with("}"))) {
41650b57cec5SDimitry Andric       return 100;
416681ad6265SDimitry Andric     }
41670b57cec5SDimitry Andric     // Prefer breaking call chains (".foo") over empty "{}", "[]" or "()".
41680b57cec5SDimitry Andric     if (Left.opensScope() && Right.closesScope())
41690b57cec5SDimitry Andric       return 200;
41705f757f3fSDimitry Andric   } else if (Style.Language == FormatStyle::LK_Proto) {
4171bdd1243dSDimitry Andric     if (Right.is(tok::l_square))
4172bdd1243dSDimitry Andric       return 1;
4173bdd1243dSDimitry Andric     if (Right.is(tok::period))
4174bdd1243dSDimitry Andric       return 500;
41750b57cec5SDimitry Andric   }
41760b57cec5SDimitry Andric 
41770b57cec5SDimitry Andric   if (Right.is(tok::identifier) && Right.Next && Right.Next->is(TT_DictLiteral))
41780b57cec5SDimitry Andric     return 1;
41790b57cec5SDimitry Andric   if (Right.is(tok::l_square)) {
41800b57cec5SDimitry Andric     if (Left.is(tok::r_square))
41810b57cec5SDimitry Andric       return 200;
41820b57cec5SDimitry Andric     // Slightly prefer formatting local lambda definitions like functions.
41830b57cec5SDimitry Andric     if (Right.is(TT_LambdaLSquare) && Left.is(tok::equal))
41840b57cec5SDimitry Andric       return 35;
41850b57cec5SDimitry Andric     if (!Right.isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
41860b57cec5SDimitry Andric                        TT_ArrayInitializerLSquare,
418781ad6265SDimitry Andric                        TT_DesignatedInitializerLSquare, TT_AttributeSquare)) {
41880b57cec5SDimitry Andric       return 500;
41890b57cec5SDimitry Andric     }
419081ad6265SDimitry Andric   }
41910b57cec5SDimitry Andric 
4192bdd1243dSDimitry Andric   if (Left.is(tok::coloncolon))
41937a6dacacSDimitry Andric     return Style.PenaltyBreakScopeResolution;
41940b57cec5SDimitry Andric   if (Right.isOneOf(TT_StartOfName, TT_FunctionDeclarationName) ||
41950b57cec5SDimitry Andric       Right.is(tok::kw_operator)) {
41960b57cec5SDimitry Andric     if (Line.startsWith(tok::kw_for) && Right.PartOfMultiVariableDeclStmt)
41970b57cec5SDimitry Andric       return 3;
41980b57cec5SDimitry Andric     if (Left.is(TT_StartOfName))
41990b57cec5SDimitry Andric       return 110;
42000b57cec5SDimitry Andric     if (InFunctionDecl && Right.NestingLevel == 0)
42010b57cec5SDimitry Andric       return Style.PenaltyReturnTypeOnItsOwnLine;
42020b57cec5SDimitry Andric     return 200;
42030b57cec5SDimitry Andric   }
42040b57cec5SDimitry Andric   if (Right.is(TT_PointerOrReference))
42050b57cec5SDimitry Andric     return 190;
42066c4b055cSDimitry Andric   if (Right.is(TT_LambdaArrow))
42070b57cec5SDimitry Andric     return 110;
42080b57cec5SDimitry Andric   if (Left.is(tok::equal) && Right.is(tok::l_brace))
42090b57cec5SDimitry Andric     return 160;
42100b57cec5SDimitry Andric   if (Left.is(TT_CastRParen))
42110b57cec5SDimitry Andric     return 100;
4212bdd1243dSDimitry Andric   if (Left.isOneOf(tok::kw_class, tok::kw_struct, tok::kw_union))
42130b57cec5SDimitry Andric     return 5000;
42140b57cec5SDimitry Andric   if (Left.is(tok::comment))
42150b57cec5SDimitry Andric     return 1000;
42160b57cec5SDimitry Andric 
42170b57cec5SDimitry Andric   if (Left.isOneOf(TT_RangeBasedForLoopColon, TT_InheritanceColon,
421881ad6265SDimitry Andric                    TT_CtorInitializerColon)) {
42190b57cec5SDimitry Andric     return 2;
422081ad6265SDimitry Andric   }
42210b57cec5SDimitry Andric 
42220b57cec5SDimitry Andric   if (Right.isMemberAccess()) {
42230b57cec5SDimitry Andric     // Breaking before the "./->" of a chained call/member access is reasonably
42240b57cec5SDimitry Andric     // cheap, as formatting those with one call per line is generally
42250b57cec5SDimitry Andric     // desirable. In particular, it should be cheaper to break before the call
42260b57cec5SDimitry Andric     // than it is to break inside a call's parameters, which could lead to weird
42270b57cec5SDimitry Andric     // "hanging" indents. The exception is the very last "./->" to support this
42280b57cec5SDimitry Andric     // frequent pattern:
42290b57cec5SDimitry Andric     //
42300b57cec5SDimitry Andric     //   aaaaaaaa.aaaaaaaa.bbbbbbb().ccccccccccccccccccccc(
42310b57cec5SDimitry Andric     //       dddddddd);
42320b57cec5SDimitry Andric     //
42330b57cec5SDimitry Andric     // which might otherwise be blown up onto many lines. Here, clang-format
42340b57cec5SDimitry Andric     // won't produce "hanging" indents anyway as there is no other trailing
42350b57cec5SDimitry Andric     // call.
42360b57cec5SDimitry Andric     //
42370b57cec5SDimitry Andric     // Also apply higher penalty is not a call as that might lead to a wrapping
42380b57cec5SDimitry Andric     // like:
42390b57cec5SDimitry Andric     //
42400b57cec5SDimitry Andric     //   aaaaaaa
42410b57cec5SDimitry Andric     //       .aaaaaaaaa.bbbbbbbb(cccccccc);
42420b57cec5SDimitry Andric     return !Right.NextOperator || !Right.NextOperator->Previous->closesScope()
42430b57cec5SDimitry Andric                ? 150
42440b57cec5SDimitry Andric                : 35;
42450b57cec5SDimitry Andric   }
42460b57cec5SDimitry Andric 
42470b57cec5SDimitry Andric   if (Right.is(TT_TrailingAnnotation) &&
42480b57cec5SDimitry Andric       (!Right.Next || Right.Next->isNot(tok::l_paren))) {
42490b57cec5SDimitry Andric     // Moving trailing annotations to the next line is fine for ObjC method
42500b57cec5SDimitry Andric     // declarations.
42510b57cec5SDimitry Andric     if (Line.startsWith(TT_ObjCMethodSpecifier))
42520b57cec5SDimitry Andric       return 10;
42530b57cec5SDimitry Andric     // Generally, breaking before a trailing annotation is bad unless it is
42540b57cec5SDimitry Andric     // function-like. It seems to be especially preferable to keep standard
42550b57cec5SDimitry Andric     // annotations (i.e. "const", "final" and "override") on the same line.
42560b57cec5SDimitry Andric     // Use a slightly higher penalty after ")" so that annotations like
42570b57cec5SDimitry Andric     // "const override" are kept together.
42580b57cec5SDimitry Andric     bool is_short_annotation = Right.TokenText.size() < 10;
42590b57cec5SDimitry Andric     return (Left.is(tok::r_paren) ? 100 : 120) + (is_short_annotation ? 50 : 0);
42600b57cec5SDimitry Andric   }
42610b57cec5SDimitry Andric 
42620b57cec5SDimitry Andric   // In for-loops, prefer breaking at ',' and ';'.
42630b57cec5SDimitry Andric   if (Line.startsWith(tok::kw_for) && Left.is(tok::equal))
42640b57cec5SDimitry Andric     return 4;
42650b57cec5SDimitry Andric 
42660b57cec5SDimitry Andric   // In Objective-C method expressions, prefer breaking before "param:" over
42670b57cec5SDimitry Andric   // breaking after it.
42680b57cec5SDimitry Andric   if (Right.is(TT_SelectorName))
42690b57cec5SDimitry Andric     return 0;
42700b57cec5SDimitry Andric   if (Left.is(tok::colon) && Left.is(TT_ObjCMethodExpr))
42710b57cec5SDimitry Andric     return Line.MightBeFunctionDecl ? 50 : 500;
42720b57cec5SDimitry Andric 
42730b57cec5SDimitry Andric   // In Objective-C type declarations, avoid breaking after the category's
42740b57cec5SDimitry Andric   // open paren (we'll prefer breaking after the protocol list's opening
42750b57cec5SDimitry Andric   // angle bracket, if present).
42760b57cec5SDimitry Andric   if (Line.Type == LT_ObjCDecl && Left.is(tok::l_paren) && Left.Previous &&
427781ad6265SDimitry Andric       Left.Previous->isOneOf(tok::identifier, tok::greater)) {
42780b57cec5SDimitry Andric     return 500;
427981ad6265SDimitry Andric   }
42800b57cec5SDimitry Andric 
428104eeddc0SDimitry Andric   if (Left.is(tok::l_paren) && Style.PenaltyBreakOpenParenthesis != 0)
428204eeddc0SDimitry Andric     return Style.PenaltyBreakOpenParenthesis;
42830b57cec5SDimitry Andric   if (Left.is(tok::l_paren) && InFunctionDecl &&
428481ad6265SDimitry Andric       Style.AlignAfterOpenBracket != FormatStyle::BAS_DontAlign) {
42850b57cec5SDimitry Andric     return 100;
428681ad6265SDimitry Andric   }
42870b57cec5SDimitry Andric   if (Left.is(tok::l_paren) && Left.Previous &&
4288bdd1243dSDimitry Andric       (Left.Previous->isOneOf(tok::kw_for, tok::kw__Generic) ||
4289bdd1243dSDimitry Andric        Left.Previous->isIf())) {
42900b57cec5SDimitry Andric     return 1000;
429181ad6265SDimitry Andric   }
42920b57cec5SDimitry Andric   if (Left.is(tok::equal) && InFunctionDecl)
42930b57cec5SDimitry Andric     return 110;
42940b57cec5SDimitry Andric   if (Right.is(tok::r_brace))
42950b57cec5SDimitry Andric     return 1;
42960b57cec5SDimitry Andric   if (Left.is(TT_TemplateOpener))
42970b57cec5SDimitry Andric     return 100;
42980b57cec5SDimitry Andric   if (Left.opensScope()) {
4299e8d8bef9SDimitry Andric     // If we aren't aligning after opening parens/braces we can always break
4300e8d8bef9SDimitry Andric     // here unless the style does not want us to place all arguments on the
4301e8d8bef9SDimitry Andric     // next line.
4302e8d8bef9SDimitry Andric     if (Style.AlignAfterOpenBracket == FormatStyle::BAS_DontAlign &&
430381ad6265SDimitry Andric         (Left.ParameterCount <= 1 || Style.AllowAllArgumentsOnNextLine)) {
43040b57cec5SDimitry Andric       return 0;
430581ad6265SDimitry Andric     }
43060b57cec5SDimitry Andric     if (Left.is(tok::l_brace) && !Style.Cpp11BracedListStyle)
43070b57cec5SDimitry Andric       return 19;
43080b57cec5SDimitry Andric     return Left.ParameterCount > 1 ? Style.PenaltyBreakBeforeFirstCallParameter
43090b57cec5SDimitry Andric                                    : 19;
43100b57cec5SDimitry Andric   }
43110b57cec5SDimitry Andric   if (Left.is(TT_JavaAnnotation))
43120b57cec5SDimitry Andric     return 50;
43130b57cec5SDimitry Andric 
4314a7dea167SDimitry Andric   if (Left.is(TT_UnaryOperator))
4315a7dea167SDimitry Andric     return 60;
43160b57cec5SDimitry Andric   if (Left.isOneOf(tok::plus, tok::comma) && Left.Previous &&
43170b57cec5SDimitry Andric       Left.Previous->isLabelString() &&
431881ad6265SDimitry Andric       (Left.NextOperator || Left.OperatorIndex != 0)) {
43190b57cec5SDimitry Andric     return 50;
432081ad6265SDimitry Andric   }
43210b57cec5SDimitry Andric   if (Right.is(tok::plus) && Left.isLabelString() &&
432281ad6265SDimitry Andric       (Right.NextOperator || Right.OperatorIndex != 0)) {
43230b57cec5SDimitry Andric     return 25;
432481ad6265SDimitry Andric   }
43250b57cec5SDimitry Andric   if (Left.is(tok::comma))
43260b57cec5SDimitry Andric     return 1;
43270b57cec5SDimitry Andric   if (Right.is(tok::lessless) && Left.isLabelString() &&
432881ad6265SDimitry Andric       (Right.NextOperator || Right.OperatorIndex != 1)) {
43290b57cec5SDimitry Andric     return 25;
433081ad6265SDimitry Andric   }
43310b57cec5SDimitry Andric   if (Right.is(tok::lessless)) {
43320b57cec5SDimitry Andric     // Breaking at a << is really cheap.
43335f757f3fSDimitry Andric     if (Left.isNot(tok::r_paren) || Right.OperatorIndex > 0) {
43340b57cec5SDimitry Andric       // Slightly prefer to break before the first one in log-like statements.
43350b57cec5SDimitry Andric       return 2;
433681ad6265SDimitry Andric     }
43370b57cec5SDimitry Andric     return 1;
43380b57cec5SDimitry Andric   }
43390b57cec5SDimitry Andric   if (Left.ClosesTemplateDeclaration)
43400b57cec5SDimitry Andric     return Style.PenaltyBreakTemplateDeclaration;
434181ad6265SDimitry Andric   if (Left.ClosesRequiresClause)
434281ad6265SDimitry Andric     return 0;
43430b57cec5SDimitry Andric   if (Left.is(TT_ConditionalExpr))
43440b57cec5SDimitry Andric     return prec::Conditional;
43450b57cec5SDimitry Andric   prec::Level Level = Left.getPrecedence();
43460b57cec5SDimitry Andric   if (Level == prec::Unknown)
43470b57cec5SDimitry Andric     Level = Right.getPrecedence();
43480b57cec5SDimitry Andric   if (Level == prec::Assignment)
43490b57cec5SDimitry Andric     return Style.PenaltyBreakAssignment;
43500b57cec5SDimitry Andric   if (Level != prec::Unknown)
43510b57cec5SDimitry Andric     return Level;
43520b57cec5SDimitry Andric 
43530b57cec5SDimitry Andric   return 3;
43540b57cec5SDimitry Andric }
43550b57cec5SDimitry Andric 
43560b57cec5SDimitry Andric bool TokenAnnotator::spaceRequiredBeforeParens(const FormatToken &Right) const {
435704eeddc0SDimitry Andric   if (Style.SpaceBeforeParens == FormatStyle::SBPO_Always)
435804eeddc0SDimitry Andric     return true;
435904eeddc0SDimitry Andric   if (Right.is(TT_OverloadedOperatorLParen) &&
436081ad6265SDimitry Andric       Style.SpaceBeforeParensOptions.AfterOverloadedOperator) {
436104eeddc0SDimitry Andric     return true;
436281ad6265SDimitry Andric   }
436304eeddc0SDimitry Andric   if (Style.SpaceBeforeParensOptions.BeforeNonEmptyParentheses &&
436481ad6265SDimitry Andric       Right.ParameterCount > 0) {
436504eeddc0SDimitry Andric     return true;
436681ad6265SDimitry Andric   }
436704eeddc0SDimitry Andric   return false;
43680b57cec5SDimitry Andric }
43690b57cec5SDimitry Andric 
43700b57cec5SDimitry Andric bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
43710b57cec5SDimitry Andric                                           const FormatToken &Left,
437281ad6265SDimitry Andric                                           const FormatToken &Right) const {
437381ad6265SDimitry Andric   if (Left.is(tok::kw_return) &&
437481ad6265SDimitry Andric       !Right.isOneOf(tok::semi, tok::r_paren, tok::hashhash)) {
43750b57cec5SDimitry Andric     return true;
437681ad6265SDimitry Andric   }
4377bdd1243dSDimitry Andric   if (Left.is(tok::kw_throw) && Right.is(tok::l_paren) && Right.MatchingParen &&
4378bdd1243dSDimitry Andric       Right.MatchingParen->is(TT_CastRParen)) {
4379bdd1243dSDimitry Andric     return true;
4380bdd1243dSDimitry Andric   }
43810b57cec5SDimitry Andric   if (Left.is(Keywords.kw_assert) && Style.Language == FormatStyle::LK_Java)
43820b57cec5SDimitry Andric     return true;
43830b57cec5SDimitry Andric   if (Style.ObjCSpaceAfterProperty && Line.Type == LT_ObjCProperty &&
438481ad6265SDimitry Andric       Left.Tok.getObjCKeywordID() == tok::objc_property) {
43850b57cec5SDimitry Andric     return true;
438681ad6265SDimitry Andric   }
43870b57cec5SDimitry Andric   if (Right.is(tok::hashhash))
43880b57cec5SDimitry Andric     return Left.is(tok::hash);
43890b57cec5SDimitry Andric   if (Left.isOneOf(tok::hashhash, tok::hash))
43900b57cec5SDimitry Andric     return Right.is(tok::hash);
43910fca6ea1SDimitry Andric   if (Left.is(BK_Block) && Right.is(tok::r_brace) &&
43920fca6ea1SDimitry Andric       Right.MatchingParen == &Left && Line.Children.empty()) {
43930fca6ea1SDimitry Andric     return Style.SpaceInEmptyBlock;
43940fca6ea1SDimitry Andric   }
4395a7dea167SDimitry Andric   if ((Left.is(tok::l_paren) && Right.is(tok::r_paren)) ||
4396e8d8bef9SDimitry Andric       (Left.is(tok::l_brace) && Left.isNot(BK_Block) &&
439781ad6265SDimitry Andric        Right.is(tok::r_brace) && Right.isNot(BK_Block))) {
439806c3fb27SDimitry Andric     return Style.SpacesInParensOptions.InEmptyParentheses;
439981ad6265SDimitry Andric   }
44000fca6ea1SDimitry Andric   if (Style.SpacesInParens == FormatStyle::SIPO_Custom &&
44010fca6ea1SDimitry Andric       Style.SpacesInParensOptions.ExceptDoubleParentheses &&
44020fca6ea1SDimitry Andric       Left.is(tok::r_paren) && Right.is(tok::r_paren)) {
44030fca6ea1SDimitry Andric     auto *InnerLParen = Left.MatchingParen;
44040fca6ea1SDimitry Andric     if (InnerLParen && InnerLParen->Previous == Right.MatchingParen) {
44050fca6ea1SDimitry Andric       InnerLParen->SpacesRequiredBefore = 0;
44060fca6ea1SDimitry Andric       return false;
44070fca6ea1SDimitry Andric     }
44080fca6ea1SDimitry Andric   }
440906c3fb27SDimitry Andric   if (Style.SpacesInParensOptions.InConditionalStatements) {
441081ad6265SDimitry Andric     const FormatToken *LeftParen = nullptr;
441181ad6265SDimitry Andric     if (Left.is(tok::l_paren))
441281ad6265SDimitry Andric       LeftParen = &Left;
441381ad6265SDimitry Andric     else if (Right.is(tok::r_paren) && Right.MatchingParen)
441481ad6265SDimitry Andric       LeftParen = Right.MatchingParen;
441506c3fb27SDimitry Andric     if (LeftParen) {
441606c3fb27SDimitry Andric       if (LeftParen->is(TT_ConditionLParen))
441706c3fb27SDimitry Andric         return true;
441806c3fb27SDimitry Andric       if (LeftParen->Previous && isKeywordWithCondition(*LeftParen->Previous))
4419480093f4SDimitry Andric         return true;
442081ad6265SDimitry Andric     }
4421480093f4SDimitry Andric   }
4422e8d8bef9SDimitry Andric 
4423bdd1243dSDimitry Andric   // trailing return type 'auto': []() -> auto {}, auto foo() -> auto {}
4424bdd1243dSDimitry Andric   if (Left.is(tok::kw_auto) && Right.isOneOf(TT_LambdaLBrace, TT_FunctionLBrace,
4425bdd1243dSDimitry Andric                                              // function return type 'auto'
4426bdd1243dSDimitry Andric                                              TT_FunctionTypeLParen)) {
4427bdd1243dSDimitry Andric     return true;
4428bdd1243dSDimitry Andric   }
4429bdd1243dSDimitry Andric 
4430349cc55cSDimitry Andric   // auto{x} auto(x)
4431349cc55cSDimitry Andric   if (Left.is(tok::kw_auto) && Right.isOneOf(tok::l_paren, tok::l_brace))
4432349cc55cSDimitry Andric     return false;
4433349cc55cSDimitry Andric 
44340fca6ea1SDimitry Andric   const auto *BeforeLeft = Left.Previous;
44350fca6ea1SDimitry Andric 
44364824e7fdSDimitry Andric   // operator co_await(x)
44370fca6ea1SDimitry Andric   if (Right.is(tok::l_paren) && Left.is(tok::kw_co_await) && BeforeLeft &&
44380fca6ea1SDimitry Andric       BeforeLeft->is(tok::kw_operator)) {
44394824e7fdSDimitry Andric     return false;
444081ad6265SDimitry Andric   }
44414824e7fdSDimitry Andric   // co_await (x), co_yield (x), co_return (x)
44424824e7fdSDimitry Andric   if (Left.isOneOf(tok::kw_co_await, tok::kw_co_yield, tok::kw_co_return) &&
444381ad6265SDimitry Andric       !Right.isOneOf(tok::semi, tok::r_paren)) {
44444824e7fdSDimitry Andric     return true;
444581ad6265SDimitry Andric   }
4446e8d8bef9SDimitry Andric 
444781ad6265SDimitry Andric   if (Left.is(tok::l_paren) || Right.is(tok::r_paren)) {
44480b57cec5SDimitry Andric     return (Right.is(TT_CastRParen) ||
44490b57cec5SDimitry Andric             (Left.MatchingParen && Left.MatchingParen->is(TT_CastRParen)))
445006c3fb27SDimitry Andric                ? Style.SpacesInParensOptions.InCStyleCasts
445106c3fb27SDimitry Andric                : Style.SpacesInParensOptions.Other;
445281ad6265SDimitry Andric   }
44530b57cec5SDimitry Andric   if (Right.isOneOf(tok::semi, tok::comma))
44540b57cec5SDimitry Andric     return false;
44550b57cec5SDimitry Andric   if (Right.is(tok::less) && Line.Type == LT_ObjCDecl) {
44560b57cec5SDimitry Andric     bool IsLightweightGeneric = Right.MatchingParen &&
44570b57cec5SDimitry Andric                                 Right.MatchingParen->Next &&
44580b57cec5SDimitry Andric                                 Right.MatchingParen->Next->is(tok::colon);
44590b57cec5SDimitry Andric     return !IsLightweightGeneric && Style.ObjCSpaceBeforeProtocolList;
44600b57cec5SDimitry Andric   }
44610b57cec5SDimitry Andric   if (Right.is(tok::less) && Left.is(tok::kw_template))
44620b57cec5SDimitry Andric     return Style.SpaceAfterTemplateKeyword;
44630b57cec5SDimitry Andric   if (Left.isOneOf(tok::exclaim, tok::tilde))
44640b57cec5SDimitry Andric     return false;
44650b57cec5SDimitry Andric   if (Left.is(tok::at) &&
44660b57cec5SDimitry Andric       Right.isOneOf(tok::identifier, tok::string_literal, tok::char_constant,
44670b57cec5SDimitry Andric                     tok::numeric_constant, tok::l_paren, tok::l_brace,
446881ad6265SDimitry Andric                     tok::kw_true, tok::kw_false)) {
44690b57cec5SDimitry Andric     return false;
447081ad6265SDimitry Andric   }
44710b57cec5SDimitry Andric   if (Left.is(tok::colon))
44725f757f3fSDimitry Andric     return Left.isNot(TT_ObjCMethodExpr);
44736c4b055cSDimitry Andric   if (Left.is(tok::coloncolon))
44746c4b055cSDimitry Andric     return false;
44750b57cec5SDimitry Andric   if (Left.is(tok::less) || Right.isOneOf(tok::greater, tok::less)) {
44760b57cec5SDimitry Andric     if (Style.Language == FormatStyle::LK_TextProto ||
44770b57cec5SDimitry Andric         (Style.Language == FormatStyle::LK_Proto &&
44780b57cec5SDimitry Andric          (Left.is(TT_DictLiteral) || Right.is(TT_DictLiteral)))) {
44790b57cec5SDimitry Andric       // Format empty list as `<>`.
44800b57cec5SDimitry Andric       if (Left.is(tok::less) && Right.is(tok::greater))
44810b57cec5SDimitry Andric         return false;
44820b57cec5SDimitry Andric       return !Style.Cpp11BracedListStyle;
44830b57cec5SDimitry Andric     }
4484bdd1243dSDimitry Andric     // Don't attempt to format operator<(), as it is handled later.
4485bdd1243dSDimitry Andric     if (Right.isNot(TT_OverloadedOperatorLParen))
44860b57cec5SDimitry Andric       return false;
44870b57cec5SDimitry Andric   }
448881ad6265SDimitry Andric   if (Right.is(tok::ellipsis)) {
44890fca6ea1SDimitry Andric     return Left.Tok.isLiteral() || (Left.is(tok::identifier) && BeforeLeft &&
44900fca6ea1SDimitry Andric                                     BeforeLeft->is(tok::kw_case));
449181ad6265SDimitry Andric   }
44920b57cec5SDimitry Andric   if (Left.is(tok::l_square) && Right.is(tok::amp))
4493480093f4SDimitry Andric     return Style.SpacesInSquareBrackets;
44940b57cec5SDimitry Andric   if (Right.is(TT_PointerOrReference)) {
44950b57cec5SDimitry Andric     if (Left.is(tok::r_paren) && Line.MightBeFunctionDecl) {
44960b57cec5SDimitry Andric       if (!Left.MatchingParen)
44970b57cec5SDimitry Andric         return true;
44980b57cec5SDimitry Andric       FormatToken *TokenBeforeMatchingParen =
44990b57cec5SDimitry Andric           Left.MatchingParen->getPreviousNonComment();
45005f757f3fSDimitry Andric       if (!TokenBeforeMatchingParen || Left.isNot(TT_TypeDeclarationParen))
45010b57cec5SDimitry Andric         return true;
45020b57cec5SDimitry Andric     }
4503349cc55cSDimitry Andric     // Add a space if the previous token is a pointer qualifier or the closing
4504e8d8bef9SDimitry Andric     // parenthesis of __attribute__(()) expression and the style requires spaces
4505e8d8bef9SDimitry Andric     // after pointer qualifiers.
4506e8d8bef9SDimitry Andric     if ((Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_After ||
4507e8d8bef9SDimitry Andric          Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_Both) &&
45085f757f3fSDimitry Andric         (Left.is(TT_AttributeRParen) ||
450981ad6265SDimitry Andric          Left.canBePointerOrReferenceQualifier())) {
4510e8d8bef9SDimitry Andric       return true;
451181ad6265SDimitry Andric     }
45120eae32dcSDimitry Andric     if (Left.Tok.isLiteral())
45130eae32dcSDimitry Andric       return true;
45140eae32dcSDimitry Andric     // for (auto a = 0, b = 0; const auto & c : {1, 2, 3})
45150fca6ea1SDimitry Andric     if (Left.isTypeOrIdentifier(LangOpts) && Right.Next && Right.Next->Next &&
451681ad6265SDimitry Andric         Right.Next->Next->is(TT_RangeBasedForLoopColon)) {
45170eae32dcSDimitry Andric       return getTokenPointerOrReferenceAlignment(Right) !=
45180eae32dcSDimitry Andric              FormatStyle::PAS_Left;
451981ad6265SDimitry Andric     }
452081ad6265SDimitry Andric     return !Left.isOneOf(TT_PointerOrReference, tok::l_paren) &&
452181ad6265SDimitry Andric            (getTokenPointerOrReferenceAlignment(Right) !=
452281ad6265SDimitry Andric                 FormatStyle::PAS_Left ||
45230b57cec5SDimitry Andric             (Line.IsMultiVariableDeclStmt &&
45240b57cec5SDimitry Andric              (Left.NestingLevel == 0 ||
452581ad6265SDimitry Andric               (Left.NestingLevel == 1 && startsWithInitStatement(Line)))));
45260b57cec5SDimitry Andric   }
45270b57cec5SDimitry Andric   if (Right.is(TT_FunctionTypeLParen) && Left.isNot(tok::l_paren) &&
45285f757f3fSDimitry Andric       (Left.isNot(TT_PointerOrReference) ||
4529fe6060f1SDimitry Andric        (getTokenPointerOrReferenceAlignment(Left) != FormatStyle::PAS_Right &&
453081ad6265SDimitry Andric         !Line.IsMultiVariableDeclStmt))) {
45310b57cec5SDimitry Andric     return true;
453281ad6265SDimitry Andric   }
4533e8d8bef9SDimitry Andric   if (Left.is(TT_PointerOrReference)) {
4534349cc55cSDimitry Andric     // Add a space if the next token is a pointer qualifier and the style
4535e8d8bef9SDimitry Andric     // requires spaces before pointer qualifiers.
4536e8d8bef9SDimitry Andric     if ((Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_Before ||
4537e8d8bef9SDimitry Andric          Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_Both) &&
453881ad6265SDimitry Andric         Right.canBePointerOrReferenceQualifier()) {
4539e8d8bef9SDimitry Andric       return true;
454081ad6265SDimitry Andric     }
45410eae32dcSDimitry Andric     // & 1
45420eae32dcSDimitry Andric     if (Right.Tok.isLiteral())
45430eae32dcSDimitry Andric       return true;
45440eae32dcSDimitry Andric     // & /* comment
45450eae32dcSDimitry Andric     if (Right.is(TT_BlockComment))
45460eae32dcSDimitry Andric       return true;
45470eae32dcSDimitry Andric     // foo() -> const Bar * override/final
454806c3fb27SDimitry Andric     // S::foo() & noexcept/requires
454906c3fb27SDimitry Andric     if (Right.isOneOf(Keywords.kw_override, Keywords.kw_final, tok::kw_noexcept,
455006c3fb27SDimitry Andric                       TT_RequiresClause) &&
45515f757f3fSDimitry Andric         Right.isNot(TT_StartOfName)) {
45520eae32dcSDimitry Andric       return true;
455381ad6265SDimitry Andric     }
45540eae32dcSDimitry Andric     // & {
45550eae32dcSDimitry Andric     if (Right.is(tok::l_brace) && Right.is(BK_Block))
45560eae32dcSDimitry Andric       return true;
45570eae32dcSDimitry Andric     // for (auto a = 0, b = 0; const auto& c : {1, 2, 3})
45580fca6ea1SDimitry Andric     if (BeforeLeft && BeforeLeft->isTypeOrIdentifier(LangOpts) && Right.Next &&
455981ad6265SDimitry Andric         Right.Next->is(TT_RangeBasedForLoopColon)) {
45600eae32dcSDimitry Andric       return getTokenPointerOrReferenceAlignment(Left) !=
45610eae32dcSDimitry Andric              FormatStyle::PAS_Right;
456281ad6265SDimitry Andric     }
456381ad6265SDimitry Andric     if (Right.isOneOf(TT_PointerOrReference, TT_ArraySubscriptLSquare,
456481ad6265SDimitry Andric                       tok::l_paren)) {
456581ad6265SDimitry Andric       return false;
456681ad6265SDimitry Andric     }
456781ad6265SDimitry Andric     if (getTokenPointerOrReferenceAlignment(Left) == FormatStyle::PAS_Right)
456881ad6265SDimitry Andric       return false;
456981ad6265SDimitry Andric     // FIXME: Setting IsMultiVariableDeclStmt for the whole line is error-prone,
457081ad6265SDimitry Andric     // because it does not take into account nested scopes like lambdas.
457181ad6265SDimitry Andric     // In multi-variable declaration statements, attach */& to the variable
457281ad6265SDimitry Andric     // independently of the style. However, avoid doing it if we are in a nested
457381ad6265SDimitry Andric     // scope, e.g. lambda. We still need to special-case statements with
457481ad6265SDimitry Andric     // initializers.
457581ad6265SDimitry Andric     if (Line.IsMultiVariableDeclStmt &&
457681ad6265SDimitry Andric         (Left.NestingLevel == Line.First->NestingLevel ||
457781ad6265SDimitry Andric          ((Left.NestingLevel == Line.First->NestingLevel + 1) &&
457881ad6265SDimitry Andric           startsWithInitStatement(Line)))) {
457981ad6265SDimitry Andric       return false;
458081ad6265SDimitry Andric     }
45810fca6ea1SDimitry Andric     if (!BeforeLeft)
45820fca6ea1SDimitry Andric       return false;
45830fca6ea1SDimitry Andric     if (BeforeLeft->is(tok::coloncolon)) {
45846c4b055cSDimitry Andric       if (Left.isNot(tok::star))
45856c4b055cSDimitry Andric         return false;
45866c4b055cSDimitry Andric       assert(Style.PointerAlignment != FormatStyle::PAS_Right);
45876c4b055cSDimitry Andric       if (!Right.startsSequence(tok::identifier, tok::r_paren))
45886c4b055cSDimitry Andric         return true;
45896c4b055cSDimitry Andric       assert(Right.Next);
45906c4b055cSDimitry Andric       const auto *LParen = Right.Next->MatchingParen;
45916c4b055cSDimitry Andric       return !LParen || LParen->isNot(TT_FunctionTypeLParen);
45920fca6ea1SDimitry Andric     }
45930fca6ea1SDimitry Andric     return !BeforeLeft->isOneOf(tok::l_paren, tok::l_square);
4594e8d8bef9SDimitry Andric   }
4595349cc55cSDimitry Andric   // Ensure right pointer alignment with ellipsis e.g. int *...P
45960fca6ea1SDimitry Andric   if (Left.is(tok::ellipsis) && BeforeLeft &&
45970fca6ea1SDimitry Andric       BeforeLeft->isPointerOrReference()) {
45985ffd83dbSDimitry Andric     return Style.PointerAlignment != FormatStyle::PAS_Right;
459981ad6265SDimitry Andric   }
46005ffd83dbSDimitry Andric 
46010b57cec5SDimitry Andric   if (Right.is(tok::star) && Left.is(tok::l_paren))
46020b57cec5SDimitry Andric     return false;
46035f757f3fSDimitry Andric   if (Left.is(tok::star) && Right.isPointerOrReference())
4604d65cd7a5SDimitry Andric     return false;
46055f757f3fSDimitry Andric   if (Right.isPointerOrReference()) {
4606d65cd7a5SDimitry Andric     const FormatToken *Previous = &Left;
46075f757f3fSDimitry Andric     while (Previous && Previous->isNot(tok::kw_operator)) {
46080fca6ea1SDimitry Andric       if (Previous->is(tok::identifier) || Previous->isTypeName(LangOpts)) {
4609d65cd7a5SDimitry Andric         Previous = Previous->getPreviousNonComment();
4610d65cd7a5SDimitry Andric         continue;
4611d65cd7a5SDimitry Andric       }
4612d65cd7a5SDimitry Andric       if (Previous->is(TT_TemplateCloser) && Previous->MatchingParen) {
4613d65cd7a5SDimitry Andric         Previous = Previous->MatchingParen->getPreviousNonComment();
4614d65cd7a5SDimitry Andric         continue;
4615d65cd7a5SDimitry Andric       }
4616d65cd7a5SDimitry Andric       if (Previous->is(tok::coloncolon)) {
4617d65cd7a5SDimitry Andric         Previous = Previous->getPreviousNonComment();
4618d65cd7a5SDimitry Andric         continue;
4619d65cd7a5SDimitry Andric       }
4620d65cd7a5SDimitry Andric       break;
4621d65cd7a5SDimitry Andric     }
46228c27c554SDimitry Andric     // Space between the type and the * in:
46238c27c554SDimitry Andric     //   operator void*()
46248c27c554SDimitry Andric     //   operator char*()
4625fe6060f1SDimitry Andric     //   operator void const*()
4626fe6060f1SDimitry Andric     //   operator void volatile*()
46278c27c554SDimitry Andric     //   operator /*comment*/ const char*()
46288c27c554SDimitry Andric     //   operator volatile /*comment*/ char*()
46298c27c554SDimitry Andric     //   operator Foo*()
4630d65cd7a5SDimitry Andric     //   operator C<T>*()
4631d65cd7a5SDimitry Andric     //   operator std::Foo*()
4632d65cd7a5SDimitry Andric     //   operator C<T>::D<U>*()
46338c27c554SDimitry Andric     // dependent on PointerAlignment style.
4634fe6060f1SDimitry Andric     if (Previous) {
4635fe6060f1SDimitry Andric       if (Previous->endsSequence(tok::kw_operator))
463681ad6265SDimitry Andric         return Style.PointerAlignment != FormatStyle::PAS_Left;
463781ad6265SDimitry Andric       if (Previous->is(tok::kw_const) || Previous->is(tok::kw_volatile)) {
4638fe6060f1SDimitry Andric         return (Style.PointerAlignment != FormatStyle::PAS_Left) ||
4639fe6060f1SDimitry Andric                (Style.SpaceAroundPointerQualifiers ==
4640fe6060f1SDimitry Andric                 FormatStyle::SAPQ_After) ||
4641fe6060f1SDimitry Andric                (Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_Both);
4642fe6060f1SDimitry Andric       }
4643d65cd7a5SDimitry Andric     }
464481ad6265SDimitry Andric   }
464506c3fb27SDimitry Andric   if (Style.isCSharp() && Left.is(Keywords.kw_is) && Right.is(tok::l_square))
464606c3fb27SDimitry Andric     return true;
46470b57cec5SDimitry Andric   const auto SpaceRequiredForArrayInitializerLSquare =
46480b57cec5SDimitry Andric       [](const FormatToken &LSquareTok, const FormatStyle &Style) {
46490b57cec5SDimitry Andric         return Style.SpacesInContainerLiterals ||
46505f757f3fSDimitry Andric                (Style.isProto() && !Style.Cpp11BracedListStyle &&
46510b57cec5SDimitry Andric                 LSquareTok.endsSequence(tok::l_square, tok::colon,
46520b57cec5SDimitry Andric                                         TT_SelectorName));
46530b57cec5SDimitry Andric       };
465481ad6265SDimitry Andric   if (Left.is(tok::l_square)) {
46550b57cec5SDimitry Andric     return (Left.is(TT_ArrayInitializerLSquare) && Right.isNot(tok::r_square) &&
46560b57cec5SDimitry Andric             SpaceRequiredForArrayInitializerLSquare(Left, Style)) ||
4657a7dea167SDimitry Andric            (Left.isOneOf(TT_ArraySubscriptLSquare, TT_StructuredBindingLSquare,
4658a7dea167SDimitry Andric                          TT_LambdaLSquare) &&
46590b57cec5SDimitry Andric             Style.SpacesInSquareBrackets && Right.isNot(tok::r_square));
466081ad6265SDimitry Andric   }
466181ad6265SDimitry Andric   if (Right.is(tok::r_square)) {
46620b57cec5SDimitry Andric     return Right.MatchingParen &&
46630b57cec5SDimitry Andric            ((Right.MatchingParen->is(TT_ArrayInitializerLSquare) &&
46640b57cec5SDimitry Andric              SpaceRequiredForArrayInitializerLSquare(*Right.MatchingParen,
46650b57cec5SDimitry Andric                                                      Style)) ||
46660b57cec5SDimitry Andric             (Style.SpacesInSquareBrackets &&
46670b57cec5SDimitry Andric              Right.MatchingParen->isOneOf(TT_ArraySubscriptLSquare,
4668a7dea167SDimitry Andric                                           TT_StructuredBindingLSquare,
46695f757f3fSDimitry Andric                                           TT_LambdaLSquare)));
467081ad6265SDimitry Andric   }
46710b57cec5SDimitry Andric   if (Right.is(tok::l_square) &&
46720b57cec5SDimitry Andric       !Right.isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
46730b57cec5SDimitry Andric                      TT_DesignatedInitializerLSquare,
46740b57cec5SDimitry Andric                      TT_StructuredBindingLSquare, TT_AttributeSquare) &&
4675480093f4SDimitry Andric       !Left.isOneOf(tok::numeric_constant, TT_DictLiteral) &&
46765f757f3fSDimitry Andric       !(Left.isNot(tok::r_square) && Style.SpaceBeforeSquareBrackets &&
467781ad6265SDimitry Andric         Right.is(TT_ArraySubscriptLSquare))) {
46780b57cec5SDimitry Andric     return false;
467981ad6265SDimitry Andric   }
46800b57cec5SDimitry Andric   if (Left.is(tok::l_brace) && Right.is(tok::r_brace))
46810b57cec5SDimitry Andric     return !Left.Children.empty(); // No spaces in "{}".
4682e8d8bef9SDimitry Andric   if ((Left.is(tok::l_brace) && Left.isNot(BK_Block)) ||
46830b57cec5SDimitry Andric       (Right.is(tok::r_brace) && Right.MatchingParen &&
468481ad6265SDimitry Andric        Right.MatchingParen->isNot(BK_Block))) {
46855f757f3fSDimitry Andric     return !Style.Cpp11BracedListStyle || Style.SpacesInParensOptions.Other;
468681ad6265SDimitry Andric   }
468781ad6265SDimitry Andric   if (Left.is(TT_BlockComment)) {
46880b57cec5SDimitry Andric     // No whitespace in x(/*foo=*/1), except for JavaScript.
46895f757f3fSDimitry Andric     return Style.isJavaScript() || !Left.TokenText.ends_with("=*/");
469081ad6265SDimitry Andric   }
46915ffd83dbSDimitry Andric 
46925ffd83dbSDimitry Andric   // Space between template and attribute.
46935ffd83dbSDimitry Andric   // e.g. template <typename T> [[nodiscard]] ...
46945ffd83dbSDimitry Andric   if (Left.is(TT_TemplateCloser) && Right.is(TT_AttributeSquare))
46955ffd83dbSDimitry Andric     return true;
4696349cc55cSDimitry Andric   // Space before parentheses common for all languages
46970b57cec5SDimitry Andric   if (Right.is(tok::l_paren)) {
4698349cc55cSDimitry Andric     if (Left.is(TT_TemplateCloser) && Right.isNot(TT_FunctionTypeLParen))
4699349cc55cSDimitry Andric       return spaceRequiredBeforeParens(Right);
470081ad6265SDimitry Andric     if (Left.isOneOf(TT_RequiresClause,
470181ad6265SDimitry Andric                      TT_RequiresClauseInARequiresExpression)) {
470281ad6265SDimitry Andric       return Style.SpaceBeforeParensOptions.AfterRequiresInClause ||
470381ad6265SDimitry Andric              spaceRequiredBeforeParens(Right);
470481ad6265SDimitry Andric     }
470581ad6265SDimitry Andric     if (Left.is(TT_RequiresExpression)) {
470681ad6265SDimitry Andric       return Style.SpaceBeforeParensOptions.AfterRequiresInExpression ||
470781ad6265SDimitry Andric              spaceRequiredBeforeParens(Right);
470881ad6265SDimitry Andric     }
47095f757f3fSDimitry Andric     if (Left.is(TT_AttributeRParen) ||
471081ad6265SDimitry Andric         (Left.is(tok::r_square) && Left.is(TT_AttributeSquare))) {
47110b57cec5SDimitry Andric       return true;
471281ad6265SDimitry Andric     }
471381ad6265SDimitry Andric     if (Left.is(TT_ForEachMacro)) {
471481ad6265SDimitry Andric       return Style.SpaceBeforeParensOptions.AfterForeachMacros ||
471581ad6265SDimitry Andric              spaceRequiredBeforeParens(Right);
471681ad6265SDimitry Andric     }
471781ad6265SDimitry Andric     if (Left.is(TT_IfMacro)) {
471881ad6265SDimitry Andric       return Style.SpaceBeforeParensOptions.AfterIfMacros ||
471981ad6265SDimitry Andric              spaceRequiredBeforeParens(Right);
472081ad6265SDimitry Andric     }
47215f757f3fSDimitry Andric     if (Style.SpaceBeforeParens == FormatStyle::SBPO_Custom &&
47225f757f3fSDimitry Andric         Left.isOneOf(tok::kw_new, tok::kw_delete) &&
47235f757f3fSDimitry Andric         Right.isNot(TT_OverloadedOperatorLParen) &&
47245f757f3fSDimitry Andric         !(Line.MightBeFunctionDecl && Left.is(TT_FunctionDeclarationName))) {
4725b3edf446SDimitry Andric       return Style.SpaceBeforeParensOptions.AfterPlacementOperator;
47265f757f3fSDimitry Andric     }
4727349cc55cSDimitry Andric     if (Line.Type == LT_ObjCDecl)
4728349cc55cSDimitry Andric       return true;
4729349cc55cSDimitry Andric     if (Left.is(tok::semi))
4730349cc55cSDimitry Andric       return true;
4731349cc55cSDimitry Andric     if (Left.isOneOf(tok::pp_elif, tok::kw_for, tok::kw_while, tok::kw_switch,
473281ad6265SDimitry Andric                      tok::kw_case, TT_ForEachMacro, TT_ObjCForIn) ||
4733bdd1243dSDimitry Andric         Left.isIf(Line.Type != LT_PreprocessorDirective) ||
4734bdd1243dSDimitry Andric         Right.is(TT_ConditionLParen)) {
4735349cc55cSDimitry Andric       return Style.SpaceBeforeParensOptions.AfterControlStatements ||
4736349cc55cSDimitry Andric              spaceRequiredBeforeParens(Right);
473781ad6265SDimitry Andric     }
47384824e7fdSDimitry Andric 
47394824e7fdSDimitry Andric     // TODO add Operator overloading specific Options to
47404824e7fdSDimitry Andric     // SpaceBeforeParensOptions
47414824e7fdSDimitry Andric     if (Right.is(TT_OverloadedOperatorLParen))
47424824e7fdSDimitry Andric       return spaceRequiredBeforeParens(Right);
4743349cc55cSDimitry Andric     // Function declaration or definition
47440fca6ea1SDimitry Andric     if (Line.MightBeFunctionDecl && Right.is(TT_FunctionDeclarationLParen)) {
47450fca6ea1SDimitry Andric       if (spaceRequiredBeforeParens(Right))
47460fca6ea1SDimitry Andric         return true;
47470fca6ea1SDimitry Andric       const auto &Options = Style.SpaceBeforeParensOptions;
47480fca6ea1SDimitry Andric       return Line.mightBeFunctionDefinition()
47490fca6ea1SDimitry Andric                  ? Options.AfterFunctionDefinitionName
47500fca6ea1SDimitry Andric                  : Options.AfterFunctionDeclarationName;
475181ad6265SDimitry Andric     }
4752349cc55cSDimitry Andric     // Lambda
4753349cc55cSDimitry Andric     if (Line.Type != LT_PreprocessorDirective && Left.is(tok::r_square) &&
475481ad6265SDimitry Andric         Left.MatchingParen && Left.MatchingParen->is(TT_LambdaLSquare)) {
4755349cc55cSDimitry Andric       return Style.SpaceBeforeParensOptions.AfterFunctionDefinitionName ||
4756349cc55cSDimitry Andric              spaceRequiredBeforeParens(Right);
475781ad6265SDimitry Andric     }
47580fca6ea1SDimitry Andric     if (!BeforeLeft || !BeforeLeft->isOneOf(tok::period, tok::arrow)) {
475981ad6265SDimitry Andric       if (Left.isOneOf(tok::kw_try, Keywords.kw___except, tok::kw_catch)) {
4760349cc55cSDimitry Andric         return Style.SpaceBeforeParensOptions.AfterControlStatements ||
4761349cc55cSDimitry Andric                spaceRequiredBeforeParens(Right);
476281ad6265SDimitry Andric       }
476381ad6265SDimitry Andric       if (Left.isOneOf(tok::kw_new, tok::kw_delete)) {
47640fca6ea1SDimitry Andric         return ((!Line.MightBeFunctionDecl || !BeforeLeft) &&
476581ad6265SDimitry Andric                 Style.SpaceBeforeParens != FormatStyle::SBPO_Never) ||
4766349cc55cSDimitry Andric                spaceRequiredBeforeParens(Right);
4767349cc55cSDimitry Andric       }
476881ad6265SDimitry Andric 
476981ad6265SDimitry Andric       if (Left.is(tok::r_square) && Left.MatchingParen &&
477081ad6265SDimitry Andric           Left.MatchingParen->Previous &&
477181ad6265SDimitry Andric           Left.MatchingParen->Previous->is(tok::kw_delete)) {
477281ad6265SDimitry Andric         return (Style.SpaceBeforeParens != FormatStyle::SBPO_Never) ||
477381ad6265SDimitry Andric                spaceRequiredBeforeParens(Right);
477481ad6265SDimitry Andric       }
477581ad6265SDimitry Andric     }
477681ad6265SDimitry Andric     // Handle builtins like identifiers.
4777349cc55cSDimitry Andric     if (Line.Type != LT_PreprocessorDirective &&
477881ad6265SDimitry Andric         (Left.Tok.getIdentifierInfo() || Left.is(tok::r_paren))) {
4779349cc55cSDimitry Andric       return spaceRequiredBeforeParens(Right);
478081ad6265SDimitry Andric     }
4781349cc55cSDimitry Andric     return false;
47820b57cec5SDimitry Andric   }
47830b57cec5SDimitry Andric   if (Left.is(tok::at) && Right.Tok.getObjCKeywordID() != tok::objc_not_keyword)
47840b57cec5SDimitry Andric     return false;
478581ad6265SDimitry Andric   if (Right.is(TT_UnaryOperator)) {
47860b57cec5SDimitry Andric     return !Left.isOneOf(tok::l_paren, tok::l_square, tok::at) &&
47870b57cec5SDimitry Andric            (Left.isNot(tok::colon) || Left.isNot(TT_ObjCMethodExpr));
478881ad6265SDimitry Andric   }
478906c3fb27SDimitry Andric   // No space between the variable name and the initializer list.
479006c3fb27SDimitry Andric   // A a1{1};
479106c3fb27SDimitry Andric   // Verilog doesn't have such syntax, but it has word operators that are C++
479206c3fb27SDimitry Andric   // identifiers like `a inside {b, c}`. So the rule is not applicable.
479306c3fb27SDimitry Andric   if (!Style.isVerilog() &&
479406c3fb27SDimitry Andric       (Left.isOneOf(tok::identifier, tok::greater, tok::r_square,
47950b57cec5SDimitry Andric                     tok::r_paren) ||
47960fca6ea1SDimitry Andric        Left.isTypeName(LangOpts)) &&
47970b57cec5SDimitry Andric       Right.is(tok::l_brace) && Right.getNextNonComment() &&
479881ad6265SDimitry Andric       Right.isNot(BK_Block)) {
47990b57cec5SDimitry Andric     return false;
480081ad6265SDimitry Andric   }
48010b57cec5SDimitry Andric   if (Left.is(tok::period) || Right.is(tok::period))
48020b57cec5SDimitry Andric     return false;
48030eae32dcSDimitry Andric   // u#str, U#str, L#str, u8#str
48040eae32dcSDimitry Andric   // uR#str, UR#str, LR#str, u8R#str
48050eae32dcSDimitry Andric   if (Right.is(tok::hash) && Left.is(tok::identifier) &&
48060eae32dcSDimitry Andric       (Left.TokenText == "L" || Left.TokenText == "u" ||
48070eae32dcSDimitry Andric        Left.TokenText == "U" || Left.TokenText == "u8" ||
48080eae32dcSDimitry Andric        Left.TokenText == "LR" || Left.TokenText == "uR" ||
480981ad6265SDimitry Andric        Left.TokenText == "UR" || Left.TokenText == "u8R")) {
48100b57cec5SDimitry Andric     return false;
481181ad6265SDimitry Andric   }
48120b57cec5SDimitry Andric   if (Left.is(TT_TemplateCloser) && Left.MatchingParen &&
48130b57cec5SDimitry Andric       Left.MatchingParen->Previous &&
48140b57cec5SDimitry Andric       (Left.MatchingParen->Previous->is(tok::period) ||
481581ad6265SDimitry Andric        Left.MatchingParen->Previous->is(tok::coloncolon))) {
48160b57cec5SDimitry Andric     // Java call to generic function with explicit type:
48170b57cec5SDimitry Andric     // A.<B<C<...>>>DoSomething();
48180b57cec5SDimitry Andric     // A::<B<C<...>>>DoSomething();  // With a Java 8 method reference.
48190b57cec5SDimitry Andric     return false;
482081ad6265SDimitry Andric   }
48210b57cec5SDimitry Andric   if (Left.is(TT_TemplateCloser) && Right.is(tok::l_square))
48220b57cec5SDimitry Andric     return false;
482381ad6265SDimitry Andric   if (Left.is(tok::l_brace) && Left.endsSequence(TT_DictLiteral, tok::at)) {
48240b57cec5SDimitry Andric     // Objective-C dictionary literal -> no space after opening brace.
48250b57cec5SDimitry Andric     return false;
482681ad6265SDimitry Andric   }
48270b57cec5SDimitry Andric   if (Right.is(tok::r_brace) && Right.MatchingParen &&
482881ad6265SDimitry Andric       Right.MatchingParen->endsSequence(TT_DictLiteral, tok::at)) {
48290b57cec5SDimitry Andric     // Objective-C dictionary literal -> no space before closing brace.
48300b57cec5SDimitry Andric     return false;
483181ad6265SDimitry Andric   }
48320fca6ea1SDimitry Andric   if (Right.is(TT_TrailingAnnotation) && Right.isOneOf(tok::amp, tok::ampamp) &&
4833a7dea167SDimitry Andric       Left.isOneOf(tok::kw_const, tok::kw_volatile) &&
483481ad6265SDimitry Andric       (!Right.Next || Right.Next->is(tok::semi))) {
4835a7dea167SDimitry Andric     // Match const and volatile ref-qualifiers without any additional
4836a7dea167SDimitry Andric     // qualifiers such as
4837a7dea167SDimitry Andric     // void Fn() const &;
4838fe6060f1SDimitry Andric     return getTokenReferenceAlignment(Right) != FormatStyle::PAS_Left;
483981ad6265SDimitry Andric   }
4840349cc55cSDimitry Andric 
48410b57cec5SDimitry Andric   return true;
48420b57cec5SDimitry Andric }
48430b57cec5SDimitry Andric 
48440b57cec5SDimitry Andric bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
484581ad6265SDimitry Andric                                          const FormatToken &Right) const {
48460b57cec5SDimitry Andric   const FormatToken &Left = *Right.Previous;
484704eeddc0SDimitry Andric 
484804eeddc0SDimitry Andric   // If the token is finalized don't touch it (as it could be in a
484904eeddc0SDimitry Andric   // clang-format-off section).
485004eeddc0SDimitry Andric   if (Left.Finalized)
485104eeddc0SDimitry Andric     return Right.hasWhitespaceBefore();
48524824e7fdSDimitry Andric 
48530fca6ea1SDimitry Andric   const bool IsVerilog = Style.isVerilog();
48540fca6ea1SDimitry Andric   assert(!IsVerilog || !IsCpp);
48550fca6ea1SDimitry Andric 
485681ad6265SDimitry Andric   // Never ever merge two words.
48570fca6ea1SDimitry Andric   if (Keywords.isWordLike(Right, IsVerilog) &&
48580fca6ea1SDimitry Andric       Keywords.isWordLike(Left, IsVerilog)) {
485981ad6265SDimitry Andric     return true;
48600fca6ea1SDimitry Andric   }
48614824e7fdSDimitry Andric 
48624824e7fdSDimitry Andric   // Leave a space between * and /* to avoid C4138 `comment end` found outside
48634824e7fdSDimitry Andric   // of comment.
48644824e7fdSDimitry Andric   if (Left.is(tok::star) && Right.is(tok::comment))
48654824e7fdSDimitry Andric     return true;
48664824e7fdSDimitry Andric 
48670fca6ea1SDimitry Andric   if (IsCpp) {
486806c3fb27SDimitry Andric     if (Left.is(TT_OverloadedOperator) &&
486906c3fb27SDimitry Andric         Right.isOneOf(TT_TemplateOpener, TT_TemplateCloser)) {
487006c3fb27SDimitry Andric       return true;
487106c3fb27SDimitry Andric     }
48721ac55f4cSDimitry Andric     // Space between UDL and dot: auto b = 4s .count();
48731ac55f4cSDimitry Andric     if (Right.is(tok::period) && Left.is(tok::numeric_constant))
48741ac55f4cSDimitry Andric       return true;
48754824e7fdSDimitry Andric     // Space between import <iostream>.
48764824e7fdSDimitry Andric     // or import .....;
48774824e7fdSDimitry Andric     if (Left.is(Keywords.kw_import) && Right.isOneOf(tok::less, tok::ellipsis))
48784824e7fdSDimitry Andric       return true;
487904eeddc0SDimitry Andric     // Space between `module :` and `import :`.
48804824e7fdSDimitry Andric     if (Left.isOneOf(Keywords.kw_module, Keywords.kw_import) &&
488181ad6265SDimitry Andric         Right.is(TT_ModulePartitionColon)) {
48824824e7fdSDimitry Andric       return true;
488381ad6265SDimitry Andric     }
48844824e7fdSDimitry Andric     // No space between import foo:bar but keep a space between import :bar;
48854824e7fdSDimitry Andric     if (Left.is(tok::identifier) && Right.is(TT_ModulePartitionColon))
48864824e7fdSDimitry Andric       return false;
48874824e7fdSDimitry Andric     // No space between :bar;
48884824e7fdSDimitry Andric     if (Left.is(TT_ModulePartitionColon) &&
488981ad6265SDimitry Andric         Right.isOneOf(tok::identifier, tok::kw_private)) {
48904824e7fdSDimitry Andric       return false;
489181ad6265SDimitry Andric     }
48924824e7fdSDimitry Andric     if (Left.is(tok::ellipsis) && Right.is(tok::identifier) &&
489381ad6265SDimitry Andric         Line.First->is(Keywords.kw_import)) {
48944824e7fdSDimitry Andric       return false;
489581ad6265SDimitry Andric     }
489604eeddc0SDimitry Andric     // Space in __attribute__((attr)) ::type.
48975f757f3fSDimitry Andric     if (Left.isOneOf(TT_AttributeRParen, TT_AttributeMacro) &&
48985f757f3fSDimitry Andric         Right.is(tok::coloncolon)) {
489904eeddc0SDimitry Andric       return true;
49005f757f3fSDimitry Andric     }
49014824e7fdSDimitry Andric 
49020b57cec5SDimitry Andric     if (Left.is(tok::kw_operator))
49030b57cec5SDimitry Andric       return Right.is(tok::coloncolon);
4904e8d8bef9SDimitry Andric     if (Right.is(tok::l_brace) && Right.is(BK_BracedInit) &&
490581ad6265SDimitry Andric         !Left.opensScope() && Style.SpaceBeforeCpp11BracedList) {
49060b57cec5SDimitry Andric       return true;
490781ad6265SDimitry Andric     }
490804eeddc0SDimitry Andric     if (Left.is(tok::less) && Left.is(TT_OverloadedOperator) &&
490981ad6265SDimitry Andric         Right.is(TT_TemplateOpener)) {
491004eeddc0SDimitry Andric       return true;
491181ad6265SDimitry Andric     }
49120fca6ea1SDimitry Andric     // C++ Core Guidelines suppression tag, e.g. `[[suppress(type.5)]]`.
49130fca6ea1SDimitry Andric     if (Left.is(tok::identifier) && Right.is(tok::numeric_constant))
49140fca6ea1SDimitry Andric       return Right.TokenText[0] != '.';
49150fca6ea1SDimitry Andric     // `Left` is a keyword (including C++ alternative operator) or identifier.
49160fca6ea1SDimitry Andric     if (Left.Tok.getIdentifierInfo() && Right.Tok.isLiteral())
49170fca6ea1SDimitry Andric       return true;
49185f757f3fSDimitry Andric   } else if (Style.isProto()) {
49190b57cec5SDimitry Andric     if (Right.is(tok::period) &&
49200b57cec5SDimitry Andric         Left.isOneOf(Keywords.kw_optional, Keywords.kw_required,
492181ad6265SDimitry Andric                      Keywords.kw_repeated, Keywords.kw_extend)) {
49220b57cec5SDimitry Andric       return true;
492381ad6265SDimitry Andric     }
49240b57cec5SDimitry Andric     if (Right.is(tok::l_paren) &&
492581ad6265SDimitry Andric         Left.isOneOf(Keywords.kw_returns, Keywords.kw_option)) {
49260b57cec5SDimitry Andric       return true;
492781ad6265SDimitry Andric     }
49280b57cec5SDimitry Andric     if (Right.isOneOf(tok::l_brace, tok::less) && Left.is(TT_SelectorName))
49290b57cec5SDimitry Andric       return true;
49300b57cec5SDimitry Andric     // Slashes occur in text protocol extension syntax: [type/type] { ... }.
49310b57cec5SDimitry Andric     if (Left.is(tok::slash) || Right.is(tok::slash))
49320b57cec5SDimitry Andric       return false;
49330b57cec5SDimitry Andric     if (Left.MatchingParen &&
49340b57cec5SDimitry Andric         Left.MatchingParen->is(TT_ProtoExtensionLSquare) &&
493581ad6265SDimitry Andric         Right.isOneOf(tok::l_brace, tok::less)) {
49360b57cec5SDimitry Andric       return !Style.Cpp11BracedListStyle;
493781ad6265SDimitry Andric     }
49380b57cec5SDimitry Andric     // A percent is probably part of a formatting specification, such as %lld.
49390b57cec5SDimitry Andric     if (Left.is(tok::percent))
49400b57cec5SDimitry Andric       return false;
49410b57cec5SDimitry Andric     // Preserve the existence of a space before a percent for cases like 0x%04x
49420b57cec5SDimitry Andric     // and "%d %d"
49430b57cec5SDimitry Andric     if (Left.is(tok::numeric_constant) && Right.is(tok::percent))
494404eeddc0SDimitry Andric       return Right.hasWhitespaceBefore();
4945fe6060f1SDimitry Andric   } else if (Style.isJson()) {
494606c3fb27SDimitry Andric     if (Right.is(tok::colon) && Left.is(tok::string_literal))
494706c3fb27SDimitry Andric       return Style.SpaceBeforeJsonColon;
4948a7dea167SDimitry Andric   } else if (Style.isCSharp()) {
49495ffd83dbSDimitry Andric     // Require spaces around '{' and  before '}' unless they appear in
49505ffd83dbSDimitry Andric     // interpolated strings. Interpolated strings are merged into a single token
49515ffd83dbSDimitry Andric     // so cannot have spaces inserted by this function.
49525ffd83dbSDimitry Andric 
49535ffd83dbSDimitry Andric     // No space between 'this' and '['
49545ffd83dbSDimitry Andric     if (Left.is(tok::kw_this) && Right.is(tok::l_square))
49555ffd83dbSDimitry Andric       return false;
49565ffd83dbSDimitry Andric 
49575ffd83dbSDimitry Andric     // No space between 'new' and '('
49585ffd83dbSDimitry Andric     if (Left.is(tok::kw_new) && Right.is(tok::l_paren))
49595ffd83dbSDimitry Andric       return false;
49605ffd83dbSDimitry Andric 
49615ffd83dbSDimitry Andric     // Space before { (including space within '{ {').
49625ffd83dbSDimitry Andric     if (Right.is(tok::l_brace))
49635ffd83dbSDimitry Andric       return true;
49645ffd83dbSDimitry Andric 
49655ffd83dbSDimitry Andric     // Spaces inside braces.
49665ffd83dbSDimitry Andric     if (Left.is(tok::l_brace) && Right.isNot(tok::r_brace))
49675ffd83dbSDimitry Andric       return true;
49685ffd83dbSDimitry Andric 
49695ffd83dbSDimitry Andric     if (Left.isNot(tok::l_brace) && Right.is(tok::r_brace))
49705ffd83dbSDimitry Andric       return true;
49715ffd83dbSDimitry Andric 
49725ffd83dbSDimitry Andric     // Spaces around '=>'.
4973fe6060f1SDimitry Andric     if (Left.is(TT_FatArrow) || Right.is(TT_FatArrow))
49745ffd83dbSDimitry Andric       return true;
49755ffd83dbSDimitry Andric 
49765ffd83dbSDimitry Andric     // No spaces around attribute target colons
49775ffd83dbSDimitry Andric     if (Left.is(TT_AttributeColon) || Right.is(TT_AttributeColon))
49785ffd83dbSDimitry Andric       return false;
49795ffd83dbSDimitry Andric 
4980a7dea167SDimitry Andric     // space between type and variable e.g. Dictionary<string,string> foo;
4981a7dea167SDimitry Andric     if (Left.is(TT_TemplateCloser) && Right.is(TT_StartOfName))
4982a7dea167SDimitry Andric       return true;
49835ffd83dbSDimitry Andric 
49845ffd83dbSDimitry Andric     // spaces inside square brackets.
49855ffd83dbSDimitry Andric     if (Left.is(tok::l_square) || Right.is(tok::r_square))
49865ffd83dbSDimitry Andric       return Style.SpacesInSquareBrackets;
49875ffd83dbSDimitry Andric 
49885ffd83dbSDimitry Andric     // No space before ? in nullable types.
49895ffd83dbSDimitry Andric     if (Right.is(TT_CSharpNullable))
49905ffd83dbSDimitry Andric       return false;
49915ffd83dbSDimitry Andric 
4992fe6060f1SDimitry Andric     // No space before null forgiving '!'.
4993fe6060f1SDimitry Andric     if (Right.is(TT_NonNullAssertion))
49945ffd83dbSDimitry Andric       return false;
49955ffd83dbSDimitry Andric 
49965ffd83dbSDimitry Andric     // No space between consecutive commas '[,,]'.
49975ffd83dbSDimitry Andric     if (Left.is(tok::comma) && Right.is(tok::comma))
49985ffd83dbSDimitry Andric       return false;
49995ffd83dbSDimitry Andric 
50005ffd83dbSDimitry Andric     // space after var in `var (key, value)`
50015ffd83dbSDimitry Andric     if (Left.is(Keywords.kw_var) && Right.is(tok::l_paren))
50025ffd83dbSDimitry Andric       return true;
50035ffd83dbSDimitry Andric 
5004a7dea167SDimitry Andric     // space between keywords and paren e.g. "using ("
500581ad6265SDimitry Andric     if (Right.is(tok::l_paren)) {
50065ffd83dbSDimitry Andric       if (Left.isOneOf(tok::kw_using, Keywords.kw_async, Keywords.kw_when,
500781ad6265SDimitry Andric                        Keywords.kw_lock)) {
5008349cc55cSDimitry Andric         return Style.SpaceBeforeParensOptions.AfterControlStatements ||
50095ffd83dbSDimitry Andric                spaceRequiredBeforeParens(Right);
501081ad6265SDimitry Andric       }
501181ad6265SDimitry Andric     }
5012e8d8bef9SDimitry Andric 
5013e8d8bef9SDimitry Andric     // space between method modifier and opening parenthesis of a tuple return
5014e8d8bef9SDimitry Andric     // type
50150fca6ea1SDimitry Andric     if ((Left.isAccessSpecifierKeyword() ||
50160fca6ea1SDimitry Andric          Left.isOneOf(tok::kw_virtual, tok::kw_extern, tok::kw_static,
5017e8d8bef9SDimitry Andric                       Keywords.kw_internal, Keywords.kw_abstract,
5018e8d8bef9SDimitry Andric                       Keywords.kw_sealed, Keywords.kw_override,
50190fca6ea1SDimitry Andric                       Keywords.kw_async, Keywords.kw_unsafe)) &&
502081ad6265SDimitry Andric         Right.is(tok::l_paren)) {
5021e8d8bef9SDimitry Andric       return true;
502281ad6265SDimitry Andric     }
50230eae32dcSDimitry Andric   } else if (Style.isJavaScript()) {
5024fe6060f1SDimitry Andric     if (Left.is(TT_FatArrow))
50250b57cec5SDimitry Andric       return true;
50260b57cec5SDimitry Andric     // for await ( ...
50270b57cec5SDimitry Andric     if (Right.is(tok::l_paren) && Left.is(Keywords.kw_await) && Left.Previous &&
502881ad6265SDimitry Andric         Left.Previous->is(tok::kw_for)) {
50290b57cec5SDimitry Andric       return true;
503081ad6265SDimitry Andric     }
50310b57cec5SDimitry Andric     if (Left.is(Keywords.kw_async) && Right.is(tok::l_paren) &&
50320b57cec5SDimitry Andric         Right.MatchingParen) {
50330b57cec5SDimitry Andric       const FormatToken *Next = Right.MatchingParen->getNextNonComment();
50340b57cec5SDimitry Andric       // An async arrow function, for example: `x = async () => foo();`,
50350b57cec5SDimitry Andric       // as opposed to calling a function called async: `x = async();`
5036fe6060f1SDimitry Andric       if (Next && Next->is(TT_FatArrow))
50370b57cec5SDimitry Andric         return true;
50380b57cec5SDimitry Andric     }
50395f757f3fSDimitry Andric     if ((Left.is(TT_TemplateString) && Left.TokenText.ends_with("${")) ||
50405f757f3fSDimitry Andric         (Right.is(TT_TemplateString) && Right.TokenText.starts_with("}"))) {
50410b57cec5SDimitry Andric       return false;
504281ad6265SDimitry Andric     }
50430b57cec5SDimitry Andric     // In tagged template literals ("html`bar baz`"), there is no space between
50445ffd83dbSDimitry Andric     // the tag identifier and the template string.
50450fca6ea1SDimitry Andric     if (Keywords.isJavaScriptIdentifier(Left,
50465ffd83dbSDimitry Andric                                         /* AcceptIdentifierName= */ false) &&
504781ad6265SDimitry Andric         Right.is(TT_TemplateString)) {
50480b57cec5SDimitry Andric       return false;
504981ad6265SDimitry Andric     }
50500b57cec5SDimitry Andric     if (Right.is(tok::star) &&
505181ad6265SDimitry Andric         Left.isOneOf(Keywords.kw_function, Keywords.kw_yield)) {
50520b57cec5SDimitry Andric       return false;
505381ad6265SDimitry Andric     }
50540b57cec5SDimitry Andric     if (Right.isOneOf(tok::l_brace, tok::l_square) &&
50550b57cec5SDimitry Andric         Left.isOneOf(Keywords.kw_function, Keywords.kw_yield,
505681ad6265SDimitry Andric                      Keywords.kw_extends, Keywords.kw_implements)) {
50570b57cec5SDimitry Andric       return true;
505881ad6265SDimitry Andric     }
50590b57cec5SDimitry Andric     if (Right.is(tok::l_paren)) {
50600b57cec5SDimitry Andric       // JS methods can use some keywords as names (e.g. `delete()`).
50610b57cec5SDimitry Andric       if (Line.MustBeDeclaration && Left.Tok.getIdentifierInfo())
50620b57cec5SDimitry Andric         return false;
50630b57cec5SDimitry Andric       // Valid JS method names can include keywords, e.g. `foo.delete()` or
50640b57cec5SDimitry Andric       // `bar.instanceof()`. Recognize call positions by preceding period.
50650b57cec5SDimitry Andric       if (Left.Previous && Left.Previous->is(tok::period) &&
506681ad6265SDimitry Andric           Left.Tok.getIdentifierInfo()) {
50670b57cec5SDimitry Andric         return false;
506881ad6265SDimitry Andric       }
50690b57cec5SDimitry Andric       // Additional unary JavaScript operators that need a space after.
50700b57cec5SDimitry Andric       if (Left.isOneOf(tok::kw_throw, Keywords.kw_await, Keywords.kw_typeof,
507181ad6265SDimitry Andric                        tok::kw_void)) {
50720b57cec5SDimitry Andric         return true;
50730b57cec5SDimitry Andric       }
5074a7dea167SDimitry Andric     }
507581ad6265SDimitry Andric     // `foo as const;` casts into a const type.
507681ad6265SDimitry Andric     if (Left.endsSequence(tok::kw_const, Keywords.kw_as))
507781ad6265SDimitry Andric       return false;
50780b57cec5SDimitry Andric     if ((Left.isOneOf(Keywords.kw_let, Keywords.kw_var, Keywords.kw_in,
50790b57cec5SDimitry Andric                       tok::kw_const) ||
50800b57cec5SDimitry Andric          // "of" is only a keyword if it appears after another identifier
50810b57cec5SDimitry Andric          // (e.g. as "const x of y" in a for loop), or after a destructuring
50820b57cec5SDimitry Andric          // operation (const [x, y] of z, const {a, b} of c).
50830b57cec5SDimitry Andric          (Left.is(Keywords.kw_of) && Left.Previous &&
508481ad6265SDimitry Andric           (Left.Previous->is(tok::identifier) ||
50850b57cec5SDimitry Andric            Left.Previous->isOneOf(tok::r_square, tok::r_brace)))) &&
50865f757f3fSDimitry Andric         (!Left.Previous || Left.Previous->isNot(tok::period))) {
50870b57cec5SDimitry Andric       return true;
508881ad6265SDimitry Andric     }
50890b57cec5SDimitry Andric     if (Left.isOneOf(tok::kw_for, Keywords.kw_as) && Left.Previous &&
509081ad6265SDimitry Andric         Left.Previous->is(tok::period) && Right.is(tok::l_paren)) {
50910b57cec5SDimitry Andric       return false;
509281ad6265SDimitry Andric     }
50930b57cec5SDimitry Andric     if (Left.is(Keywords.kw_as) &&
509481ad6265SDimitry Andric         Right.isOneOf(tok::l_square, tok::l_brace, tok::l_paren)) {
50950b57cec5SDimitry Andric       return true;
509681ad6265SDimitry Andric     }
50970b57cec5SDimitry Andric     if (Left.is(tok::kw_default) && Left.Previous &&
509881ad6265SDimitry Andric         Left.Previous->is(tok::kw_export)) {
50990b57cec5SDimitry Andric       return true;
510081ad6265SDimitry Andric     }
51010b57cec5SDimitry Andric     if (Left.is(Keywords.kw_is) && Right.is(tok::l_brace))
51020b57cec5SDimitry Andric       return true;
51030b57cec5SDimitry Andric     if (Right.isOneOf(TT_JsTypeColon, TT_JsTypeOptionalQuestion))
51040b57cec5SDimitry Andric       return false;
51050b57cec5SDimitry Andric     if (Left.is(TT_JsTypeOperator) || Right.is(TT_JsTypeOperator))
51060b57cec5SDimitry Andric       return false;
51070b57cec5SDimitry Andric     if ((Left.is(tok::l_brace) || Right.is(tok::r_brace)) &&
510881ad6265SDimitry Andric         Line.First->isOneOf(Keywords.kw_import, tok::kw_export)) {
51090b57cec5SDimitry Andric       return false;
511081ad6265SDimitry Andric     }
51110b57cec5SDimitry Andric     if (Left.is(tok::ellipsis))
51120b57cec5SDimitry Andric       return false;
51130b57cec5SDimitry Andric     if (Left.is(TT_TemplateCloser) &&
51140b57cec5SDimitry Andric         !Right.isOneOf(tok::equal, tok::l_brace, tok::comma, tok::l_square,
511581ad6265SDimitry Andric                        Keywords.kw_implements, Keywords.kw_extends)) {
51160b57cec5SDimitry Andric       // Type assertions ('<type>expr') are not followed by whitespace. Other
51170b57cec5SDimitry Andric       // locations that should have whitespace following are identified by the
51180b57cec5SDimitry Andric       // above set of follower tokens.
51190b57cec5SDimitry Andric       return false;
512081ad6265SDimitry Andric     }
5121fe6060f1SDimitry Andric     if (Right.is(TT_NonNullAssertion))
51220b57cec5SDimitry Andric       return false;
5123fe6060f1SDimitry Andric     if (Left.is(TT_NonNullAssertion) &&
512481ad6265SDimitry Andric         Right.isOneOf(Keywords.kw_as, Keywords.kw_in)) {
51250b57cec5SDimitry Andric       return true; // "x! as string", "x! in y"
512681ad6265SDimitry Andric     }
51270b57cec5SDimitry Andric   } else if (Style.Language == FormatStyle::LK_Java) {
51280fca6ea1SDimitry Andric     if (Left.is(TT_CaseLabelArrow) || Right.is(TT_CaseLabelArrow))
51290fca6ea1SDimitry Andric       return true;
51300b57cec5SDimitry Andric     if (Left.is(tok::r_square) && Right.is(tok::l_brace))
51310b57cec5SDimitry Andric       return true;
51327a6dacacSDimitry Andric     // spaces inside square brackets.
51337a6dacacSDimitry Andric     if (Left.is(tok::l_square) || Right.is(tok::r_square))
51347a6dacacSDimitry Andric       return Style.SpacesInSquareBrackets;
51357a6dacacSDimitry Andric 
513681ad6265SDimitry Andric     if (Left.is(Keywords.kw_synchronized) && Right.is(tok::l_paren)) {
5137349cc55cSDimitry Andric       return Style.SpaceBeforeParensOptions.AfterControlStatements ||
5138349cc55cSDimitry Andric              spaceRequiredBeforeParens(Right);
513981ad6265SDimitry Andric     }
51400fca6ea1SDimitry Andric     if ((Left.isAccessSpecifierKeyword() ||
51410fca6ea1SDimitry Andric          Left.isOneOf(tok::kw_static, Keywords.kw_final, Keywords.kw_abstract,
51420b57cec5SDimitry Andric                       Keywords.kw_native)) &&
514381ad6265SDimitry Andric         Right.is(TT_TemplateOpener)) {
51440b57cec5SDimitry Andric       return true;
51450b57cec5SDimitry Andric     }
51460fca6ea1SDimitry Andric   } else if (IsVerilog) {
514706c3fb27SDimitry Andric     // An escaped identifier ends with whitespace.
51480fca6ea1SDimitry Andric     if (Left.is(tok::identifier) && Left.TokenText[0] == '\\')
514906c3fb27SDimitry Andric       return true;
5150bdd1243dSDimitry Andric     // Add space between things in a primitive's state table unless in a
5151bdd1243dSDimitry Andric     // transition like `(0?)`.
5152bdd1243dSDimitry Andric     if ((Left.is(TT_VerilogTableItem) &&
5153bdd1243dSDimitry Andric          !Right.isOneOf(tok::r_paren, tok::semi)) ||
5154bdd1243dSDimitry Andric         (Right.is(TT_VerilogTableItem) && Left.isNot(tok::l_paren))) {
5155bdd1243dSDimitry Andric       const FormatToken *Next = Right.getNextNonComment();
5156bdd1243dSDimitry Andric       return !(Next && Next->is(tok::r_paren));
5157bdd1243dSDimitry Andric     }
515881ad6265SDimitry Andric     // Don't add space within a delay like `#0`.
5159bdd1243dSDimitry Andric     if (Left.isNot(TT_BinaryOperator) &&
516081ad6265SDimitry Andric         Left.isOneOf(Keywords.kw_verilogHash, Keywords.kw_verilogHashHash)) {
516181ad6265SDimitry Andric       return false;
516281ad6265SDimitry Andric     }
516381ad6265SDimitry Andric     // Add space after a delay.
51645f757f3fSDimitry Andric     if (Right.isNot(tok::semi) &&
516581ad6265SDimitry Andric         (Left.endsSequence(tok::numeric_constant, Keywords.kw_verilogHash) ||
516681ad6265SDimitry Andric          Left.endsSequence(tok::numeric_constant,
516781ad6265SDimitry Andric                            Keywords.kw_verilogHashHash) ||
516881ad6265SDimitry Andric          (Left.is(tok::r_paren) && Left.MatchingParen &&
516981ad6265SDimitry Andric           Left.MatchingParen->endsSequence(tok::l_paren, tok::at)))) {
517081ad6265SDimitry Andric       return true;
517181ad6265SDimitry Andric     }
5172bdd1243dSDimitry Andric     // Don't add embedded spaces in a number literal like `16'h1?ax` or an array
5173bdd1243dSDimitry Andric     // literal like `'{}`.
5174bdd1243dSDimitry Andric     if (Left.is(Keywords.kw_apostrophe) ||
5175bdd1243dSDimitry Andric         (Left.is(TT_VerilogNumberBase) && Right.is(tok::numeric_constant))) {
5176bdd1243dSDimitry Andric       return false;
5177bdd1243dSDimitry Andric     }
51785f757f3fSDimitry Andric     // Add spaces around the implication operator `->`.
51795f757f3fSDimitry Andric     if (Left.is(tok::arrow) || Right.is(tok::arrow))
51805f757f3fSDimitry Andric       return true;
518106c3fb27SDimitry Andric     // Don't add spaces between two at signs. Like in a coverage event.
518206c3fb27SDimitry Andric     // Don't add spaces between at and a sensitivity list like
518306c3fb27SDimitry Andric     // `@(posedge clk)`.
518406c3fb27SDimitry Andric     if (Left.is(tok::at) && Right.isOneOf(tok::l_paren, tok::star, tok::at))
518506c3fb27SDimitry Andric       return false;
5186bdd1243dSDimitry Andric     // Add space between the type name and dimension like `logic [1:0]`.
5187bdd1243dSDimitry Andric     if (Right.is(tok::l_square) &&
5188bdd1243dSDimitry Andric         Left.isOneOf(TT_VerilogDimensionedTypeName, Keywords.kw_function)) {
5189bdd1243dSDimitry Andric       return true;
5190bdd1243dSDimitry Andric     }
51915f757f3fSDimitry Andric     // In a tagged union expression, there should be a space after the tag.
51925f757f3fSDimitry Andric     if (Right.isOneOf(tok::period, Keywords.kw_apostrophe) &&
51935f757f3fSDimitry Andric         Keywords.isVerilogIdentifier(Left) && Left.getPreviousNonComment() &&
51945f757f3fSDimitry Andric         Left.getPreviousNonComment()->is(Keywords.kw_tagged)) {
51955f757f3fSDimitry Andric       return true;
51965f757f3fSDimitry Andric     }
5197bdd1243dSDimitry Andric     // Don't add spaces between a casting type and the quote or repetition count
51985f757f3fSDimitry Andric     // and the brace. The case of tagged union expressions is handled by the
51995f757f3fSDimitry Andric     // previous rule.
5200bdd1243dSDimitry Andric     if ((Right.is(Keywords.kw_apostrophe) ||
5201bdd1243dSDimitry Andric          (Right.is(BK_BracedInit) && Right.is(tok::l_brace))) &&
5202bdd1243dSDimitry Andric         !(Left.isOneOf(Keywords.kw_assign, Keywords.kw_unique) ||
5203bdd1243dSDimitry Andric           Keywords.isVerilogWordOperator(Left)) &&
5204bdd1243dSDimitry Andric         (Left.isOneOf(tok::r_square, tok::r_paren, tok::r_brace,
5205bdd1243dSDimitry Andric                       tok::numeric_constant) ||
5206bdd1243dSDimitry Andric          Keywords.isWordLike(Left))) {
5207bdd1243dSDimitry Andric       return false;
5208bdd1243dSDimitry Andric     }
520906c3fb27SDimitry Andric     // Don't add spaces in imports like `import foo::*;`.
521006c3fb27SDimitry Andric     if ((Right.is(tok::star) && Left.is(tok::coloncolon)) ||
521106c3fb27SDimitry Andric         (Left.is(tok::star) && Right.is(tok::semi))) {
521206c3fb27SDimitry Andric       return false;
521306c3fb27SDimitry Andric     }
5214bdd1243dSDimitry Andric     // Add space in attribute like `(* ASYNC_REG = "TRUE" *)`.
5215bdd1243dSDimitry Andric     if (Left.endsSequence(tok::star, tok::l_paren) && Right.is(tok::identifier))
5216bdd1243dSDimitry Andric       return true;
521706c3fb27SDimitry Andric     // Add space before drive strength like in `wire (strong1, pull0)`.
521806c3fb27SDimitry Andric     if (Right.is(tok::l_paren) && Right.is(TT_VerilogStrength))
521906c3fb27SDimitry Andric       return true;
522006c3fb27SDimitry Andric     // Don't add space in a streaming concatenation like `{>>{j}}`.
522106c3fb27SDimitry Andric     if ((Left.is(tok::l_brace) &&
522206c3fb27SDimitry Andric          Right.isOneOf(tok::lessless, tok::greatergreater)) ||
522306c3fb27SDimitry Andric         (Left.endsSequence(tok::lessless, tok::l_brace) ||
522406c3fb27SDimitry Andric          Left.endsSequence(tok::greatergreater, tok::l_brace))) {
522506c3fb27SDimitry Andric       return false;
522606c3fb27SDimitry Andric     }
52270fca6ea1SDimitry Andric   } else if (Style.isTableGen()) {
52280fca6ea1SDimitry Andric     // Avoid to connect [ and {. [{ is start token of multiline string.
52290fca6ea1SDimitry Andric     if (Left.is(tok::l_square) && Right.is(tok::l_brace))
52300fca6ea1SDimitry Andric       return true;
52310fca6ea1SDimitry Andric     if (Left.is(tok::r_brace) && Right.is(tok::r_square))
52320fca6ea1SDimitry Andric       return true;
52330fca6ea1SDimitry Andric     // Do not insert around colon in DAGArg and cond operator.
52340fca6ea1SDimitry Andric     if (Right.isOneOf(TT_TableGenDAGArgListColon,
52350fca6ea1SDimitry Andric                       TT_TableGenDAGArgListColonToAlign) ||
52360fca6ea1SDimitry Andric         Left.isOneOf(TT_TableGenDAGArgListColon,
52370fca6ea1SDimitry Andric                      TT_TableGenDAGArgListColonToAlign)) {
52380fca6ea1SDimitry Andric       return false;
523981ad6265SDimitry Andric     }
52400fca6ea1SDimitry Andric     if (Right.is(TT_TableGenCondOperatorColon))
52410fca6ea1SDimitry Andric       return false;
52420fca6ea1SDimitry Andric     if (Left.isOneOf(TT_TableGenDAGArgOperatorID,
52430fca6ea1SDimitry Andric                      TT_TableGenDAGArgOperatorToBreak) &&
52440fca6ea1SDimitry Andric         Right.isNot(TT_TableGenDAGArgCloser)) {
52450fca6ea1SDimitry Andric       return true;
52460fca6ea1SDimitry Andric     }
52470fca6ea1SDimitry Andric     // Do not insert bang operators and consequent openers.
52480fca6ea1SDimitry Andric     if (Right.isOneOf(tok::l_paren, tok::less) &&
52490fca6ea1SDimitry Andric         Left.isOneOf(TT_TableGenBangOperator, TT_TableGenCondOperator)) {
52500fca6ea1SDimitry Andric       return false;
52510fca6ea1SDimitry Andric     }
52520fca6ea1SDimitry Andric     // Trailing paste requires space before '{' or ':', the case in name values.
52530fca6ea1SDimitry Andric     // Not before ';', the case in normal values.
52540fca6ea1SDimitry Andric     if (Left.is(TT_TableGenTrailingPasteOperator) &&
52550fca6ea1SDimitry Andric         Right.isOneOf(tok::l_brace, tok::colon)) {
52560fca6ea1SDimitry Andric       return true;
52570fca6ea1SDimitry Andric     }
52580fca6ea1SDimitry Andric     // Otherwise paste operator does not prefer space around.
52590fca6ea1SDimitry Andric     if (Left.is(tok::hash) || Right.is(tok::hash))
52600fca6ea1SDimitry Andric       return false;
52610fca6ea1SDimitry Andric     // Sure not to connect after defining keywords.
52620fca6ea1SDimitry Andric     if (Keywords.isTableGenDefinition(Left))
52630fca6ea1SDimitry Andric       return true;
52640fca6ea1SDimitry Andric   }
52650fca6ea1SDimitry Andric 
52660b57cec5SDimitry Andric   if (Left.is(TT_ImplicitStringLiteral))
526704eeddc0SDimitry Andric     return Right.hasWhitespaceBefore();
52680b57cec5SDimitry Andric   if (Line.Type == LT_ObjCMethodDecl) {
52690b57cec5SDimitry Andric     if (Left.is(TT_ObjCMethodSpecifier))
52700b57cec5SDimitry Andric       return true;
52715f757f3fSDimitry Andric     if (Left.is(tok::r_paren) && Left.isNot(TT_AttributeRParen) &&
52725f757f3fSDimitry Andric         canBeObjCSelectorComponent(Right)) {
52730b57cec5SDimitry Andric       // Don't space between ')' and <id> or ')' and 'new'. 'new' is not a
52740b57cec5SDimitry Andric       // keyword in Objective-C, and '+ (instancetype)new;' is a standard class
52750b57cec5SDimitry Andric       // method declaration.
52760b57cec5SDimitry Andric       return false;
52770b57cec5SDimitry Andric     }
527881ad6265SDimitry Andric   }
52790b57cec5SDimitry Andric   if (Line.Type == LT_ObjCProperty &&
528081ad6265SDimitry Andric       (Right.is(tok::equal) || Left.is(tok::equal))) {
52810b57cec5SDimitry Andric     return false;
528281ad6265SDimitry Andric   }
52830b57cec5SDimitry Andric 
52846c4b055cSDimitry Andric   if (Right.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow) ||
52856c4b055cSDimitry Andric       Left.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow)) {
52860b57cec5SDimitry Andric     return true;
52876c4b055cSDimitry Andric   }
52885f757f3fSDimitry Andric   if (Left.is(tok::comma) && Right.isNot(TT_OverloadedOperatorLParen) &&
528906c3fb27SDimitry Andric       // In an unexpanded macro call we only find the parentheses and commas
529006c3fb27SDimitry Andric       // in a line; the commas and closing parenthesis do not require a space.
529106c3fb27SDimitry Andric       (Left.Children.empty() || !Left.MacroParent)) {
52920b57cec5SDimitry Andric     return true;
529306c3fb27SDimitry Andric   }
52940b57cec5SDimitry Andric   if (Right.is(tok::comma))
52950b57cec5SDimitry Andric     return false;
52960b57cec5SDimitry Andric   if (Right.is(TT_ObjCBlockLParen))
52970b57cec5SDimitry Andric     return true;
52980b57cec5SDimitry Andric   if (Right.is(TT_CtorInitializerColon))
52990b57cec5SDimitry Andric     return Style.SpaceBeforeCtorInitializerColon;
53000b57cec5SDimitry Andric   if (Right.is(TT_InheritanceColon) && !Style.SpaceBeforeInheritanceColon)
53010b57cec5SDimitry Andric     return false;
53020b57cec5SDimitry Andric   if (Right.is(TT_RangeBasedForLoopColon) &&
530381ad6265SDimitry Andric       !Style.SpaceBeforeRangeBasedForLoopColon) {
53040b57cec5SDimitry Andric     return false;
530581ad6265SDimitry Andric   }
530681ad6265SDimitry Andric   if (Left.is(TT_BitFieldColon)) {
5307e8d8bef9SDimitry Andric     return Style.BitFieldColonSpacing == FormatStyle::BFCS_Both ||
5308e8d8bef9SDimitry Andric            Style.BitFieldColonSpacing == FormatStyle::BFCS_After;
530981ad6265SDimitry Andric   }
53100b57cec5SDimitry Andric   if (Right.is(tok::colon)) {
531106c3fb27SDimitry Andric     if (Right.is(TT_CaseLabelColon))
5312bdd1243dSDimitry Andric       return Style.SpaceBeforeCaseColon;
531306c3fb27SDimitry Andric     if (Right.is(TT_GotoLabelColon))
531406c3fb27SDimitry Andric       return false;
531506c3fb27SDimitry Andric     // `private:` and `public:`.
531606c3fb27SDimitry Andric     if (!Right.getNextNonComment())
53170b57cec5SDimitry Andric       return false;
53180b57cec5SDimitry Andric     if (Right.is(TT_ObjCMethodExpr))
53190b57cec5SDimitry Andric       return false;
53200b57cec5SDimitry Andric     if (Left.is(tok::question))
53210b57cec5SDimitry Andric       return false;
53220b57cec5SDimitry Andric     if (Right.is(TT_InlineASMColon) && Left.is(tok::coloncolon))
53230b57cec5SDimitry Andric       return false;
53240b57cec5SDimitry Andric     if (Right.is(TT_DictLiteral))
53250b57cec5SDimitry Andric       return Style.SpacesInContainerLiterals;
53260b57cec5SDimitry Andric     if (Right.is(TT_AttributeColon))
53270b57cec5SDimitry Andric       return false;
53285ffd83dbSDimitry Andric     if (Right.is(TT_CSharpNamedArgumentColon))
53295ffd83dbSDimitry Andric       return false;
5330bdd1243dSDimitry Andric     if (Right.is(TT_GenericSelectionColon))
5331bdd1243dSDimitry Andric       return false;
533281ad6265SDimitry Andric     if (Right.is(TT_BitFieldColon)) {
5333e8d8bef9SDimitry Andric       return Style.BitFieldColonSpacing == FormatStyle::BFCS_Both ||
5334e8d8bef9SDimitry Andric              Style.BitFieldColonSpacing == FormatStyle::BFCS_Before;
533581ad6265SDimitry Andric     }
53360b57cec5SDimitry Andric     return true;
53370b57cec5SDimitry Andric   }
5338fe6060f1SDimitry Andric   // Do not merge "- -" into "--".
5339fe6060f1SDimitry Andric   if ((Left.isOneOf(tok::minus, tok::minusminus) &&
5340fe6060f1SDimitry Andric        Right.isOneOf(tok::minus, tok::minusminus)) ||
5341fe6060f1SDimitry Andric       (Left.isOneOf(tok::plus, tok::plusplus) &&
534281ad6265SDimitry Andric        Right.isOneOf(tok::plus, tok::plusplus))) {
5343fe6060f1SDimitry Andric     return true;
534481ad6265SDimitry Andric   }
5345a7dea167SDimitry Andric   if (Left.is(TT_UnaryOperator)) {
5346480093f4SDimitry Andric     // Lambda captures allow for a lone &, so "&]" needs to be properly
5347480093f4SDimitry Andric     // handled.
5348480093f4SDimitry Andric     if (Left.is(tok::amp) && Right.is(tok::r_square))
5349480093f4SDimitry Andric       return Style.SpacesInSquareBrackets;
53500fca6ea1SDimitry Andric     return Style.SpaceAfterLogicalNot && Left.is(tok::exclaim);
5351a7dea167SDimitry Andric   }
53520b57cec5SDimitry Andric 
53530b57cec5SDimitry Andric   // If the next token is a binary operator or a selector name, we have
53540b57cec5SDimitry Andric   // incorrectly classified the parenthesis as a cast. FIXME: Detect correctly.
535581ad6265SDimitry Andric   if (Left.is(TT_CastRParen)) {
53560b57cec5SDimitry Andric     return Style.SpaceAfterCStyleCast ||
53570b57cec5SDimitry Andric            Right.isOneOf(TT_BinaryOperator, TT_SelectorName);
535881ad6265SDimitry Andric   }
53590b57cec5SDimitry Andric 
536004eeddc0SDimitry Andric   auto ShouldAddSpacesInAngles = [this, &Right]() {
5361fe6060f1SDimitry Andric     if (this->Style.SpacesInAngles == FormatStyle::SIAS_Always)
5362fe6060f1SDimitry Andric       return true;
5363fe6060f1SDimitry Andric     if (this->Style.SpacesInAngles == FormatStyle::SIAS_Leave)
536404eeddc0SDimitry Andric       return Right.hasWhitespaceBefore();
5365fe6060f1SDimitry Andric     return false;
5366fe6060f1SDimitry Andric   };
5367fe6060f1SDimitry Andric 
53680b57cec5SDimitry Andric   if (Left.is(tok::greater) && Right.is(tok::greater)) {
53690b57cec5SDimitry Andric     if (Style.Language == FormatStyle::LK_TextProto ||
537081ad6265SDimitry Andric         (Style.Language == FormatStyle::LK_Proto && Left.is(TT_DictLiteral))) {
53710b57cec5SDimitry Andric       return !Style.Cpp11BracedListStyle;
537281ad6265SDimitry Andric     }
53730b57cec5SDimitry Andric     return Right.is(TT_TemplateCloser) && Left.is(TT_TemplateCloser) &&
5374fe6060f1SDimitry Andric            ((Style.Standard < FormatStyle::LS_Cpp11) ||
5375fe6060f1SDimitry Andric             ShouldAddSpacesInAngles());
53760b57cec5SDimitry Andric   }
53770b57cec5SDimitry Andric   if (Right.isOneOf(tok::arrow, tok::arrowstar, tok::periodstar) ||
53780b57cec5SDimitry Andric       Left.isOneOf(tok::arrow, tok::period, tok::arrowstar, tok::periodstar) ||
537981ad6265SDimitry Andric       (Right.is(tok::period) && Right.isNot(TT_DesignatedInitializerPeriod))) {
53800b57cec5SDimitry Andric     return false;
538181ad6265SDimitry Andric   }
5382a7dea167SDimitry Andric   if (!Style.SpaceBeforeAssignmentOperators && Left.isNot(TT_TemplateCloser) &&
538381ad6265SDimitry Andric       Right.getPrecedence() == prec::Assignment) {
53840b57cec5SDimitry Andric     return false;
538581ad6265SDimitry Andric   }
53860b57cec5SDimitry Andric   if (Style.Language == FormatStyle::LK_Java && Right.is(tok::coloncolon) &&
538781ad6265SDimitry Andric       (Left.is(tok::identifier) || Left.is(tok::kw_this))) {
53880b57cec5SDimitry Andric     return false;
538981ad6265SDimitry Andric   }
539081ad6265SDimitry Andric   if (Right.is(tok::coloncolon) && Left.is(tok::identifier)) {
53910b57cec5SDimitry Andric     // Generally don't remove existing spaces between an identifier and "::".
53920b57cec5SDimitry Andric     // The identifier might actually be a macro name such as ALWAYS_INLINE. If
53930b57cec5SDimitry Andric     // this turns out to be too lenient, add analysis of the identifier itself.
539404eeddc0SDimitry Andric     return Right.hasWhitespaceBefore();
539581ad6265SDimitry Andric   }
5396480093f4SDimitry Andric   if (Right.is(tok::coloncolon) &&
539781ad6265SDimitry Andric       !Left.isOneOf(tok::l_brace, tok::comment, tok::l_paren)) {
53985ffd83dbSDimitry Andric     // Put a space between < and :: in vector< ::std::string >
53990b57cec5SDimitry Andric     return (Left.is(TT_TemplateOpener) &&
5400fe6060f1SDimitry Andric             ((Style.Standard < FormatStyle::LS_Cpp11) ||
5401fe6060f1SDimitry Andric              ShouldAddSpacesInAngles())) ||
54020b57cec5SDimitry Andric            !(Left.isOneOf(tok::l_paren, tok::r_paren, tok::l_square,
54035ffd83dbSDimitry Andric                           tok::kw___super, TT_TemplateOpener,
54045ffd83dbSDimitry Andric                           TT_TemplateCloser)) ||
540506c3fb27SDimitry Andric            (Left.is(tok::l_paren) && Style.SpacesInParensOptions.Other);
540681ad6265SDimitry Andric   }
54070b57cec5SDimitry Andric   if ((Left.is(TT_TemplateOpener)) != (Right.is(TT_TemplateCloser)))
5408fe6060f1SDimitry Andric     return ShouldAddSpacesInAngles();
54090b57cec5SDimitry Andric   // Space before TT_StructuredBindingLSquare.
541081ad6265SDimitry Andric   if (Right.is(TT_StructuredBindingLSquare)) {
54110b57cec5SDimitry Andric     return !Left.isOneOf(tok::amp, tok::ampamp) ||
5412fe6060f1SDimitry Andric            getTokenReferenceAlignment(Left) != FormatStyle::PAS_Right;
541381ad6265SDimitry Andric   }
54140b57cec5SDimitry Andric   // Space before & or && following a TT_StructuredBindingLSquare.
54150b57cec5SDimitry Andric   if (Right.Next && Right.Next->is(TT_StructuredBindingLSquare) &&
541681ad6265SDimitry Andric       Right.isOneOf(tok::amp, tok::ampamp)) {
5417fe6060f1SDimitry Andric     return getTokenReferenceAlignment(Right) != FormatStyle::PAS_Left;
541881ad6265SDimitry Andric   }
54195f757f3fSDimitry Andric   if ((Right.is(TT_BinaryOperator) && Left.isNot(tok::l_paren)) ||
54200b57cec5SDimitry Andric       (Left.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) &&
54215f757f3fSDimitry Andric        Right.isNot(tok::r_paren))) {
54220b57cec5SDimitry Andric     return true;
542381ad6265SDimitry Andric   }
54240b57cec5SDimitry Andric   if (Right.is(TT_TemplateOpener) && Left.is(tok::r_paren) &&
542581ad6265SDimitry Andric       Left.MatchingParen &&
542681ad6265SDimitry Andric       Left.MatchingParen->is(TT_OverloadedOperatorLParen)) {
54270b57cec5SDimitry Andric     return false;
542881ad6265SDimitry Andric   }
54290b57cec5SDimitry Andric   if (Right.is(tok::less) && Left.isNot(tok::l_paren) &&
5430bdd1243dSDimitry Andric       Line.Type == LT_ImportStatement) {
54310b57cec5SDimitry Andric     return true;
543281ad6265SDimitry Andric   }
54330b57cec5SDimitry Andric   if (Right.is(TT_TrailingUnaryOperator))
54340b57cec5SDimitry Andric     return false;
54350b57cec5SDimitry Andric   if (Left.is(TT_RegexLiteral))
54360b57cec5SDimitry Andric     return false;
54370b57cec5SDimitry Andric   return spaceRequiredBetween(Line, Left, Right);
54380b57cec5SDimitry Andric }
54390b57cec5SDimitry Andric 
54400b57cec5SDimitry Andric // Returns 'true' if 'Tok' is a brace we'd want to break before in Allman style.
54410b57cec5SDimitry Andric static bool isAllmanBrace(const FormatToken &Tok) {
5442e8d8bef9SDimitry Andric   return Tok.is(tok::l_brace) && Tok.is(BK_Block) &&
54430b57cec5SDimitry Andric          !Tok.isOneOf(TT_ObjCBlockLBrace, TT_LambdaLBrace, TT_DictLiteral);
54440b57cec5SDimitry Andric }
54450b57cec5SDimitry Andric 
5446349cc55cSDimitry Andric // Returns 'true' if 'Tok' is a function argument.
54475ffd83dbSDimitry Andric static bool IsFunctionArgument(const FormatToken &Tok) {
54485ffd83dbSDimitry Andric   return Tok.MatchingParen && Tok.MatchingParen->Next &&
54495ffd83dbSDimitry Andric          Tok.MatchingParen->Next->isOneOf(tok::comma, tok::r_paren);
54505ffd83dbSDimitry Andric }
54515ffd83dbSDimitry Andric 
54525ffd83dbSDimitry Andric static bool
54535ffd83dbSDimitry Andric isItAnEmptyLambdaAllowed(const FormatToken &Tok,
54545ffd83dbSDimitry Andric                          FormatStyle::ShortLambdaStyle ShortLambdaOption) {
54555ffd83dbSDimitry Andric   return Tok.Children.empty() && ShortLambdaOption != FormatStyle::SLS_None;
54565ffd83dbSDimitry Andric }
54575ffd83dbSDimitry Andric 
54585ffd83dbSDimitry Andric static bool isAllmanLambdaBrace(const FormatToken &Tok) {
545981ad6265SDimitry Andric   return Tok.is(tok::l_brace) && Tok.is(BK_Block) &&
546081ad6265SDimitry Andric          !Tok.isOneOf(TT_ObjCBlockLBrace, TT_DictLiteral);
54615ffd83dbSDimitry Andric }
54625ffd83dbSDimitry Andric 
54630b57cec5SDimitry Andric bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
546481ad6265SDimitry Andric                                      const FormatToken &Right) const {
54650b57cec5SDimitry Andric   const FormatToken &Left = *Right.Previous;
54660b57cec5SDimitry Andric   if (Right.NewlinesBefore > 1 && Style.MaxEmptyLinesToKeep > 0)
54670b57cec5SDimitry Andric     return true;
54680b57cec5SDimitry Andric 
54690fca6ea1SDimitry Andric   if (Style.BreakFunctionDefinitionParameters && Line.MightBeFunctionDecl &&
54700fca6ea1SDimitry Andric       Line.mightBeFunctionDefinition() && Left.MightBeFunctionDeclParen &&
54710fca6ea1SDimitry Andric       Left.ParameterCount > 0) {
54720fca6ea1SDimitry Andric     return true;
54730fca6ea1SDimitry Andric   }
54740fca6ea1SDimitry Andric 
54750fca6ea1SDimitry Andric   const auto *BeforeLeft = Left.Previous;
54760fca6ea1SDimitry Andric   const auto *AfterRight = Right.Next;
54770fca6ea1SDimitry Andric 
54785ffd83dbSDimitry Andric   if (Style.isCSharp()) {
54790eae32dcSDimitry Andric     if (Left.is(TT_FatArrow) && Right.is(tok::l_brace) &&
548081ad6265SDimitry Andric         Style.BraceWrapping.AfterFunction) {
54810eae32dcSDimitry Andric       return true;
548281ad6265SDimitry Andric     }
54835ffd83dbSDimitry Andric     if (Right.is(TT_CSharpNamedArgumentColon) ||
548481ad6265SDimitry Andric         Left.is(TT_CSharpNamedArgumentColon)) {
54855ffd83dbSDimitry Andric       return false;
548681ad6265SDimitry Andric     }
54875ffd83dbSDimitry Andric     if (Right.is(TT_CSharpGenericTypeConstraint))
54885ffd83dbSDimitry Andric       return true;
54890fca6ea1SDimitry Andric     if (AfterRight && AfterRight->is(TT_FatArrow) &&
54900eae32dcSDimitry Andric         (Right.is(tok::numeric_constant) ||
549181ad6265SDimitry Andric          (Right.is(tok::identifier) && Right.TokenText == "_"))) {
54920eae32dcSDimitry Andric       return true;
549381ad6265SDimitry Andric     }
5494fe6060f1SDimitry Andric 
5495fe6060f1SDimitry Andric     // Break after C# [...] and before public/protected/private/internal.
5496fe6060f1SDimitry Andric     if (Left.is(TT_AttributeSquare) && Left.is(tok::r_square) &&
5497fe6060f1SDimitry Andric         (Right.isAccessSpecifier(/*ColonRequired=*/false) ||
549881ad6265SDimitry Andric          Right.is(Keywords.kw_internal))) {
5499fe6060f1SDimitry Andric       return true;
550081ad6265SDimitry Andric     }
5501fe6060f1SDimitry Andric     // Break between ] and [ but only when there are really 2 attributes.
5502fe6060f1SDimitry Andric     if (Left.is(TT_AttributeSquare) && Right.is(TT_AttributeSquare) &&
550381ad6265SDimitry Andric         Left.is(tok::r_square) && Right.is(tok::l_square)) {
5504fe6060f1SDimitry Andric       return true;
550581ad6265SDimitry Andric     }
55060eae32dcSDimitry Andric   } else if (Style.isJavaScript()) {
55070b57cec5SDimitry Andric     // FIXME: This might apply to other languages and token kinds.
55080fca6ea1SDimitry Andric     if (Right.is(tok::string_literal) && Left.is(tok::plus) && BeforeLeft &&
55090fca6ea1SDimitry Andric         BeforeLeft->is(tok::string_literal)) {
55100b57cec5SDimitry Andric       return true;
551181ad6265SDimitry Andric     }
55120b57cec5SDimitry Andric     if (Left.is(TT_DictLiteral) && Left.is(tok::l_brace) && Line.Level == 0 &&
55130fca6ea1SDimitry Andric         BeforeLeft && BeforeLeft->is(tok::equal) &&
55140b57cec5SDimitry Andric         Line.First->isOneOf(tok::identifier, Keywords.kw_import, tok::kw_export,
55150b57cec5SDimitry Andric                             tok::kw_const) &&
55160b57cec5SDimitry Andric         // kw_var/kw_let are pseudo-tokens that are tok::identifier, so match
55170b57cec5SDimitry Andric         // above.
551881ad6265SDimitry Andric         !Line.First->isOneOf(Keywords.kw_var, Keywords.kw_let)) {
55190b57cec5SDimitry Andric       // Object literals on the top level of a file are treated as "enum-style".
55200b57cec5SDimitry Andric       // Each key/value pair is put on a separate line, instead of bin-packing.
55210b57cec5SDimitry Andric       return true;
552281ad6265SDimitry Andric     }
55230b57cec5SDimitry Andric     if (Left.is(tok::l_brace) && Line.Level == 0 &&
55240b57cec5SDimitry Andric         (Line.startsWith(tok::kw_enum) ||
55250b57cec5SDimitry Andric          Line.startsWith(tok::kw_const, tok::kw_enum) ||
55260b57cec5SDimitry Andric          Line.startsWith(tok::kw_export, tok::kw_enum) ||
552781ad6265SDimitry Andric          Line.startsWith(tok::kw_export, tok::kw_const, tok::kw_enum))) {
55280b57cec5SDimitry Andric       // JavaScript top-level enum key/value pairs are put on separate lines
55290b57cec5SDimitry Andric       // instead of bin-packing.
55300b57cec5SDimitry Andric       return true;
553181ad6265SDimitry Andric     }
55320fca6ea1SDimitry Andric     if (Right.is(tok::r_brace) && Left.is(tok::l_brace) && BeforeLeft &&
55330fca6ea1SDimitry Andric         BeforeLeft->is(TT_FatArrow)) {
55345ffd83dbSDimitry Andric       // JS arrow function (=> {...}).
55355ffd83dbSDimitry Andric       switch (Style.AllowShortLambdasOnASingleLine) {
55365ffd83dbSDimitry Andric       case FormatStyle::SLS_All:
55375ffd83dbSDimitry Andric         return false;
55385ffd83dbSDimitry Andric       case FormatStyle::SLS_None:
55395ffd83dbSDimitry Andric         return true;
55405ffd83dbSDimitry Andric       case FormatStyle::SLS_Empty:
55415ffd83dbSDimitry Andric         return !Left.Children.empty();
55425ffd83dbSDimitry Andric       case FormatStyle::SLS_Inline:
55435ffd83dbSDimitry Andric         // allow one-lining inline (e.g. in function call args) and empty arrow
55445ffd83dbSDimitry Andric         // functions.
55455ffd83dbSDimitry Andric         return (Left.NestingLevel == 0 && Line.Level == 0) &&
55465ffd83dbSDimitry Andric                !Left.Children.empty();
55475ffd83dbSDimitry Andric       }
55485ffd83dbSDimitry Andric       llvm_unreachable("Unknown FormatStyle::ShortLambdaStyle enum");
55495ffd83dbSDimitry Andric     }
55505ffd83dbSDimitry Andric 
55510b57cec5SDimitry Andric     if (Right.is(tok::r_brace) && Left.is(tok::l_brace) &&
555281ad6265SDimitry Andric         !Left.Children.empty()) {
55530b57cec5SDimitry Andric       // Support AllowShortFunctionsOnASingleLine for JavaScript.
55540b57cec5SDimitry Andric       return Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_None ||
55550b57cec5SDimitry Andric              Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Empty ||
55560b57cec5SDimitry Andric              (Left.NestingLevel == 0 && Line.Level == 0 &&
55570b57cec5SDimitry Andric               Style.AllowShortFunctionsOnASingleLine &
55580b57cec5SDimitry Andric                   FormatStyle::SFS_InlineOnly);
555981ad6265SDimitry Andric     }
55600b57cec5SDimitry Andric   } else if (Style.Language == FormatStyle::LK_Java) {
55610fca6ea1SDimitry Andric     if (Right.is(tok::plus) && Left.is(tok::string_literal) && AfterRight &&
55620fca6ea1SDimitry Andric         AfterRight->is(tok::string_literal)) {
55630b57cec5SDimitry Andric       return true;
556481ad6265SDimitry Andric     }
5565bdd1243dSDimitry Andric   } else if (Style.isVerilog()) {
556606c3fb27SDimitry Andric     // Break between assignments.
556706c3fb27SDimitry Andric     if (Left.is(TT_VerilogAssignComma))
556806c3fb27SDimitry Andric       return true;
556906c3fb27SDimitry Andric     // Break between ports of different types.
557006c3fb27SDimitry Andric     if (Left.is(TT_VerilogTypeComma))
557106c3fb27SDimitry Andric       return true;
557206c3fb27SDimitry Andric     // Break between ports in a module instantiation and after the parameter
557306c3fb27SDimitry Andric     // list.
557406c3fb27SDimitry Andric     if (Style.VerilogBreakBetweenInstancePorts &&
557506c3fb27SDimitry Andric         (Left.is(TT_VerilogInstancePortComma) ||
557606c3fb27SDimitry Andric          (Left.is(tok::r_paren) && Keywords.isVerilogIdentifier(Right) &&
557706c3fb27SDimitry Andric           Left.MatchingParen &&
557806c3fb27SDimitry Andric           Left.MatchingParen->is(TT_VerilogInstancePortLParen)))) {
557906c3fb27SDimitry Andric       return true;
558006c3fb27SDimitry Andric     }
5581bdd1243dSDimitry Andric     // Break after labels. In Verilog labels don't have the 'case' keyword, so
5582bdd1243dSDimitry Andric     // it is hard to identify them in UnwrappedLineParser.
5583bdd1243dSDimitry Andric     if (!Keywords.isVerilogBegin(Right) && Keywords.isVerilogEndOfLabel(Left))
5584bdd1243dSDimitry Andric       return true;
55855f757f3fSDimitry Andric   } else if (Style.BreakAdjacentStringLiterals &&
55860fca6ea1SDimitry Andric              (IsCpp || Style.isProto() ||
55875f757f3fSDimitry Andric               Style.Language == FormatStyle::LK_TableGen)) {
55880b57cec5SDimitry Andric     if (Left.isStringLiteral() && Right.isStringLiteral())
55890b57cec5SDimitry Andric       return true;
55900b57cec5SDimitry Andric   }
55910b57cec5SDimitry Andric 
5592fe6060f1SDimitry Andric   // Basic JSON newline processing.
5593fe6060f1SDimitry Andric   if (Style.isJson()) {
5594fe6060f1SDimitry Andric     // Always break after a JSON record opener.
5595fe6060f1SDimitry Andric     // {
5596fe6060f1SDimitry Andric     // }
5597fe6060f1SDimitry Andric     if (Left.is(TT_DictLiteral) && Left.is(tok::l_brace))
5598fe6060f1SDimitry Andric       return true;
5599bdd1243dSDimitry Andric     // Always break after a JSON array opener based on BreakArrays.
5600bdd1243dSDimitry Andric     if ((Left.is(TT_ArrayInitializerLSquare) && Left.is(tok::l_square) &&
5601bdd1243dSDimitry Andric          Right.isNot(tok::r_square)) ||
5602bdd1243dSDimitry Andric         Left.is(tok::comma)) {
5603bdd1243dSDimitry Andric       if (Right.is(tok::l_brace))
5604fe6060f1SDimitry Andric         return true;
5605bdd1243dSDimitry Andric       // scan to the right if an we see an object or an array inside
5606bdd1243dSDimitry Andric       // then break.
5607bdd1243dSDimitry Andric       for (const auto *Tok = &Right; Tok; Tok = Tok->Next) {
5608bdd1243dSDimitry Andric         if (Tok->isOneOf(tok::l_brace, tok::l_square))
5609bdd1243dSDimitry Andric           return true;
5610bdd1243dSDimitry Andric         if (Tok->isOneOf(tok::r_brace, tok::r_square))
5611bdd1243dSDimitry Andric           break;
561281ad6265SDimitry Andric       }
5613bdd1243dSDimitry Andric       return Style.BreakArrays;
5614bdd1243dSDimitry Andric     }
56150fca6ea1SDimitry Andric   } else if (Style.isTableGen()) {
56160fca6ea1SDimitry Andric     // Break the comma in side cond operators.
56170fca6ea1SDimitry Andric     // !cond(case1:1,
56180fca6ea1SDimitry Andric     //       case2:0);
56190fca6ea1SDimitry Andric     if (Left.is(TT_TableGenCondOperatorComma))
56200fca6ea1SDimitry Andric       return true;
56210fca6ea1SDimitry Andric     if (Left.is(TT_TableGenDAGArgOperatorToBreak) &&
56220fca6ea1SDimitry Andric         Right.isNot(TT_TableGenDAGArgCloser)) {
56230fca6ea1SDimitry Andric       return true;
56240fca6ea1SDimitry Andric     }
56250fca6ea1SDimitry Andric     if (Left.is(TT_TableGenDAGArgListCommaToBreak))
56260fca6ea1SDimitry Andric       return true;
56270fca6ea1SDimitry Andric     if (Right.is(TT_TableGenDAGArgCloser) && Right.MatchingParen &&
56280fca6ea1SDimitry Andric         Right.MatchingParen->is(TT_TableGenDAGArgOpenerToBreak) &&
56290fca6ea1SDimitry Andric         &Left != Right.MatchingParen->Next) {
56300fca6ea1SDimitry Andric       // Check to avoid empty DAGArg such as (ins).
56310fca6ea1SDimitry Andric       return Style.TableGenBreakInsideDAGArg == FormatStyle::DAS_BreakAll;
56320fca6ea1SDimitry Andric     }
5633bdd1243dSDimitry Andric   }
5634bdd1243dSDimitry Andric 
5635bdd1243dSDimitry Andric   if (Line.startsWith(tok::kw_asm) && Right.is(TT_InlineASMColon) &&
5636bdd1243dSDimitry Andric       Style.BreakBeforeInlineASMColon == FormatStyle::BBIAS_Always) {
5637fe6060f1SDimitry Andric     return true;
5638fe6060f1SDimitry Andric   }
5639fe6060f1SDimitry Andric 
56400b57cec5SDimitry Andric   // If the last token before a '}', ']', or ')' is a comma or a trailing
56410b57cec5SDimitry Andric   // comment, the intention is to insert a line break after it in order to make
56420b57cec5SDimitry Andric   // shuffling around entries easier. Import statements, especially in
56430b57cec5SDimitry Andric   // JavaScript, can be an exception to this rule.
56440b57cec5SDimitry Andric   if (Style.JavaScriptWrapImports || Line.Type != LT_ImportStatement) {
56450b57cec5SDimitry Andric     const FormatToken *BeforeClosingBrace = nullptr;
56460b57cec5SDimitry Andric     if ((Left.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
56470eae32dcSDimitry Andric          (Style.isJavaScript() && Left.is(tok::l_paren))) &&
564881ad6265SDimitry Andric         Left.isNot(BK_Block) && Left.MatchingParen) {
56490b57cec5SDimitry Andric       BeforeClosingBrace = Left.MatchingParen->Previous;
565081ad6265SDimitry Andric     } else if (Right.MatchingParen &&
56510b57cec5SDimitry Andric                (Right.MatchingParen->isOneOf(tok::l_brace,
56520b57cec5SDimitry Andric                                              TT_ArrayInitializerLSquare) ||
565381ad6265SDimitry Andric                 (Style.isJavaScript() &&
565481ad6265SDimitry Andric                  Right.MatchingParen->is(tok::l_paren)))) {
56550b57cec5SDimitry Andric       BeforeClosingBrace = &Left;
565681ad6265SDimitry Andric     }
56570b57cec5SDimitry Andric     if (BeforeClosingBrace && (BeforeClosingBrace->is(tok::comma) ||
565881ad6265SDimitry Andric                                BeforeClosingBrace->isTrailingComment())) {
56590b57cec5SDimitry Andric       return true;
56600b57cec5SDimitry Andric     }
566181ad6265SDimitry Andric   }
56620b57cec5SDimitry Andric 
566381ad6265SDimitry Andric   if (Right.is(tok::comment)) {
5664e8d8bef9SDimitry Andric     return Left.isNot(BK_BracedInit) && Left.isNot(TT_CtorInitializerColon) &&
56650b57cec5SDimitry Andric            (Right.NewlinesBefore > 0 && Right.HasUnescapedNewline);
566681ad6265SDimitry Andric   }
56670b57cec5SDimitry Andric   if (Left.isTrailingComment())
56680b57cec5SDimitry Andric     return true;
566904eeddc0SDimitry Andric   if (Left.IsUnterminatedLiteral)
56700b57cec5SDimitry Andric     return true;
56710fca6ea1SDimitry Andric 
56720fca6ea1SDimitry Andric   if (BeforeLeft && BeforeLeft->is(tok::lessless) &&
56730fca6ea1SDimitry Andric       Left.is(tok::string_literal) && Right.is(tok::lessless) && AfterRight &&
56740fca6ea1SDimitry Andric       AfterRight->is(tok::string_literal)) {
56750fca6ea1SDimitry Andric     return Right.NewlinesBefore > 0;
56761db9f3b2SDimitry Andric   }
56770fca6ea1SDimitry Andric 
567881ad6265SDimitry Andric   if (Right.is(TT_RequiresClause)) {
567981ad6265SDimitry Andric     switch (Style.RequiresClausePosition) {
568081ad6265SDimitry Andric     case FormatStyle::RCPS_OwnLine:
568181ad6265SDimitry Andric     case FormatStyle::RCPS_WithFollowing:
568281ad6265SDimitry Andric       return true;
568381ad6265SDimitry Andric     default:
568481ad6265SDimitry Andric       break;
568581ad6265SDimitry Andric     }
568681ad6265SDimitry Andric   }
5687e8d8bef9SDimitry Andric   // Can break after template<> declaration
568804eeddc0SDimitry Andric   if (Left.ClosesTemplateDeclaration && Left.MatchingParen &&
568904eeddc0SDimitry Andric       Left.MatchingParen->NestingLevel == 0) {
5690e8d8bef9SDimitry Andric     // Put concepts on the next line e.g.
5691e8d8bef9SDimitry Andric     // template<typename T>
5692e8d8bef9SDimitry Andric     // concept ...
5693e8d8bef9SDimitry Andric     if (Right.is(tok::kw_concept))
569481ad6265SDimitry Andric       return Style.BreakBeforeConceptDeclarations == FormatStyle::BBCDS_Always;
56950fca6ea1SDimitry Andric     return Style.BreakTemplateDeclarations == FormatStyle::BTDS_Yes ||
56960fca6ea1SDimitry Andric            (Style.BreakTemplateDeclarations == FormatStyle::BTDS_Leave &&
56970fca6ea1SDimitry Andric             Right.NewlinesBefore > 0);
569881ad6265SDimitry Andric   }
569981ad6265SDimitry Andric   if (Left.ClosesRequiresClause && Right.isNot(tok::semi)) {
570081ad6265SDimitry Andric     switch (Style.RequiresClausePosition) {
570181ad6265SDimitry Andric     case FormatStyle::RCPS_OwnLine:
570281ad6265SDimitry Andric     case FormatStyle::RCPS_WithPreceding:
570381ad6265SDimitry Andric       return true;
570481ad6265SDimitry Andric     default:
570581ad6265SDimitry Andric       break;
570681ad6265SDimitry Andric     }
5707e8d8bef9SDimitry Andric   }
5708349cc55cSDimitry Andric   if (Style.PackConstructorInitializers == FormatStyle::PCIS_Never) {
5709349cc55cSDimitry Andric     if (Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeColon &&
571081ad6265SDimitry Andric         (Left.is(TT_CtorInitializerComma) ||
571181ad6265SDimitry Andric          Right.is(TT_CtorInitializerColon))) {
57120b57cec5SDimitry Andric       return true;
571381ad6265SDimitry Andric     }
5714349cc55cSDimitry Andric 
5715349cc55cSDimitry Andric     if (Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon &&
571681ad6265SDimitry Andric         Left.isOneOf(TT_CtorInitializerColon, TT_CtorInitializerComma)) {
5717349cc55cSDimitry Andric       return true;
5718349cc55cSDimitry Andric     }
571981ad6265SDimitry Andric   }
5720349cc55cSDimitry Andric   if (Style.PackConstructorInitializers < FormatStyle::PCIS_CurrentLine &&
57210b57cec5SDimitry Andric       Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma &&
572281ad6265SDimitry Andric       Right.isOneOf(TT_CtorInitializerComma, TT_CtorInitializerColon)) {
57230b57cec5SDimitry Andric     return true;
572481ad6265SDimitry Andric   }
572506c3fb27SDimitry Andric   if (Style.PackConstructorInitializers == FormatStyle::PCIS_NextLineOnly) {
572606c3fb27SDimitry Andric     if ((Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeColon ||
572706c3fb27SDimitry Andric          Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma) &&
572806c3fb27SDimitry Andric         Right.is(TT_CtorInitializerColon)) {
572906c3fb27SDimitry Andric       return true;
573006c3fb27SDimitry Andric     }
573106c3fb27SDimitry Andric 
573206c3fb27SDimitry Andric     if (Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon &&
573306c3fb27SDimitry Andric         Left.is(TT_CtorInitializerColon)) {
573406c3fb27SDimitry Andric       return true;
573506c3fb27SDimitry Andric     }
573606c3fb27SDimitry Andric   }
57370b57cec5SDimitry Andric   // Break only if we have multiple inheritance.
57380b57cec5SDimitry Andric   if (Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma &&
573981ad6265SDimitry Andric       Right.is(TT_InheritanceComma)) {
57400b57cec5SDimitry Andric     return true;
574181ad6265SDimitry Andric   }
5742fe6060f1SDimitry Andric   if (Style.BreakInheritanceList == FormatStyle::BILS_AfterComma &&
574381ad6265SDimitry Andric       Left.is(TT_InheritanceComma)) {
5744fe6060f1SDimitry Andric     return true;
574581ad6265SDimitry Andric   }
57465f757f3fSDimitry Andric   if (Right.is(tok::string_literal) && Right.TokenText.starts_with("R\"")) {
57470b57cec5SDimitry Andric     // Multiline raw string literals are special wrt. line breaks. The author
57480b57cec5SDimitry Andric     // has made a deliberate choice and might have aligned the contents of the
57490b57cec5SDimitry Andric     // string literal accordingly. Thus, we try keep existing line breaks.
57500b57cec5SDimitry Andric     return Right.IsMultiline && Right.NewlinesBefore > 0;
575181ad6265SDimitry Andric   }
57520fca6ea1SDimitry Andric   if ((Left.is(tok::l_brace) ||
57530fca6ea1SDimitry Andric        (Left.is(tok::less) && BeforeLeft && BeforeLeft->is(tok::equal))) &&
57540b57cec5SDimitry Andric       Right.NestingLevel == 1 && Style.Language == FormatStyle::LK_Proto) {
57550b57cec5SDimitry Andric     // Don't put enums or option definitions onto single lines in protocol
57560b57cec5SDimitry Andric     // buffers.
57570b57cec5SDimitry Andric     return true;
57580b57cec5SDimitry Andric   }
57590b57cec5SDimitry Andric   if (Right.is(TT_InlineASMBrace))
57600b57cec5SDimitry Andric     return Right.HasUnescapedNewline;
57615ffd83dbSDimitry Andric 
5762349cc55cSDimitry Andric   if (isAllmanBrace(Left) || isAllmanBrace(Right)) {
57635f757f3fSDimitry Andric     auto *FirstNonComment = Line.getFirstNonComment();
5764349cc55cSDimitry Andric     bool AccessSpecifier =
57650fca6ea1SDimitry Andric         FirstNonComment && (FirstNonComment->is(Keywords.kw_internal) ||
57660fca6ea1SDimitry Andric                             FirstNonComment->isAccessSpecifierKeyword());
5767349cc55cSDimitry Andric 
5768349cc55cSDimitry Andric     if (Style.BraceWrapping.AfterEnum) {
5769349cc55cSDimitry Andric       if (Line.startsWith(tok::kw_enum) ||
577081ad6265SDimitry Andric           Line.startsWith(tok::kw_typedef, tok::kw_enum)) {
5771349cc55cSDimitry Andric         return true;
577281ad6265SDimitry Andric       }
5773349cc55cSDimitry Andric       // Ensure BraceWrapping for `public enum A {`.
5774349cc55cSDimitry Andric       if (AccessSpecifier && FirstNonComment->Next &&
577581ad6265SDimitry Andric           FirstNonComment->Next->is(tok::kw_enum)) {
5776349cc55cSDimitry Andric         return true;
5777349cc55cSDimitry Andric       }
577881ad6265SDimitry Andric     }
5779349cc55cSDimitry Andric 
5780349cc55cSDimitry Andric     // Ensure BraceWrapping for `public interface A {`.
5781349cc55cSDimitry Andric     if (Style.BraceWrapping.AfterClass &&
5782349cc55cSDimitry Andric         ((AccessSpecifier && FirstNonComment->Next &&
5783349cc55cSDimitry Andric           FirstNonComment->Next->is(Keywords.kw_interface)) ||
578481ad6265SDimitry Andric          Line.startsWith(Keywords.kw_interface))) {
5785349cc55cSDimitry Andric       return true;
578681ad6265SDimitry Andric     }
5787349cc55cSDimitry Andric 
578806c3fb27SDimitry Andric     // Don't attempt to interpret struct return types as structs.
578906c3fb27SDimitry Andric     if (Right.isNot(TT_FunctionLBrace)) {
579006c3fb27SDimitry Andric       return (Line.startsWith(tok::kw_class) &&
579106c3fb27SDimitry Andric               Style.BraceWrapping.AfterClass) ||
579206c3fb27SDimitry Andric              (Line.startsWith(tok::kw_struct) &&
579306c3fb27SDimitry Andric               Style.BraceWrapping.AfterStruct);
579406c3fb27SDimitry Andric     }
5795349cc55cSDimitry Andric   }
5796349cc55cSDimitry Andric 
5797a7dea167SDimitry Andric   if (Left.is(TT_ObjCBlockLBrace) &&
579881ad6265SDimitry Andric       Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Never) {
57990b57cec5SDimitry Andric     return true;
580081ad6265SDimitry Andric   }
58010b57cec5SDimitry Andric 
5802349cc55cSDimitry Andric   // Ensure wrapping after __attribute__((XX)) and @interface etc.
58035f757f3fSDimitry Andric   if (Left.isOneOf(TT_AttributeRParen, TT_AttributeMacro) &&
58045f757f3fSDimitry Andric       Right.is(TT_ObjCDecl)) {
5805349cc55cSDimitry Andric     return true;
58065f757f3fSDimitry Andric   }
5807349cc55cSDimitry Andric 
58080b57cec5SDimitry Andric   if (Left.is(TT_LambdaLBrace)) {
58095ffd83dbSDimitry Andric     if (IsFunctionArgument(Left) &&
581081ad6265SDimitry Andric         Style.AllowShortLambdasOnASingleLine == FormatStyle::SLS_Inline) {
58110b57cec5SDimitry Andric       return false;
581281ad6265SDimitry Andric     }
58130b57cec5SDimitry Andric 
58140b57cec5SDimitry Andric     if (Style.AllowShortLambdasOnASingleLine == FormatStyle::SLS_None ||
58150b57cec5SDimitry Andric         Style.AllowShortLambdasOnASingleLine == FormatStyle::SLS_Inline ||
58160b57cec5SDimitry Andric         (!Left.Children.empty() &&
581781ad6265SDimitry Andric          Style.AllowShortLambdasOnASingleLine == FormatStyle::SLS_Empty)) {
58180b57cec5SDimitry Andric       return true;
58190b57cec5SDimitry Andric     }
582081ad6265SDimitry Andric   }
58210b57cec5SDimitry Andric 
5822fe6060f1SDimitry Andric   if (Style.BraceWrapping.BeforeLambdaBody && Right.is(TT_LambdaLBrace) &&
58235f757f3fSDimitry Andric       (Left.isPointerOrReference() || Left.is(TT_TemplateCloser))) {
5824fe6060f1SDimitry Andric     return true;
5825fe6060f1SDimitry Andric   }
5826fe6060f1SDimitry Andric 
58270b57cec5SDimitry Andric   // Put multiple Java annotation on a new line.
58280eae32dcSDimitry Andric   if ((Style.Language == FormatStyle::LK_Java || Style.isJavaScript()) &&
58290b57cec5SDimitry Andric       Left.is(TT_LeadingJavaAnnotation) &&
58300b57cec5SDimitry Andric       Right.isNot(TT_LeadingJavaAnnotation) && Right.isNot(tok::l_paren) &&
583181ad6265SDimitry Andric       (Line.Last->is(tok::l_brace) || Style.BreakAfterJavaFieldAnnotations)) {
58320b57cec5SDimitry Andric     return true;
583381ad6265SDimitry Andric   }
58340b57cec5SDimitry Andric 
58350b57cec5SDimitry Andric   if (Right.is(TT_ProtoExtensionLSquare))
58360b57cec5SDimitry Andric     return true;
58370b57cec5SDimitry Andric 
58380b57cec5SDimitry Andric   // In text proto instances if a submessage contains at least 2 entries and at
58390b57cec5SDimitry Andric   // least one of them is a submessage, like A { ... B { ... } ... },
58400b57cec5SDimitry Andric   // put all of the entries of A on separate lines by forcing the selector of
58410b57cec5SDimitry Andric   // the submessage B to be put on a newline.
58420b57cec5SDimitry Andric   //
58430b57cec5SDimitry Andric   // Example: these can stay on one line:
58440b57cec5SDimitry Andric   // a { scalar_1: 1 scalar_2: 2 }
58450b57cec5SDimitry Andric   // a { b { key: value } }
58460b57cec5SDimitry Andric   //
58470b57cec5SDimitry Andric   // and these entries need to be on a new line even if putting them all in one
58480b57cec5SDimitry Andric   // line is under the column limit:
58490b57cec5SDimitry Andric   // a {
58500b57cec5SDimitry Andric   //   scalar: 1
58510b57cec5SDimitry Andric   //   b { key: value }
58520b57cec5SDimitry Andric   // }
58530b57cec5SDimitry Andric   //
58540b57cec5SDimitry Andric   // We enforce this by breaking before a submessage field that has previous
58550b57cec5SDimitry Andric   // siblings, *and* breaking before a field that follows a submessage field.
58560b57cec5SDimitry Andric   //
58570b57cec5SDimitry Andric   // Be careful to exclude the case  [proto.ext] { ... } since the `]` is
58580b57cec5SDimitry Andric   // the TT_SelectorName there, but we don't want to break inside the brackets.
58590b57cec5SDimitry Andric   //
58600b57cec5SDimitry Andric   // Another edge case is @submessage { key: value }, which is a common
58610b57cec5SDimitry Andric   // substitution placeholder. In this case we want to keep `@` and `submessage`
58620b57cec5SDimitry Andric   // together.
58630b57cec5SDimitry Andric   //
58640b57cec5SDimitry Andric   // We ensure elsewhere that extensions are always on their own line.
58655f757f3fSDimitry Andric   if (Style.isProto() && Right.is(TT_SelectorName) &&
58660fca6ea1SDimitry Andric       Right.isNot(tok::r_square) && AfterRight) {
58670b57cec5SDimitry Andric     // Keep `@submessage` together in:
58680b57cec5SDimitry Andric     // @submessage { key: value }
586904eeddc0SDimitry Andric     if (Left.is(tok::at))
58700b57cec5SDimitry Andric       return false;
58710b57cec5SDimitry Andric     // Look for the scope opener after selector in cases like:
58720b57cec5SDimitry Andric     // selector { ...
58730b57cec5SDimitry Andric     // selector: { ...
58740b57cec5SDimitry Andric     // selector: @base { ...
58750fca6ea1SDimitry Andric     const auto *LBrace = AfterRight;
58760b57cec5SDimitry Andric     if (LBrace && LBrace->is(tok::colon)) {
58770b57cec5SDimitry Andric       LBrace = LBrace->Next;
58780b57cec5SDimitry Andric       if (LBrace && LBrace->is(tok::at)) {
58790b57cec5SDimitry Andric         LBrace = LBrace->Next;
58800b57cec5SDimitry Andric         if (LBrace)
58810b57cec5SDimitry Andric           LBrace = LBrace->Next;
58820b57cec5SDimitry Andric       }
58830b57cec5SDimitry Andric     }
58840b57cec5SDimitry Andric     if (LBrace &&
58850b57cec5SDimitry Andric         // The scope opener is one of {, [, <:
58860b57cec5SDimitry Andric         // selector { ... }
58870b57cec5SDimitry Andric         // selector [ ... ]
58880b57cec5SDimitry Andric         // selector < ... >
58890b57cec5SDimitry Andric         //
58900b57cec5SDimitry Andric         // In case of selector { ... }, the l_brace is TT_DictLiteral.
58910b57cec5SDimitry Andric         // In case of an empty selector {}, the l_brace is not TT_DictLiteral,
58920b57cec5SDimitry Andric         // so we check for immediately following r_brace.
58930b57cec5SDimitry Andric         ((LBrace->is(tok::l_brace) &&
58940b57cec5SDimitry Andric           (LBrace->is(TT_DictLiteral) ||
58950b57cec5SDimitry Andric            (LBrace->Next && LBrace->Next->is(tok::r_brace)))) ||
58960b57cec5SDimitry Andric          LBrace->is(TT_ArrayInitializerLSquare) || LBrace->is(tok::less))) {
58970b57cec5SDimitry Andric       // If Left.ParameterCount is 0, then this submessage entry is not the
58980b57cec5SDimitry Andric       // first in its parent submessage, and we want to break before this entry.
58990b57cec5SDimitry Andric       // If Left.ParameterCount is greater than 0, then its parent submessage
59000b57cec5SDimitry Andric       // might contain 1 or more entries and we want to break before this entry
59010b57cec5SDimitry Andric       // if it contains at least 2 entries. We deal with this case later by
59020b57cec5SDimitry Andric       // detecting and breaking before the next entry in the parent submessage.
59030b57cec5SDimitry Andric       if (Left.ParameterCount == 0)
59040b57cec5SDimitry Andric         return true;
59050b57cec5SDimitry Andric       // However, if this submessage is the first entry in its parent
59060b57cec5SDimitry Andric       // submessage, Left.ParameterCount might be 1 in some cases.
59070b57cec5SDimitry Andric       // We deal with this case later by detecting an entry
59080b57cec5SDimitry Andric       // following a closing paren of this submessage.
59090b57cec5SDimitry Andric     }
59100b57cec5SDimitry Andric 
59110b57cec5SDimitry Andric     // If this is an entry immediately following a submessage, it will be
59120b57cec5SDimitry Andric     // preceded by a closing paren of that submessage, like in:
59130b57cec5SDimitry Andric     //     left---.  .---right
59140b57cec5SDimitry Andric     //            v  v
59150b57cec5SDimitry Andric     // sub: { ... } key: value
59160b57cec5SDimitry Andric     // If there was a comment between `}` an `key` above, then `key` would be
59170b57cec5SDimitry Andric     // put on a new line anyways.
59180b57cec5SDimitry Andric     if (Left.isOneOf(tok::r_brace, tok::greater, tok::r_square))
59190b57cec5SDimitry Andric       return true;
59200b57cec5SDimitry Andric   }
59210b57cec5SDimitry Andric 
59220b57cec5SDimitry Andric   return false;
59230b57cec5SDimitry Andric }
59240b57cec5SDimitry Andric 
59250b57cec5SDimitry Andric bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
592681ad6265SDimitry Andric                                     const FormatToken &Right) const {
59270b57cec5SDimitry Andric   const FormatToken &Left = *Right.Previous;
59280b57cec5SDimitry Andric   // Language-specific stuff.
59295ffd83dbSDimitry Andric   if (Style.isCSharp()) {
59305ffd83dbSDimitry Andric     if (Left.isOneOf(TT_CSharpNamedArgumentColon, TT_AttributeColon) ||
593181ad6265SDimitry Andric         Right.isOneOf(TT_CSharpNamedArgumentColon, TT_AttributeColon)) {
59325ffd83dbSDimitry Andric       return false;
593381ad6265SDimitry Andric     }
59345ffd83dbSDimitry Andric     // Only break after commas for generic type constraints.
59355ffd83dbSDimitry Andric     if (Line.First->is(TT_CSharpGenericTypeConstraint))
59365ffd83dbSDimitry Andric       return Left.is(TT_CSharpGenericTypeConstraintComma);
5937fe6060f1SDimitry Andric     // Keep nullable operators attached to their identifiers.
593881ad6265SDimitry Andric     if (Right.is(TT_CSharpNullable))
5939fe6060f1SDimitry Andric       return false;
59405ffd83dbSDimitry Andric   } else if (Style.Language == FormatStyle::LK_Java) {
59410b57cec5SDimitry Andric     if (Left.isOneOf(Keywords.kw_throws, Keywords.kw_extends,
594281ad6265SDimitry Andric                      Keywords.kw_implements)) {
59430b57cec5SDimitry Andric       return false;
594481ad6265SDimitry Andric     }
59450b57cec5SDimitry Andric     if (Right.isOneOf(Keywords.kw_throws, Keywords.kw_extends,
594681ad6265SDimitry Andric                       Keywords.kw_implements)) {
59470b57cec5SDimitry Andric       return true;
594881ad6265SDimitry Andric     }
59490eae32dcSDimitry Andric   } else if (Style.isJavaScript()) {
59500b57cec5SDimitry Andric     const FormatToken *NonComment = Right.getPreviousNonComment();
59510b57cec5SDimitry Andric     if (NonComment &&
59520fca6ea1SDimitry Andric         (NonComment->isAccessSpecifierKeyword() ||
59530b57cec5SDimitry Andric          NonComment->isOneOf(
59540b57cec5SDimitry Andric              tok::kw_return, Keywords.kw_yield, tok::kw_continue, tok::kw_break,
59550b57cec5SDimitry Andric              tok::kw_throw, Keywords.kw_interface, Keywords.kw_type,
59560fca6ea1SDimitry Andric              tok::kw_static, Keywords.kw_readonly, Keywords.kw_override,
59570fca6ea1SDimitry Andric              Keywords.kw_abstract, Keywords.kw_get, Keywords.kw_set,
59580fca6ea1SDimitry Andric              Keywords.kw_async, Keywords.kw_await))) {
59590b57cec5SDimitry Andric       return false; // Otherwise automatic semicolon insertion would trigger.
596081ad6265SDimitry Andric     }
59610b57cec5SDimitry Andric     if (Right.NestingLevel == 0 &&
59620b57cec5SDimitry Andric         (Left.Tok.getIdentifierInfo() ||
59630b57cec5SDimitry Andric          Left.isOneOf(tok::r_square, tok::r_paren)) &&
596481ad6265SDimitry Andric         Right.isOneOf(tok::l_square, tok::l_paren)) {
59650b57cec5SDimitry Andric       return false; // Otherwise automatic semicolon insertion would trigger.
596681ad6265SDimitry Andric     }
5967fe6060f1SDimitry Andric     if (NonComment && NonComment->is(tok::identifier) &&
596881ad6265SDimitry Andric         NonComment->TokenText == "asserts") {
5969fe6060f1SDimitry Andric       return false;
597081ad6265SDimitry Andric     }
5971fe6060f1SDimitry Andric     if (Left.is(TT_FatArrow) && Right.is(tok::l_brace))
59720b57cec5SDimitry Andric       return false;
59730b57cec5SDimitry Andric     if (Left.is(TT_JsTypeColon))
59740b57cec5SDimitry Andric       return true;
59750b57cec5SDimitry Andric     // Don't wrap between ":" and "!" of a strict prop init ("field!: type;").
59760b57cec5SDimitry Andric     if (Left.is(tok::exclaim) && Right.is(tok::colon))
59770b57cec5SDimitry Andric       return false;
59780b57cec5SDimitry Andric     // Look for is type annotations like:
59790b57cec5SDimitry Andric     // function f(): a is B { ... }
59800b57cec5SDimitry Andric     // Do not break before is in these cases.
59810b57cec5SDimitry Andric     if (Right.is(Keywords.kw_is)) {
59820b57cec5SDimitry Andric       const FormatToken *Next = Right.getNextNonComment();
59830b57cec5SDimitry Andric       // If `is` is followed by a colon, it's likely that it's a dict key, so
59840b57cec5SDimitry Andric       // ignore it for this check.
59850b57cec5SDimitry Andric       // For example this is common in Polymer:
59860b57cec5SDimitry Andric       // Polymer({
59870b57cec5SDimitry Andric       //   is: 'name',
59880b57cec5SDimitry Andric       //   ...
59890b57cec5SDimitry Andric       // });
59905f757f3fSDimitry Andric       if (!Next || Next->isNot(tok::colon))
59910b57cec5SDimitry Andric         return false;
59920b57cec5SDimitry Andric     }
59930b57cec5SDimitry Andric     if (Left.is(Keywords.kw_in))
59940b57cec5SDimitry Andric       return Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None;
59950b57cec5SDimitry Andric     if (Right.is(Keywords.kw_in))
59960b57cec5SDimitry Andric       return Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None;
59970b57cec5SDimitry Andric     if (Right.is(Keywords.kw_as))
59980b57cec5SDimitry Andric       return false; // must not break before as in 'x as type' casts
59990b57cec5SDimitry Andric     if (Right.isOneOf(Keywords.kw_extends, Keywords.kw_infer)) {
60000b57cec5SDimitry Andric       // extends and infer can appear as keywords in conditional types:
60010b57cec5SDimitry Andric       //   https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#conditional-types
60020b57cec5SDimitry Andric       // do not break before them, as the expressions are subject to ASI.
60030b57cec5SDimitry Andric       return false;
60040b57cec5SDimitry Andric     }
60050b57cec5SDimitry Andric     if (Left.is(Keywords.kw_as))
60060b57cec5SDimitry Andric       return true;
6007fe6060f1SDimitry Andric     if (Left.is(TT_NonNullAssertion))
60080b57cec5SDimitry Andric       return true;
60090b57cec5SDimitry Andric     if (Left.is(Keywords.kw_declare) &&
60100b57cec5SDimitry Andric         Right.isOneOf(Keywords.kw_module, tok::kw_namespace,
60110b57cec5SDimitry Andric                       Keywords.kw_function, tok::kw_class, tok::kw_enum,
60120b57cec5SDimitry Andric                       Keywords.kw_interface, Keywords.kw_type, Keywords.kw_var,
601381ad6265SDimitry Andric                       Keywords.kw_let, tok::kw_const)) {
60140b57cec5SDimitry Andric       // See grammar for 'declare' statements at:
6015349cc55cSDimitry Andric       // https://github.com/Microsoft/TypeScript/blob/main/doc/spec-ARCHIVED.md#A.10
60160b57cec5SDimitry Andric       return false;
601781ad6265SDimitry Andric     }
60180b57cec5SDimitry Andric     if (Left.isOneOf(Keywords.kw_module, tok::kw_namespace) &&
601981ad6265SDimitry Andric         Right.isOneOf(tok::identifier, tok::string_literal)) {
60200b57cec5SDimitry Andric       return false; // must not break in "module foo { ...}"
602181ad6265SDimitry Andric     }
60220b57cec5SDimitry Andric     if (Right.is(TT_TemplateString) && Right.closesScope())
60230b57cec5SDimitry Andric       return false;
60240b57cec5SDimitry Andric     // Don't split tagged template literal so there is a break between the tag
60250b57cec5SDimitry Andric     // identifier and template string.
602681ad6265SDimitry Andric     if (Left.is(tok::identifier) && Right.is(TT_TemplateString))
60270b57cec5SDimitry Andric       return false;
60280b57cec5SDimitry Andric     if (Left.is(TT_TemplateString) && Left.opensScope())
60290b57cec5SDimitry Andric       return true;
60300fca6ea1SDimitry Andric   } else if (Style.isTableGen()) {
60310fca6ea1SDimitry Andric     // Avoid to break after "def", "class", "let" and so on.
60320fca6ea1SDimitry Andric     if (Keywords.isTableGenDefinition(Left))
60330fca6ea1SDimitry Andric       return false;
60340fca6ea1SDimitry Andric     // Avoid to break after '(' in the cases that is in bang operators.
60350fca6ea1SDimitry Andric     if (Right.is(tok::l_paren)) {
60360fca6ea1SDimitry Andric       return !Left.isOneOf(TT_TableGenBangOperator, TT_TableGenCondOperator,
60370fca6ea1SDimitry Andric                            TT_TemplateCloser);
60380fca6ea1SDimitry Andric     }
60390fca6ea1SDimitry Andric     // Avoid to break between the value and its suffix part.
60400fca6ea1SDimitry Andric     if (Left.is(TT_TableGenValueSuffix))
60410fca6ea1SDimitry Andric       return false;
60420fca6ea1SDimitry Andric     // Avoid to break around paste operator.
60430fca6ea1SDimitry Andric     if (Left.is(tok::hash) || Right.is(tok::hash))
60440fca6ea1SDimitry Andric       return false;
60450fca6ea1SDimitry Andric     if (Left.isOneOf(TT_TableGenBangOperator, TT_TableGenCondOperator))
60460fca6ea1SDimitry Andric       return false;
60470b57cec5SDimitry Andric   }
60480b57cec5SDimitry Andric 
60490b57cec5SDimitry Andric   if (Left.is(tok::at))
60500b57cec5SDimitry Andric     return false;
60510b57cec5SDimitry Andric   if (Left.Tok.getObjCKeywordID() == tok::objc_interface)
60520b57cec5SDimitry Andric     return false;
60530b57cec5SDimitry Andric   if (Left.isOneOf(TT_JavaAnnotation, TT_LeadingJavaAnnotation))
60545f757f3fSDimitry Andric     return Right.isNot(tok::l_paren);
605581ad6265SDimitry Andric   if (Right.is(TT_PointerOrReference)) {
60560b57cec5SDimitry Andric     return Line.IsMultiVariableDeclStmt ||
6057fe6060f1SDimitry Andric            (getTokenPointerOrReferenceAlignment(Right) ==
6058fe6060f1SDimitry Andric                 FormatStyle::PAS_Right &&
60590b57cec5SDimitry Andric             (!Right.Next || Right.Next->isNot(TT_FunctionDeclarationName)));
606081ad6265SDimitry Andric   }
60610b57cec5SDimitry Andric   if (Right.isOneOf(TT_StartOfName, TT_FunctionDeclarationName) ||
606281ad6265SDimitry Andric       Right.is(tok::kw_operator)) {
60630b57cec5SDimitry Andric     return true;
606481ad6265SDimitry Andric   }
60650b57cec5SDimitry Andric   if (Left.is(TT_PointerOrReference))
60660b57cec5SDimitry Andric     return false;
606781ad6265SDimitry Andric   if (Right.isTrailingComment()) {
60680b57cec5SDimitry Andric     // We rely on MustBreakBefore being set correctly here as we should not
60690b57cec5SDimitry Andric     // change the "binding" behavior of a comment.
60700b57cec5SDimitry Andric     // The first comment in a braced lists is always interpreted as belonging to
60710b57cec5SDimitry Andric     // the first list element. Otherwise, it should be placed outside of the
60720b57cec5SDimitry Andric     // list.
6073e8d8bef9SDimitry Andric     return Left.is(BK_BracedInit) ||
6074753f127fSDimitry Andric            (Left.is(TT_CtorInitializerColon) && Right.NewlinesBefore > 0 &&
60750b57cec5SDimitry Andric             Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon);
607681ad6265SDimitry Andric   }
60770b57cec5SDimitry Andric   if (Left.is(tok::question) && Right.is(tok::colon))
60780b57cec5SDimitry Andric     return false;
60790b57cec5SDimitry Andric   if (Right.is(TT_ConditionalExpr) || Right.is(tok::question))
60800b57cec5SDimitry Andric     return Style.BreakBeforeTernaryOperators;
60810b57cec5SDimitry Andric   if (Left.is(TT_ConditionalExpr) || Left.is(tok::question))
60820b57cec5SDimitry Andric     return !Style.BreakBeforeTernaryOperators;
60830b57cec5SDimitry Andric   if (Left.is(TT_InheritanceColon))
60840b57cec5SDimitry Andric     return Style.BreakInheritanceList == FormatStyle::BILS_AfterColon;
60850b57cec5SDimitry Andric   if (Right.is(TT_InheritanceColon))
60860b57cec5SDimitry Andric     return Style.BreakInheritanceList != FormatStyle::BILS_AfterColon;
60875f757f3fSDimitry Andric   if (Right.is(TT_ObjCMethodExpr) && Right.isNot(tok::r_square) &&
608881ad6265SDimitry Andric       Left.isNot(TT_SelectorName)) {
60890b57cec5SDimitry Andric     return true;
609081ad6265SDimitry Andric   }
60910b57cec5SDimitry Andric 
60920b57cec5SDimitry Andric   if (Right.is(tok::colon) &&
609381ad6265SDimitry Andric       !Right.isOneOf(TT_CtorInitializerColon, TT_InlineASMColon)) {
60940b57cec5SDimitry Andric     return false;
609581ad6265SDimitry Andric   }
60960b57cec5SDimitry Andric   if (Left.is(tok::colon) && Left.isOneOf(TT_DictLiteral, TT_ObjCMethodExpr)) {
60975f757f3fSDimitry Andric     if (Style.isProto()) {
60980b57cec5SDimitry Andric       if (!Style.AlwaysBreakBeforeMultilineStrings && Right.isStringLiteral())
60990b57cec5SDimitry Andric         return false;
61000b57cec5SDimitry Andric       // Prevent cases like:
61010b57cec5SDimitry Andric       //
61020b57cec5SDimitry Andric       // submessage:
61030b57cec5SDimitry Andric       //     { key: valueeeeeeeeeeee }
61040b57cec5SDimitry Andric       //
61050b57cec5SDimitry Andric       // when the snippet does not fit into one line.
61060b57cec5SDimitry Andric       // Prefer:
61070b57cec5SDimitry Andric       //
61080b57cec5SDimitry Andric       // submessage: {
61090b57cec5SDimitry Andric       //   key: valueeeeeeeeeeee
61100b57cec5SDimitry Andric       // }
61110b57cec5SDimitry Andric       //
61120b57cec5SDimitry Andric       // instead, even if it is longer by one line.
61130b57cec5SDimitry Andric       //
6114bdd1243dSDimitry Andric       // Note that this allows the "{" to go over the column limit
61150b57cec5SDimitry Andric       // when the column limit is just between ":" and "{", but that does
61160b57cec5SDimitry Andric       // not happen too often and alternative formattings in this case are
61170b57cec5SDimitry Andric       // not much better.
61180b57cec5SDimitry Andric       //
61190b57cec5SDimitry Andric       // The code covers the cases:
61200b57cec5SDimitry Andric       //
61210b57cec5SDimitry Andric       // submessage: { ... }
61220b57cec5SDimitry Andric       // submessage: < ... >
61230b57cec5SDimitry Andric       // repeated: [ ... ]
61240b57cec5SDimitry Andric       if (((Right.is(tok::l_brace) || Right.is(tok::less)) &&
61250b57cec5SDimitry Andric            Right.is(TT_DictLiteral)) ||
612681ad6265SDimitry Andric           Right.is(TT_ArrayInitializerLSquare)) {
61270b57cec5SDimitry Andric         return false;
61280b57cec5SDimitry Andric       }
612981ad6265SDimitry Andric     }
61300b57cec5SDimitry Andric     return true;
61310b57cec5SDimitry Andric   }
61320b57cec5SDimitry Andric   if (Right.is(tok::r_square) && Right.MatchingParen &&
613381ad6265SDimitry Andric       Right.MatchingParen->is(TT_ProtoExtensionLSquare)) {
61340b57cec5SDimitry Andric     return false;
613581ad6265SDimitry Andric   }
61360b57cec5SDimitry Andric   if (Right.is(TT_SelectorName) || (Right.is(tok::identifier) && Right.Next &&
613781ad6265SDimitry Andric                                     Right.Next->is(TT_ObjCMethodExpr))) {
61380b57cec5SDimitry Andric     return Left.isNot(tok::period); // FIXME: Properly parse ObjC calls.
613981ad6265SDimitry Andric   }
61400b57cec5SDimitry Andric   if (Left.is(tok::r_paren) && Line.Type == LT_ObjCProperty)
61410b57cec5SDimitry Andric     return true;
614281ad6265SDimitry Andric   if (Right.is(tok::kw_concept))
614381ad6265SDimitry Andric     return Style.BreakBeforeConceptDeclarations != FormatStyle::BBCDS_Never;
614481ad6265SDimitry Andric   if (Right.is(TT_RequiresClause))
614581ad6265SDimitry Andric     return true;
61460fca6ea1SDimitry Andric   if (Left.ClosesTemplateDeclaration) {
61470fca6ea1SDimitry Andric     return Style.BreakTemplateDeclarations != FormatStyle::BTDS_Leave ||
61480fca6ea1SDimitry Andric            Right.NewlinesBefore > 0;
61490fca6ea1SDimitry Andric   }
61500fca6ea1SDimitry Andric   if (Left.is(TT_FunctionAnnotationRParen))
61510b57cec5SDimitry Andric     return true;
615281ad6265SDimitry Andric   if (Left.ClosesRequiresClause)
615381ad6265SDimitry Andric     return true;
61540b57cec5SDimitry Andric   if (Right.isOneOf(TT_RangeBasedForLoopColon, TT_OverloadedOperatorLParen,
615581ad6265SDimitry Andric                     TT_OverloadedOperator)) {
61560b57cec5SDimitry Andric     return false;
615781ad6265SDimitry Andric   }
61580b57cec5SDimitry Andric   if (Left.is(TT_RangeBasedForLoopColon))
61590b57cec5SDimitry Andric     return true;
61600b57cec5SDimitry Andric   if (Right.is(TT_RangeBasedForLoopColon))
61610b57cec5SDimitry Andric     return false;
61620b57cec5SDimitry Andric   if (Left.is(TT_TemplateCloser) && Right.is(TT_TemplateOpener))
61630b57cec5SDimitry Andric     return true;
616481ad6265SDimitry Andric   if ((Left.is(tok::greater) && Right.is(tok::greater)) ||
616581ad6265SDimitry Andric       (Left.is(tok::less) && Right.is(tok::less))) {
616681ad6265SDimitry Andric     return false;
616781ad6265SDimitry Andric   }
616881ad6265SDimitry Andric   if (Right.is(TT_BinaryOperator) &&
616981ad6265SDimitry Andric       Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None &&
617081ad6265SDimitry Andric       (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_All ||
617181ad6265SDimitry Andric        Right.getPrecedence() != prec::Assignment)) {
617281ad6265SDimitry Andric     return true;
617381ad6265SDimitry Andric   }
61740b57cec5SDimitry Andric   if (Left.isOneOf(TT_TemplateCloser, TT_UnaryOperator) ||
617581ad6265SDimitry Andric       Left.is(tok::kw_operator)) {
61760b57cec5SDimitry Andric     return false;
617781ad6265SDimitry Andric   }
61780b57cec5SDimitry Andric   if (Left.is(tok::equal) && !Right.isOneOf(tok::kw_default, tok::kw_delete) &&
617981ad6265SDimitry Andric       Line.Type == LT_VirtualFunctionDecl && Left.NestingLevel == 0) {
61800b57cec5SDimitry Andric     return false;
618181ad6265SDimitry Andric   }
61820b57cec5SDimitry Andric   if (Left.is(tok::equal) && Right.is(tok::l_brace) &&
618381ad6265SDimitry Andric       !Style.Cpp11BracedListStyle) {
61840b57cec5SDimitry Andric     return false;
618581ad6265SDimitry Andric   }
61865f757f3fSDimitry Andric   if (Left.is(TT_AttributeLParen) ||
61875f757f3fSDimitry Andric       (Left.is(tok::l_paren) && Left.is(TT_TypeDeclarationParen))) {
61880b57cec5SDimitry Andric     return false;
618981ad6265SDimitry Andric   }
61900b57cec5SDimitry Andric   if (Left.is(tok::l_paren) && Left.Previous &&
619181ad6265SDimitry Andric       (Left.Previous->isOneOf(TT_BinaryOperator, TT_CastRParen))) {
61920b57cec5SDimitry Andric     return false;
619381ad6265SDimitry Andric   }
61940b57cec5SDimitry Andric   if (Right.is(TT_ImplicitStringLiteral))
61950b57cec5SDimitry Andric     return false;
61960b57cec5SDimitry Andric 
619704eeddc0SDimitry Andric   if (Right.is(TT_TemplateCloser))
61980b57cec5SDimitry Andric     return false;
61990b57cec5SDimitry Andric   if (Right.is(tok::r_square) && Right.MatchingParen &&
620081ad6265SDimitry Andric       Right.MatchingParen->is(TT_LambdaLSquare)) {
62010b57cec5SDimitry Andric     return false;
620281ad6265SDimitry Andric   }
62030b57cec5SDimitry Andric 
62040b57cec5SDimitry Andric   // We only break before r_brace if there was a corresponding break before
62050b57cec5SDimitry Andric   // the l_brace, which is tracked by BreakBeforeClosingBrace.
620606c3fb27SDimitry Andric   if (Right.is(tok::r_brace)) {
620706c3fb27SDimitry Andric     return Right.MatchingParen && (Right.MatchingParen->is(BK_Block) ||
620806c3fb27SDimitry Andric                                    (Right.isBlockIndentedInitRBrace(Style)));
620906c3fb27SDimitry Andric   }
62100b57cec5SDimitry Andric 
621104eeddc0SDimitry Andric   // We only break before r_paren if we're in a block indented context.
621204eeddc0SDimitry Andric   if (Right.is(tok::r_paren)) {
621381ad6265SDimitry Andric     if (Style.AlignAfterOpenBracket != FormatStyle::BAS_BlockIndent ||
621481ad6265SDimitry Andric         !Right.MatchingParen) {
621504eeddc0SDimitry Andric       return false;
621604eeddc0SDimitry Andric     }
6217bdd1243dSDimitry Andric     auto Next = Right.Next;
6218bdd1243dSDimitry Andric     if (Next && Next->is(tok::r_paren))
6219bdd1243dSDimitry Andric       Next = Next->Next;
6220bdd1243dSDimitry Andric     if (Next && Next->is(tok::l_paren))
6221bdd1243dSDimitry Andric       return false;
622281ad6265SDimitry Andric     const FormatToken *Previous = Right.MatchingParen->Previous;
622381ad6265SDimitry Andric     return !(Previous && (Previous->is(tok::kw_for) || Previous->isIf()));
622481ad6265SDimitry Andric   }
622504eeddc0SDimitry Andric 
62260b57cec5SDimitry Andric   // Allow breaking after a trailing annotation, e.g. after a method
62270b57cec5SDimitry Andric   // declaration.
622881ad6265SDimitry Andric   if (Left.is(TT_TrailingAnnotation)) {
62290b57cec5SDimitry Andric     return !Right.isOneOf(tok::l_brace, tok::semi, tok::equal, tok::l_paren,
62300b57cec5SDimitry Andric                           tok::less, tok::coloncolon);
623181ad6265SDimitry Andric   }
62320b57cec5SDimitry Andric 
62335f757f3fSDimitry Andric   if (Right.isAttribute())
62345f757f3fSDimitry Andric     return true;
62355f757f3fSDimitry Andric 
62365f757f3fSDimitry Andric   if (Right.is(tok::l_square) && Right.is(TT_AttributeSquare))
62375f757f3fSDimitry Andric     return Left.isNot(TT_AttributeSquare);
62380b57cec5SDimitry Andric 
62390b57cec5SDimitry Andric   if (Left.is(tok::identifier) && Right.is(tok::string_literal))
62400b57cec5SDimitry Andric     return true;
62410b57cec5SDimitry Andric 
62420b57cec5SDimitry Andric   if (Right.is(tok::identifier) && Right.Next && Right.Next->is(TT_DictLiteral))
62430b57cec5SDimitry Andric     return true;
62440b57cec5SDimitry Andric 
6245753f127fSDimitry Andric   if (Left.is(TT_CtorInitializerColon)) {
6246753f127fSDimitry Andric     return Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon &&
6247753f127fSDimitry Andric            (!Right.isTrailingComment() || Right.NewlinesBefore > 0);
6248753f127fSDimitry Andric   }
62490b57cec5SDimitry Andric   if (Right.is(TT_CtorInitializerColon))
62500b57cec5SDimitry Andric     return Style.BreakConstructorInitializers != FormatStyle::BCIS_AfterColon;
62510b57cec5SDimitry Andric   if (Left.is(TT_CtorInitializerComma) &&
625281ad6265SDimitry Andric       Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma) {
62530b57cec5SDimitry Andric     return false;
625481ad6265SDimitry Andric   }
62550b57cec5SDimitry Andric   if (Right.is(TT_CtorInitializerComma) &&
625681ad6265SDimitry Andric       Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma) {
62570b57cec5SDimitry Andric     return true;
625881ad6265SDimitry Andric   }
62590b57cec5SDimitry Andric   if (Left.is(TT_InheritanceComma) &&
626081ad6265SDimitry Andric       Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma) {
62610b57cec5SDimitry Andric     return false;
626281ad6265SDimitry Andric   }
62630b57cec5SDimitry Andric   if (Right.is(TT_InheritanceComma) &&
626481ad6265SDimitry Andric       Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma) {
62650b57cec5SDimitry Andric     return true;
626681ad6265SDimitry Andric   }
62670b57cec5SDimitry Andric   if (Left.is(TT_ArrayInitializerLSquare))
62680b57cec5SDimitry Andric     return true;
62690b57cec5SDimitry Andric   if (Right.is(tok::kw_typename) && Left.isNot(tok::kw_const))
62700b57cec5SDimitry Andric     return true;
62710b57cec5SDimitry Andric   if ((Left.isBinaryOperator() || Left.is(TT_BinaryOperator)) &&
62720b57cec5SDimitry Andric       !Left.isOneOf(tok::arrowstar, tok::lessless) &&
62730b57cec5SDimitry Andric       Style.BreakBeforeBinaryOperators != FormatStyle::BOS_All &&
62740b57cec5SDimitry Andric       (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None ||
627581ad6265SDimitry Andric        Left.getPrecedence() == prec::Assignment)) {
62760b57cec5SDimitry Andric     return true;
627781ad6265SDimitry Andric   }
62780b57cec5SDimitry Andric   if ((Left.is(TT_AttributeSquare) && Right.is(tok::l_square)) ||
627981ad6265SDimitry Andric       (Left.is(tok::r_square) && Right.is(TT_AttributeSquare))) {
62800b57cec5SDimitry Andric     return false;
628181ad6265SDimitry Andric   }
62825ffd83dbSDimitry Andric 
62835ffd83dbSDimitry Andric   auto ShortLambdaOption = Style.AllowShortLambdasOnASingleLine;
6284fe6060f1SDimitry Andric   if (Style.BraceWrapping.BeforeLambdaBody && Right.is(TT_LambdaLBrace)) {
62855ffd83dbSDimitry Andric     if (isAllmanLambdaBrace(Left))
62865ffd83dbSDimitry Andric       return !isItAnEmptyLambdaAllowed(Left, ShortLambdaOption);
62875ffd83dbSDimitry Andric     if (isAllmanLambdaBrace(Right))
62885ffd83dbSDimitry Andric       return !isItAnEmptyLambdaAllowed(Right, ShortLambdaOption);
62895ffd83dbSDimitry Andric   }
62905ffd83dbSDimitry Andric 
62915f757f3fSDimitry Andric   if (Right.is(tok::kw_noexcept) && Right.is(TT_TrailingAnnotation)) {
62925f757f3fSDimitry Andric     switch (Style.AllowBreakBeforeNoexceptSpecifier) {
62935f757f3fSDimitry Andric     case FormatStyle::BBNSS_Never:
62945f757f3fSDimitry Andric       return false;
62955f757f3fSDimitry Andric     case FormatStyle::BBNSS_Always:
62965f757f3fSDimitry Andric       return true;
62975f757f3fSDimitry Andric     case FormatStyle::BBNSS_OnlyWithParen:
62985f757f3fSDimitry Andric       return Right.Next && Right.Next->is(tok::l_paren);
62995f757f3fSDimitry Andric     }
63005f757f3fSDimitry Andric   }
63015f757f3fSDimitry Andric 
63020b57cec5SDimitry Andric   return Left.isOneOf(tok::comma, tok::coloncolon, tok::semi, tok::l_brace,
63030b57cec5SDimitry Andric                       tok::kw_class, tok::kw_struct, tok::comment) ||
63040b57cec5SDimitry Andric          Right.isMemberAccess() ||
63056c4b055cSDimitry Andric          Right.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow, tok::lessless,
63066c4b055cSDimitry Andric                        tok::colon, tok::l_square, tok::at) ||
63070b57cec5SDimitry Andric          (Left.is(tok::r_paren) &&
63080b57cec5SDimitry Andric           Right.isOneOf(tok::identifier, tok::kw_const)) ||
63095f757f3fSDimitry Andric          (Left.is(tok::l_paren) && Right.isNot(tok::r_paren)) ||
63105f757f3fSDimitry Andric          (Left.is(TT_TemplateOpener) && Right.isNot(TT_TemplateCloser));
63110b57cec5SDimitry Andric }
63120b57cec5SDimitry Andric 
631381ad6265SDimitry Andric void TokenAnnotator::printDebugInfo(const AnnotatedLine &Line) const {
6314bdd1243dSDimitry Andric   llvm::errs() << "AnnotatedTokens(L=" << Line.Level << ", P=" << Line.PPLevel
6315bdd1243dSDimitry Andric                << ", T=" << Line.Type << ", C=" << Line.IsContinuation
6316bdd1243dSDimitry Andric                << "):\n";
63170b57cec5SDimitry Andric   const FormatToken *Tok = Line.First;
63180b57cec5SDimitry Andric   while (Tok) {
63190b57cec5SDimitry Andric     llvm::errs() << " M=" << Tok->MustBreakBefore
63200b57cec5SDimitry Andric                  << " C=" << Tok->CanBreakBefore
63215ffd83dbSDimitry Andric                  << " T=" << getTokenTypeName(Tok->getType())
63220b57cec5SDimitry Andric                  << " S=" << Tok->SpacesRequiredBefore
63235ffd83dbSDimitry Andric                  << " F=" << Tok->Finalized << " B=" << Tok->BlockParameterCount
6324e8d8bef9SDimitry Andric                  << " BK=" << Tok->getBlockKind() << " P=" << Tok->SplitPenalty
63250b57cec5SDimitry Andric                  << " Name=" << Tok->Tok.getName() << " L=" << Tok->TotalLength
6326e8d8bef9SDimitry Andric                  << " PPK=" << Tok->getPackingKind() << " FakeLParens=";
632781ad6265SDimitry Andric     for (prec::Level LParen : Tok->FakeLParens)
632881ad6265SDimitry Andric       llvm::errs() << LParen << "/";
63290b57cec5SDimitry Andric     llvm::errs() << " FakeRParens=" << Tok->FakeRParens;
63300b57cec5SDimitry Andric     llvm::errs() << " II=" << Tok->Tok.getIdentifierInfo();
63310b57cec5SDimitry Andric     llvm::errs() << " Text='" << Tok->TokenText << "'\n";
63320b57cec5SDimitry Andric     if (!Tok->Next)
63330b57cec5SDimitry Andric       assert(Tok == Line.Last);
63340b57cec5SDimitry Andric     Tok = Tok->Next;
63350b57cec5SDimitry Andric   }
63360b57cec5SDimitry Andric   llvm::errs() << "----\n";
63370b57cec5SDimitry Andric }
63380b57cec5SDimitry Andric 
6339fe6060f1SDimitry Andric FormatStyle::PointerAlignmentStyle
634081ad6265SDimitry Andric TokenAnnotator::getTokenReferenceAlignment(const FormatToken &Reference) const {
6341fe6060f1SDimitry Andric   assert(Reference.isOneOf(tok::amp, tok::ampamp));
6342fe6060f1SDimitry Andric   switch (Style.ReferenceAlignment) {
6343fe6060f1SDimitry Andric   case FormatStyle::RAS_Pointer:
6344fe6060f1SDimitry Andric     return Style.PointerAlignment;
6345fe6060f1SDimitry Andric   case FormatStyle::RAS_Left:
6346fe6060f1SDimitry Andric     return FormatStyle::PAS_Left;
6347fe6060f1SDimitry Andric   case FormatStyle::RAS_Right:
6348fe6060f1SDimitry Andric     return FormatStyle::PAS_Right;
6349fe6060f1SDimitry Andric   case FormatStyle::RAS_Middle:
6350fe6060f1SDimitry Andric     return FormatStyle::PAS_Middle;
6351fe6060f1SDimitry Andric   }
6352fe6060f1SDimitry Andric   assert(0); //"Unhandled value of ReferenceAlignment"
6353fe6060f1SDimitry Andric   return Style.PointerAlignment;
6354fe6060f1SDimitry Andric }
6355fe6060f1SDimitry Andric 
6356fe6060f1SDimitry Andric FormatStyle::PointerAlignmentStyle
6357fe6060f1SDimitry Andric TokenAnnotator::getTokenPointerOrReferenceAlignment(
635881ad6265SDimitry Andric     const FormatToken &PointerOrReference) const {
6359fe6060f1SDimitry Andric   if (PointerOrReference.isOneOf(tok::amp, tok::ampamp)) {
6360fe6060f1SDimitry Andric     switch (Style.ReferenceAlignment) {
6361fe6060f1SDimitry Andric     case FormatStyle::RAS_Pointer:
6362fe6060f1SDimitry Andric       return Style.PointerAlignment;
6363fe6060f1SDimitry Andric     case FormatStyle::RAS_Left:
6364fe6060f1SDimitry Andric       return FormatStyle::PAS_Left;
6365fe6060f1SDimitry Andric     case FormatStyle::RAS_Right:
6366fe6060f1SDimitry Andric       return FormatStyle::PAS_Right;
6367fe6060f1SDimitry Andric     case FormatStyle::RAS_Middle:
6368fe6060f1SDimitry Andric       return FormatStyle::PAS_Middle;
6369fe6060f1SDimitry Andric     }
6370fe6060f1SDimitry Andric   }
6371fe6060f1SDimitry Andric   assert(PointerOrReference.is(tok::star));
6372fe6060f1SDimitry Andric   return Style.PointerAlignment;
6373fe6060f1SDimitry Andric }
6374fe6060f1SDimitry Andric 
63750b57cec5SDimitry Andric } // namespace format
63760b57cec5SDimitry Andric } // namespace clang
6377