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