1f4a2713aSLionel Sambuc //===--- UnwrappedLineParser.cpp - Format C++ code ------------------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc ///
10f4a2713aSLionel Sambuc /// \file
11f4a2713aSLionel Sambuc /// \brief This file contains the implementation of the UnwrappedLineParser,
12f4a2713aSLionel Sambuc /// which turns a stream of tokens into UnwrappedLines.
13f4a2713aSLionel Sambuc ///
14f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
15f4a2713aSLionel Sambuc 
16f4a2713aSLionel Sambuc #include "UnwrappedLineParser.h"
17f4a2713aSLionel Sambuc #include "llvm/Support/Debug.h"
18f4a2713aSLionel Sambuc 
19*0a6a1f1dSLionel Sambuc #define DEBUG_TYPE "format-parser"
20*0a6a1f1dSLionel Sambuc 
21f4a2713aSLionel Sambuc namespace clang {
22f4a2713aSLionel Sambuc namespace format {
23f4a2713aSLionel Sambuc 
24f4a2713aSLionel Sambuc class FormatTokenSource {
25f4a2713aSLionel Sambuc public:
~FormatTokenSource()26f4a2713aSLionel Sambuc   virtual ~FormatTokenSource() {}
27f4a2713aSLionel Sambuc   virtual FormatToken *getNextToken() = 0;
28f4a2713aSLionel Sambuc 
29f4a2713aSLionel Sambuc   virtual unsigned getPosition() = 0;
30f4a2713aSLionel Sambuc   virtual FormatToken *setPosition(unsigned Position) = 0;
31f4a2713aSLionel Sambuc };
32f4a2713aSLionel Sambuc 
33f4a2713aSLionel Sambuc namespace {
34f4a2713aSLionel Sambuc 
35f4a2713aSLionel Sambuc class ScopedDeclarationState {
36f4a2713aSLionel Sambuc public:
ScopedDeclarationState(UnwrappedLine & Line,std::vector<bool> & Stack,bool MustBeDeclaration)37f4a2713aSLionel Sambuc   ScopedDeclarationState(UnwrappedLine &Line, std::vector<bool> &Stack,
38f4a2713aSLionel Sambuc                          bool MustBeDeclaration)
39f4a2713aSLionel Sambuc       : Line(Line), Stack(Stack) {
40f4a2713aSLionel Sambuc     Line.MustBeDeclaration = MustBeDeclaration;
41f4a2713aSLionel Sambuc     Stack.push_back(MustBeDeclaration);
42f4a2713aSLionel Sambuc   }
~ScopedDeclarationState()43f4a2713aSLionel Sambuc   ~ScopedDeclarationState() {
44f4a2713aSLionel Sambuc     Stack.pop_back();
45f4a2713aSLionel Sambuc     if (!Stack.empty())
46f4a2713aSLionel Sambuc       Line.MustBeDeclaration = Stack.back();
47f4a2713aSLionel Sambuc     else
48f4a2713aSLionel Sambuc       Line.MustBeDeclaration = true;
49f4a2713aSLionel Sambuc   }
50f4a2713aSLionel Sambuc 
51f4a2713aSLionel Sambuc private:
52f4a2713aSLionel Sambuc   UnwrappedLine &Line;
53f4a2713aSLionel Sambuc   std::vector<bool> &Stack;
54f4a2713aSLionel Sambuc };
55f4a2713aSLionel Sambuc 
56f4a2713aSLionel Sambuc class ScopedMacroState : public FormatTokenSource {
57f4a2713aSLionel Sambuc public:
ScopedMacroState(UnwrappedLine & Line,FormatTokenSource * & TokenSource,FormatToken * & ResetToken,bool & StructuralError)58f4a2713aSLionel Sambuc   ScopedMacroState(UnwrappedLine &Line, FormatTokenSource *&TokenSource,
59f4a2713aSLionel Sambuc                    FormatToken *&ResetToken, bool &StructuralError)
60f4a2713aSLionel Sambuc       : Line(Line), TokenSource(TokenSource), ResetToken(ResetToken),
61f4a2713aSLionel Sambuc         PreviousLineLevel(Line.Level), PreviousTokenSource(TokenSource),
62f4a2713aSLionel Sambuc         StructuralError(StructuralError),
63*0a6a1f1dSLionel Sambuc         PreviousStructuralError(StructuralError), Token(nullptr) {
64f4a2713aSLionel Sambuc     TokenSource = this;
65f4a2713aSLionel Sambuc     Line.Level = 0;
66f4a2713aSLionel Sambuc     Line.InPPDirective = true;
67f4a2713aSLionel Sambuc   }
68f4a2713aSLionel Sambuc 
~ScopedMacroState()69f4a2713aSLionel Sambuc   ~ScopedMacroState() {
70f4a2713aSLionel Sambuc     TokenSource = PreviousTokenSource;
71f4a2713aSLionel Sambuc     ResetToken = Token;
72f4a2713aSLionel Sambuc     Line.InPPDirective = false;
73f4a2713aSLionel Sambuc     Line.Level = PreviousLineLevel;
74f4a2713aSLionel Sambuc     StructuralError = PreviousStructuralError;
75f4a2713aSLionel Sambuc   }
76f4a2713aSLionel Sambuc 
getNextToken()77*0a6a1f1dSLionel Sambuc   FormatToken *getNextToken() override {
78f4a2713aSLionel Sambuc     // The \c UnwrappedLineParser guards against this by never calling
79f4a2713aSLionel Sambuc     // \c getNextToken() after it has encountered the first eof token.
80f4a2713aSLionel Sambuc     assert(!eof());
81f4a2713aSLionel Sambuc     Token = PreviousTokenSource->getNextToken();
82f4a2713aSLionel Sambuc     if (eof())
83f4a2713aSLionel Sambuc       return getFakeEOF();
84f4a2713aSLionel Sambuc     return Token;
85f4a2713aSLionel Sambuc   }
86f4a2713aSLionel Sambuc 
getPosition()87*0a6a1f1dSLionel Sambuc   unsigned getPosition() override { return PreviousTokenSource->getPosition(); }
88f4a2713aSLionel Sambuc 
setPosition(unsigned Position)89*0a6a1f1dSLionel Sambuc   FormatToken *setPosition(unsigned Position) override {
90f4a2713aSLionel Sambuc     Token = PreviousTokenSource->setPosition(Position);
91f4a2713aSLionel Sambuc     return Token;
92f4a2713aSLionel Sambuc   }
93f4a2713aSLionel Sambuc 
94f4a2713aSLionel Sambuc private:
eof()95f4a2713aSLionel Sambuc   bool eof() { return Token && Token->HasUnescapedNewline; }
96f4a2713aSLionel Sambuc 
getFakeEOF()97f4a2713aSLionel Sambuc   FormatToken *getFakeEOF() {
98f4a2713aSLionel Sambuc     static bool EOFInitialized = false;
99f4a2713aSLionel Sambuc     static FormatToken FormatTok;
100f4a2713aSLionel Sambuc     if (!EOFInitialized) {
101f4a2713aSLionel Sambuc       FormatTok.Tok.startToken();
102f4a2713aSLionel Sambuc       FormatTok.Tok.setKind(tok::eof);
103f4a2713aSLionel Sambuc       EOFInitialized = true;
104f4a2713aSLionel Sambuc     }
105f4a2713aSLionel Sambuc     return &FormatTok;
106f4a2713aSLionel Sambuc   }
107f4a2713aSLionel Sambuc 
108f4a2713aSLionel Sambuc   UnwrappedLine &Line;
109f4a2713aSLionel Sambuc   FormatTokenSource *&TokenSource;
110f4a2713aSLionel Sambuc   FormatToken *&ResetToken;
111f4a2713aSLionel Sambuc   unsigned PreviousLineLevel;
112f4a2713aSLionel Sambuc   FormatTokenSource *PreviousTokenSource;
113f4a2713aSLionel Sambuc   bool &StructuralError;
114f4a2713aSLionel Sambuc   bool PreviousStructuralError;
115f4a2713aSLionel Sambuc 
116f4a2713aSLionel Sambuc   FormatToken *Token;
117f4a2713aSLionel Sambuc };
118f4a2713aSLionel Sambuc 
119f4a2713aSLionel Sambuc } // end anonymous namespace
120f4a2713aSLionel Sambuc 
121f4a2713aSLionel Sambuc class ScopedLineState {
122f4a2713aSLionel Sambuc public:
ScopedLineState(UnwrappedLineParser & Parser,bool SwitchToPreprocessorLines=false)123f4a2713aSLionel Sambuc   ScopedLineState(UnwrappedLineParser &Parser,
124f4a2713aSLionel Sambuc                   bool SwitchToPreprocessorLines = false)
125*0a6a1f1dSLionel Sambuc       : Parser(Parser), OriginalLines(Parser.CurrentLines) {
126f4a2713aSLionel Sambuc     if (SwitchToPreprocessorLines)
127f4a2713aSLionel Sambuc       Parser.CurrentLines = &Parser.PreprocessorDirectives;
128f4a2713aSLionel Sambuc     else if (!Parser.Line->Tokens.empty())
129f4a2713aSLionel Sambuc       Parser.CurrentLines = &Parser.Line->Tokens.back().Children;
130*0a6a1f1dSLionel Sambuc     PreBlockLine = std::move(Parser.Line);
131*0a6a1f1dSLionel Sambuc     Parser.Line = llvm::make_unique<UnwrappedLine>();
132f4a2713aSLionel Sambuc     Parser.Line->Level = PreBlockLine->Level;
133f4a2713aSLionel Sambuc     Parser.Line->InPPDirective = PreBlockLine->InPPDirective;
134f4a2713aSLionel Sambuc   }
135f4a2713aSLionel Sambuc 
~ScopedLineState()136f4a2713aSLionel Sambuc   ~ScopedLineState() {
137f4a2713aSLionel Sambuc     if (!Parser.Line->Tokens.empty()) {
138f4a2713aSLionel Sambuc       Parser.addUnwrappedLine();
139f4a2713aSLionel Sambuc     }
140f4a2713aSLionel Sambuc     assert(Parser.Line->Tokens.empty());
141*0a6a1f1dSLionel Sambuc     Parser.Line = std::move(PreBlockLine);
142f4a2713aSLionel Sambuc     if (Parser.CurrentLines == &Parser.PreprocessorDirectives)
143f4a2713aSLionel Sambuc       Parser.MustBreakBeforeNextToken = true;
144f4a2713aSLionel Sambuc     Parser.CurrentLines = OriginalLines;
145f4a2713aSLionel Sambuc   }
146f4a2713aSLionel Sambuc 
147f4a2713aSLionel Sambuc private:
148f4a2713aSLionel Sambuc   UnwrappedLineParser &Parser;
149f4a2713aSLionel Sambuc 
150*0a6a1f1dSLionel Sambuc   std::unique_ptr<UnwrappedLine> PreBlockLine;
151f4a2713aSLionel Sambuc   SmallVectorImpl<UnwrappedLine> *OriginalLines;
152f4a2713aSLionel Sambuc };
153f4a2713aSLionel Sambuc 
154*0a6a1f1dSLionel Sambuc class CompoundStatementIndenter {
155*0a6a1f1dSLionel Sambuc public:
CompoundStatementIndenter(UnwrappedLineParser * Parser,const FormatStyle & Style,unsigned & LineLevel)156*0a6a1f1dSLionel Sambuc   CompoundStatementIndenter(UnwrappedLineParser *Parser,
157*0a6a1f1dSLionel Sambuc                             const FormatStyle &Style, unsigned &LineLevel)
158*0a6a1f1dSLionel Sambuc       : LineLevel(LineLevel), OldLineLevel(LineLevel) {
159*0a6a1f1dSLionel Sambuc     if (Style.BreakBeforeBraces == FormatStyle::BS_Allman) {
160*0a6a1f1dSLionel Sambuc       Parser->addUnwrappedLine();
161*0a6a1f1dSLionel Sambuc     } else if (Style.BreakBeforeBraces == FormatStyle::BS_GNU) {
162*0a6a1f1dSLionel Sambuc       Parser->addUnwrappedLine();
163*0a6a1f1dSLionel Sambuc       ++LineLevel;
164*0a6a1f1dSLionel Sambuc     }
165*0a6a1f1dSLionel Sambuc   }
~CompoundStatementIndenter()166*0a6a1f1dSLionel Sambuc   ~CompoundStatementIndenter() { LineLevel = OldLineLevel; }
167*0a6a1f1dSLionel Sambuc 
168*0a6a1f1dSLionel Sambuc private:
169*0a6a1f1dSLionel Sambuc   unsigned &LineLevel;
170*0a6a1f1dSLionel Sambuc   unsigned OldLineLevel;
171*0a6a1f1dSLionel Sambuc };
172*0a6a1f1dSLionel Sambuc 
173f4a2713aSLionel Sambuc namespace {
174f4a2713aSLionel Sambuc 
175f4a2713aSLionel Sambuc class IndexedTokenSource : public FormatTokenSource {
176f4a2713aSLionel Sambuc public:
IndexedTokenSource(ArrayRef<FormatToken * > Tokens)177f4a2713aSLionel Sambuc   IndexedTokenSource(ArrayRef<FormatToken *> Tokens)
178f4a2713aSLionel Sambuc       : Tokens(Tokens), Position(-1) {}
179f4a2713aSLionel Sambuc 
getNextToken()180*0a6a1f1dSLionel Sambuc   FormatToken *getNextToken() override {
181f4a2713aSLionel Sambuc     ++Position;
182f4a2713aSLionel Sambuc     return Tokens[Position];
183f4a2713aSLionel Sambuc   }
184f4a2713aSLionel Sambuc 
getPosition()185*0a6a1f1dSLionel Sambuc   unsigned getPosition() override {
186f4a2713aSLionel Sambuc     assert(Position >= 0);
187f4a2713aSLionel Sambuc     return Position;
188f4a2713aSLionel Sambuc   }
189f4a2713aSLionel Sambuc 
setPosition(unsigned P)190*0a6a1f1dSLionel Sambuc   FormatToken *setPosition(unsigned P) override {
191f4a2713aSLionel Sambuc     Position = P;
192f4a2713aSLionel Sambuc     return Tokens[Position];
193f4a2713aSLionel Sambuc   }
194f4a2713aSLionel Sambuc 
reset()195f4a2713aSLionel Sambuc   void reset() { Position = -1; }
196f4a2713aSLionel Sambuc 
197f4a2713aSLionel Sambuc private:
198f4a2713aSLionel Sambuc   ArrayRef<FormatToken *> Tokens;
199f4a2713aSLionel Sambuc   int Position;
200f4a2713aSLionel Sambuc };
201f4a2713aSLionel Sambuc 
202f4a2713aSLionel Sambuc } // end anonymous namespace
203f4a2713aSLionel Sambuc 
UnwrappedLineParser(const FormatStyle & Style,const AdditionalKeywords & Keywords,ArrayRef<FormatToken * > Tokens,UnwrappedLineConsumer & Callback)204f4a2713aSLionel Sambuc UnwrappedLineParser::UnwrappedLineParser(const FormatStyle &Style,
205*0a6a1f1dSLionel Sambuc                                          const AdditionalKeywords &Keywords,
206f4a2713aSLionel Sambuc                                          ArrayRef<FormatToken *> Tokens,
207f4a2713aSLionel Sambuc                                          UnwrappedLineConsumer &Callback)
208f4a2713aSLionel Sambuc     : Line(new UnwrappedLine), MustBreakBeforeNextToken(false),
209*0a6a1f1dSLionel Sambuc       CurrentLines(&Lines), StructuralError(false), Style(Style),
210*0a6a1f1dSLionel Sambuc       Keywords(Keywords), Tokens(nullptr), Callback(Callback),
211*0a6a1f1dSLionel Sambuc       AllTokens(Tokens), PPBranchLevel(-1) {}
212f4a2713aSLionel Sambuc 
reset()213f4a2713aSLionel Sambuc void UnwrappedLineParser::reset() {
214f4a2713aSLionel Sambuc   PPBranchLevel = -1;
215f4a2713aSLionel Sambuc   Line.reset(new UnwrappedLine);
216f4a2713aSLionel Sambuc   CommentsBeforeNextToken.clear();
217*0a6a1f1dSLionel Sambuc   FormatTok = nullptr;
218f4a2713aSLionel Sambuc   MustBreakBeforeNextToken = false;
219f4a2713aSLionel Sambuc   PreprocessorDirectives.clear();
220f4a2713aSLionel Sambuc   CurrentLines = &Lines;
221f4a2713aSLionel Sambuc   DeclarationScopeStack.clear();
222f4a2713aSLionel Sambuc   StructuralError = false;
223f4a2713aSLionel Sambuc   PPStack.clear();
224f4a2713aSLionel Sambuc }
225f4a2713aSLionel Sambuc 
parse()226f4a2713aSLionel Sambuc bool UnwrappedLineParser::parse() {
227f4a2713aSLionel Sambuc   IndexedTokenSource TokenSource(AllTokens);
228f4a2713aSLionel Sambuc   do {
229f4a2713aSLionel Sambuc     DEBUG(llvm::dbgs() << "----\n");
230f4a2713aSLionel Sambuc     reset();
231f4a2713aSLionel Sambuc     Tokens = &TokenSource;
232f4a2713aSLionel Sambuc     TokenSource.reset();
233f4a2713aSLionel Sambuc 
234f4a2713aSLionel Sambuc     readToken();
235f4a2713aSLionel Sambuc     parseFile();
236f4a2713aSLionel Sambuc     // Create line with eof token.
237f4a2713aSLionel Sambuc     pushToken(FormatTok);
238f4a2713aSLionel Sambuc     addUnwrappedLine();
239f4a2713aSLionel Sambuc 
240f4a2713aSLionel Sambuc     for (SmallVectorImpl<UnwrappedLine>::iterator I = Lines.begin(),
241f4a2713aSLionel Sambuc                                                   E = Lines.end();
242f4a2713aSLionel Sambuc          I != E; ++I) {
243f4a2713aSLionel Sambuc       Callback.consumeUnwrappedLine(*I);
244f4a2713aSLionel Sambuc     }
245f4a2713aSLionel Sambuc     Callback.finishRun();
246f4a2713aSLionel Sambuc     Lines.clear();
247f4a2713aSLionel Sambuc     while (!PPLevelBranchIndex.empty() &&
248f4a2713aSLionel Sambuc            PPLevelBranchIndex.back() + 1 >= PPLevelBranchCount.back()) {
249f4a2713aSLionel Sambuc       PPLevelBranchIndex.resize(PPLevelBranchIndex.size() - 1);
250f4a2713aSLionel Sambuc       PPLevelBranchCount.resize(PPLevelBranchCount.size() - 1);
251f4a2713aSLionel Sambuc     }
252f4a2713aSLionel Sambuc     if (!PPLevelBranchIndex.empty()) {
253f4a2713aSLionel Sambuc       ++PPLevelBranchIndex.back();
254f4a2713aSLionel Sambuc       assert(PPLevelBranchIndex.size() == PPLevelBranchCount.size());
255f4a2713aSLionel Sambuc       assert(PPLevelBranchIndex.back() <= PPLevelBranchCount.back());
256f4a2713aSLionel Sambuc     }
257f4a2713aSLionel Sambuc   } while (!PPLevelBranchIndex.empty());
258f4a2713aSLionel Sambuc 
259f4a2713aSLionel Sambuc   return StructuralError;
260f4a2713aSLionel Sambuc }
261f4a2713aSLionel Sambuc 
parseFile()262f4a2713aSLionel Sambuc void UnwrappedLineParser::parseFile() {
263f4a2713aSLionel Sambuc   ScopedDeclarationState DeclarationState(
264f4a2713aSLionel Sambuc       *Line, DeclarationScopeStack,
265f4a2713aSLionel Sambuc       /*MustBeDeclaration=*/ !Line->InPPDirective);
266f4a2713aSLionel Sambuc   parseLevel(/*HasOpeningBrace=*/false);
267f4a2713aSLionel Sambuc   // Make sure to format the remaining tokens.
268f4a2713aSLionel Sambuc   flushComments(true);
269f4a2713aSLionel Sambuc   addUnwrappedLine();
270f4a2713aSLionel Sambuc }
271f4a2713aSLionel Sambuc 
parseLevel(bool HasOpeningBrace)272f4a2713aSLionel Sambuc void UnwrappedLineParser::parseLevel(bool HasOpeningBrace) {
273f4a2713aSLionel Sambuc   bool SwitchLabelEncountered = false;
274f4a2713aSLionel Sambuc   do {
275f4a2713aSLionel Sambuc     switch (FormatTok->Tok.getKind()) {
276f4a2713aSLionel Sambuc     case tok::comment:
277f4a2713aSLionel Sambuc       nextToken();
278f4a2713aSLionel Sambuc       addUnwrappedLine();
279f4a2713aSLionel Sambuc       break;
280f4a2713aSLionel Sambuc     case tok::l_brace:
281f4a2713aSLionel Sambuc       // FIXME: Add parameter whether this can happen - if this happens, we must
282f4a2713aSLionel Sambuc       // be in a non-declaration context.
283f4a2713aSLionel Sambuc       parseBlock(/*MustBeDeclaration=*/false);
284f4a2713aSLionel Sambuc       addUnwrappedLine();
285f4a2713aSLionel Sambuc       break;
286f4a2713aSLionel Sambuc     case tok::r_brace:
287f4a2713aSLionel Sambuc       if (HasOpeningBrace)
288f4a2713aSLionel Sambuc         return;
289f4a2713aSLionel Sambuc       StructuralError = true;
290f4a2713aSLionel Sambuc       nextToken();
291f4a2713aSLionel Sambuc       addUnwrappedLine();
292f4a2713aSLionel Sambuc       break;
293f4a2713aSLionel Sambuc     case tok::kw_default:
294f4a2713aSLionel Sambuc     case tok::kw_case:
295f4a2713aSLionel Sambuc       if (!SwitchLabelEncountered &&
296f4a2713aSLionel Sambuc           (Style.IndentCaseLabels || (Line->InPPDirective && Line->Level == 1)))
297f4a2713aSLionel Sambuc         ++Line->Level;
298f4a2713aSLionel Sambuc       SwitchLabelEncountered = true;
299f4a2713aSLionel Sambuc       parseStructuralElement();
300f4a2713aSLionel Sambuc       break;
301f4a2713aSLionel Sambuc     default:
302f4a2713aSLionel Sambuc       parseStructuralElement();
303f4a2713aSLionel Sambuc       break;
304f4a2713aSLionel Sambuc     }
305f4a2713aSLionel Sambuc   } while (!eof());
306f4a2713aSLionel Sambuc }
307f4a2713aSLionel Sambuc 
calculateBraceTypes()308f4a2713aSLionel Sambuc void UnwrappedLineParser::calculateBraceTypes() {
309f4a2713aSLionel Sambuc   // We'll parse forward through the tokens until we hit
310f4a2713aSLionel Sambuc   // a closing brace or eof - note that getNextToken() will
311f4a2713aSLionel Sambuc   // parse macros, so this will magically work inside macro
312f4a2713aSLionel Sambuc   // definitions, too.
313f4a2713aSLionel Sambuc   unsigned StoredPosition = Tokens->getPosition();
314f4a2713aSLionel Sambuc   FormatToken *Tok = FormatTok;
315f4a2713aSLionel Sambuc   // Keep a stack of positions of lbrace tokens. We will
316f4a2713aSLionel Sambuc   // update information about whether an lbrace starts a
317f4a2713aSLionel Sambuc   // braced init list or a different block during the loop.
318f4a2713aSLionel Sambuc   SmallVector<FormatToken *, 8> LBraceStack;
319f4a2713aSLionel Sambuc   assert(Tok->Tok.is(tok::l_brace));
320f4a2713aSLionel Sambuc   do {
321f4a2713aSLionel Sambuc     // Get next none-comment token.
322f4a2713aSLionel Sambuc     FormatToken *NextTok;
323f4a2713aSLionel Sambuc     unsigned ReadTokens = 0;
324f4a2713aSLionel Sambuc     do {
325f4a2713aSLionel Sambuc       NextTok = Tokens->getNextToken();
326f4a2713aSLionel Sambuc       ++ReadTokens;
327f4a2713aSLionel Sambuc     } while (NextTok->is(tok::comment));
328f4a2713aSLionel Sambuc 
329f4a2713aSLionel Sambuc     switch (Tok->Tok.getKind()) {
330f4a2713aSLionel Sambuc     case tok::l_brace:
331f4a2713aSLionel Sambuc       LBraceStack.push_back(Tok);
332f4a2713aSLionel Sambuc       break;
333f4a2713aSLionel Sambuc     case tok::r_brace:
334f4a2713aSLionel Sambuc       if (!LBraceStack.empty()) {
335f4a2713aSLionel Sambuc         if (LBraceStack.back()->BlockKind == BK_Unknown) {
336*0a6a1f1dSLionel Sambuc           bool ProbablyBracedList = false;
337*0a6a1f1dSLionel Sambuc           if (Style.Language == FormatStyle::LK_Proto) {
338*0a6a1f1dSLionel Sambuc             ProbablyBracedList = NextTok->isOneOf(tok::comma, tok::r_square);
339*0a6a1f1dSLionel Sambuc           } else {
340*0a6a1f1dSLionel Sambuc             // Using OriginalColumn to distinguish between ObjC methods and
341*0a6a1f1dSLionel Sambuc             // binary operators is a bit hacky.
342*0a6a1f1dSLionel Sambuc             bool NextIsObjCMethod = NextTok->isOneOf(tok::plus, tok::minus) &&
343*0a6a1f1dSLionel Sambuc                                     NextTok->OriginalColumn == 0;
344*0a6a1f1dSLionel Sambuc 
345f4a2713aSLionel Sambuc             // If there is a comma, semicolon or right paren after the closing
346f4a2713aSLionel Sambuc             // brace, we assume this is a braced initializer list.  Note that
347f4a2713aSLionel Sambuc             // regardless how we mark inner braces here, we will overwrite the
348*0a6a1f1dSLionel Sambuc             // BlockKind later if we parse a braced list (where all blocks
349*0a6a1f1dSLionel Sambuc             // inside are by default braced lists), or when we explicitly detect
350*0a6a1f1dSLionel Sambuc             // blocks (for example while parsing lambdas).
351f4a2713aSLionel Sambuc             //
352f4a2713aSLionel Sambuc             // We exclude + and - as they can be ObjC visibility modifiers.
353*0a6a1f1dSLionel Sambuc             ProbablyBracedList =
354*0a6a1f1dSLionel Sambuc                 NextTok->isOneOf(tok::comma, tok::semi, tok::period, tok::colon,
355*0a6a1f1dSLionel Sambuc                                  tok::r_paren, tok::r_square, tok::l_brace,
356*0a6a1f1dSLionel Sambuc                                  tok::l_paren, tok::ellipsis) ||
357*0a6a1f1dSLionel Sambuc                 (NextTok->isBinaryOperator() && !NextIsObjCMethod);
358*0a6a1f1dSLionel Sambuc           }
359*0a6a1f1dSLionel Sambuc           if (ProbablyBracedList) {
360f4a2713aSLionel Sambuc             Tok->BlockKind = BK_BracedInit;
361f4a2713aSLionel Sambuc             LBraceStack.back()->BlockKind = BK_BracedInit;
362f4a2713aSLionel Sambuc           } else {
363f4a2713aSLionel Sambuc             Tok->BlockKind = BK_Block;
364f4a2713aSLionel Sambuc             LBraceStack.back()->BlockKind = BK_Block;
365f4a2713aSLionel Sambuc           }
366f4a2713aSLionel Sambuc         }
367f4a2713aSLionel Sambuc         LBraceStack.pop_back();
368f4a2713aSLionel Sambuc       }
369f4a2713aSLionel Sambuc       break;
370*0a6a1f1dSLionel Sambuc     case tok::at:
371f4a2713aSLionel Sambuc     case tok::semi:
372f4a2713aSLionel Sambuc     case tok::kw_if:
373f4a2713aSLionel Sambuc     case tok::kw_while:
374f4a2713aSLionel Sambuc     case tok::kw_for:
375f4a2713aSLionel Sambuc     case tok::kw_switch:
376f4a2713aSLionel Sambuc     case tok::kw_try:
377f4a2713aSLionel Sambuc       if (!LBraceStack.empty())
378f4a2713aSLionel Sambuc         LBraceStack.back()->BlockKind = BK_Block;
379f4a2713aSLionel Sambuc       break;
380f4a2713aSLionel Sambuc     default:
381f4a2713aSLionel Sambuc       break;
382f4a2713aSLionel Sambuc     }
383f4a2713aSLionel Sambuc     Tok = NextTok;
384f4a2713aSLionel Sambuc   } while (Tok->Tok.isNot(tok::eof) && !LBraceStack.empty());
385f4a2713aSLionel Sambuc   // Assume other blocks for all unclosed opening braces.
386f4a2713aSLionel Sambuc   for (unsigned i = 0, e = LBraceStack.size(); i != e; ++i) {
387f4a2713aSLionel Sambuc     if (LBraceStack[i]->BlockKind == BK_Unknown)
388f4a2713aSLionel Sambuc       LBraceStack[i]->BlockKind = BK_Block;
389f4a2713aSLionel Sambuc   }
390f4a2713aSLionel Sambuc 
391f4a2713aSLionel Sambuc   FormatTok = Tokens->setPosition(StoredPosition);
392f4a2713aSLionel Sambuc }
393f4a2713aSLionel Sambuc 
parseBlock(bool MustBeDeclaration,bool AddLevel,bool MunchSemi)394f4a2713aSLionel Sambuc void UnwrappedLineParser::parseBlock(bool MustBeDeclaration, bool AddLevel,
395f4a2713aSLionel Sambuc                                      bool MunchSemi) {
396f4a2713aSLionel Sambuc   assert(FormatTok->Tok.is(tok::l_brace) && "'{' expected");
397f4a2713aSLionel Sambuc   unsigned InitialLevel = Line->Level;
398f4a2713aSLionel Sambuc   nextToken();
399f4a2713aSLionel Sambuc 
400f4a2713aSLionel Sambuc   addUnwrappedLine();
401f4a2713aSLionel Sambuc 
402f4a2713aSLionel Sambuc   ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
403f4a2713aSLionel Sambuc                                           MustBeDeclaration);
404f4a2713aSLionel Sambuc   if (AddLevel)
405f4a2713aSLionel Sambuc     ++Line->Level;
406f4a2713aSLionel Sambuc   parseLevel(/*HasOpeningBrace=*/true);
407f4a2713aSLionel Sambuc 
408f4a2713aSLionel Sambuc   if (!FormatTok->Tok.is(tok::r_brace)) {
409f4a2713aSLionel Sambuc     Line->Level = InitialLevel;
410f4a2713aSLionel Sambuc     StructuralError = true;
411f4a2713aSLionel Sambuc     return;
412f4a2713aSLionel Sambuc   }
413f4a2713aSLionel Sambuc 
414f4a2713aSLionel Sambuc   nextToken(); // Munch the closing brace.
415f4a2713aSLionel Sambuc   if (MunchSemi && FormatTok->Tok.is(tok::semi))
416f4a2713aSLionel Sambuc     nextToken();
417f4a2713aSLionel Sambuc   Line->Level = InitialLevel;
418f4a2713aSLionel Sambuc }
419f4a2713aSLionel Sambuc 
IsGoogScope(const UnwrappedLine & Line)420*0a6a1f1dSLionel Sambuc static bool IsGoogScope(const UnwrappedLine &Line) {
421*0a6a1f1dSLionel Sambuc   // FIXME: Closure-library specific stuff should not be hard-coded but be
422*0a6a1f1dSLionel Sambuc   // configurable.
423*0a6a1f1dSLionel Sambuc   if (Line.Tokens.size() < 4)
424*0a6a1f1dSLionel Sambuc     return false;
425*0a6a1f1dSLionel Sambuc   auto I = Line.Tokens.begin();
426*0a6a1f1dSLionel Sambuc   if (I->Tok->TokenText != "goog")
427*0a6a1f1dSLionel Sambuc     return false;
428*0a6a1f1dSLionel Sambuc   ++I;
429*0a6a1f1dSLionel Sambuc   if (I->Tok->isNot(tok::period))
430*0a6a1f1dSLionel Sambuc     return false;
431*0a6a1f1dSLionel Sambuc   ++I;
432*0a6a1f1dSLionel Sambuc   if (I->Tok->TokenText != "scope")
433*0a6a1f1dSLionel Sambuc     return false;
434*0a6a1f1dSLionel Sambuc   ++I;
435*0a6a1f1dSLionel Sambuc   return I->Tok->is(tok::l_paren);
436*0a6a1f1dSLionel Sambuc }
437*0a6a1f1dSLionel Sambuc 
ShouldBreakBeforeBrace(const FormatStyle & Style,const FormatToken & InitialToken)438*0a6a1f1dSLionel Sambuc static bool ShouldBreakBeforeBrace(const FormatStyle &Style,
439*0a6a1f1dSLionel Sambuc                                    const FormatToken &InitialToken) {
440*0a6a1f1dSLionel Sambuc   switch (Style.BreakBeforeBraces) {
441*0a6a1f1dSLionel Sambuc   case FormatStyle::BS_Linux:
442*0a6a1f1dSLionel Sambuc     return InitialToken.isOneOf(tok::kw_namespace, tok::kw_class);
443*0a6a1f1dSLionel Sambuc   case FormatStyle::BS_Allman:
444*0a6a1f1dSLionel Sambuc   case FormatStyle::BS_GNU:
445*0a6a1f1dSLionel Sambuc     return true;
446*0a6a1f1dSLionel Sambuc   default:
447*0a6a1f1dSLionel Sambuc     return false;
448*0a6a1f1dSLionel Sambuc   }
449*0a6a1f1dSLionel Sambuc }
450*0a6a1f1dSLionel Sambuc 
parseChildBlock()451f4a2713aSLionel Sambuc void UnwrappedLineParser::parseChildBlock() {
452f4a2713aSLionel Sambuc   FormatTok->BlockKind = BK_Block;
453f4a2713aSLionel Sambuc   nextToken();
454f4a2713aSLionel Sambuc   {
455*0a6a1f1dSLionel Sambuc     bool GoogScope =
456*0a6a1f1dSLionel Sambuc         Style.Language == FormatStyle::LK_JavaScript && IsGoogScope(*Line);
457f4a2713aSLionel Sambuc     ScopedLineState LineState(*this);
458f4a2713aSLionel Sambuc     ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
459f4a2713aSLionel Sambuc                                             /*MustBeDeclaration=*/false);
460*0a6a1f1dSLionel Sambuc     Line->Level += GoogScope ? 0 : 1;
461f4a2713aSLionel Sambuc     parseLevel(/*HasOpeningBrace=*/true);
462*0a6a1f1dSLionel Sambuc     Line->Level -= GoogScope ? 0 : 1;
463f4a2713aSLionel Sambuc   }
464f4a2713aSLionel Sambuc   nextToken();
465f4a2713aSLionel Sambuc }
466f4a2713aSLionel Sambuc 
parsePPDirective()467f4a2713aSLionel Sambuc void UnwrappedLineParser::parsePPDirective() {
468f4a2713aSLionel Sambuc   assert(FormatTok->Tok.is(tok::hash) && "'#' expected");
469f4a2713aSLionel Sambuc   ScopedMacroState MacroState(*Line, Tokens, FormatTok, StructuralError);
470f4a2713aSLionel Sambuc   nextToken();
471f4a2713aSLionel Sambuc 
472*0a6a1f1dSLionel Sambuc   if (!FormatTok->Tok.getIdentifierInfo()) {
473f4a2713aSLionel Sambuc     parsePPUnknown();
474f4a2713aSLionel Sambuc     return;
475f4a2713aSLionel Sambuc   }
476f4a2713aSLionel Sambuc 
477f4a2713aSLionel Sambuc   switch (FormatTok->Tok.getIdentifierInfo()->getPPKeywordID()) {
478f4a2713aSLionel Sambuc   case tok::pp_define:
479f4a2713aSLionel Sambuc     parsePPDefine();
480f4a2713aSLionel Sambuc     return;
481f4a2713aSLionel Sambuc   case tok::pp_if:
482f4a2713aSLionel Sambuc     parsePPIf(/*IfDef=*/false);
483f4a2713aSLionel Sambuc     break;
484f4a2713aSLionel Sambuc   case tok::pp_ifdef:
485f4a2713aSLionel Sambuc   case tok::pp_ifndef:
486f4a2713aSLionel Sambuc     parsePPIf(/*IfDef=*/true);
487f4a2713aSLionel Sambuc     break;
488f4a2713aSLionel Sambuc   case tok::pp_else:
489f4a2713aSLionel Sambuc     parsePPElse();
490f4a2713aSLionel Sambuc     break;
491f4a2713aSLionel Sambuc   case tok::pp_elif:
492f4a2713aSLionel Sambuc     parsePPElIf();
493f4a2713aSLionel Sambuc     break;
494f4a2713aSLionel Sambuc   case tok::pp_endif:
495f4a2713aSLionel Sambuc     parsePPEndIf();
496f4a2713aSLionel Sambuc     break;
497f4a2713aSLionel Sambuc   default:
498f4a2713aSLionel Sambuc     parsePPUnknown();
499f4a2713aSLionel Sambuc     break;
500f4a2713aSLionel Sambuc   }
501f4a2713aSLionel Sambuc }
502f4a2713aSLionel Sambuc 
conditionalCompilationCondition(bool Unreachable)503*0a6a1f1dSLionel Sambuc void UnwrappedLineParser::conditionalCompilationCondition(bool Unreachable) {
504*0a6a1f1dSLionel Sambuc   if (Unreachable || (!PPStack.empty() && PPStack.back() == PP_Unreachable))
505f4a2713aSLionel Sambuc     PPStack.push_back(PP_Unreachable);
506f4a2713aSLionel Sambuc   else
507f4a2713aSLionel Sambuc     PPStack.push_back(PP_Conditional);
508f4a2713aSLionel Sambuc }
509f4a2713aSLionel Sambuc 
conditionalCompilationStart(bool Unreachable)510*0a6a1f1dSLionel Sambuc void UnwrappedLineParser::conditionalCompilationStart(bool Unreachable) {
511f4a2713aSLionel Sambuc   ++PPBranchLevel;
512f4a2713aSLionel Sambuc   assert(PPBranchLevel >= 0 && PPBranchLevel <= (int)PPLevelBranchIndex.size());
513f4a2713aSLionel Sambuc   if (PPBranchLevel == (int)PPLevelBranchIndex.size()) {
514f4a2713aSLionel Sambuc     PPLevelBranchIndex.push_back(0);
515f4a2713aSLionel Sambuc     PPLevelBranchCount.push_back(0);
516f4a2713aSLionel Sambuc   }
517f4a2713aSLionel Sambuc   PPChainBranchIndex.push(0);
518*0a6a1f1dSLionel Sambuc   bool Skip = PPLevelBranchIndex[PPBranchLevel] > 0;
519*0a6a1f1dSLionel Sambuc   conditionalCompilationCondition(Unreachable || Skip);
520f4a2713aSLionel Sambuc }
521f4a2713aSLionel Sambuc 
conditionalCompilationAlternative()522*0a6a1f1dSLionel Sambuc void UnwrappedLineParser::conditionalCompilationAlternative() {
523f4a2713aSLionel Sambuc   if (!PPStack.empty())
524f4a2713aSLionel Sambuc     PPStack.pop_back();
525f4a2713aSLionel Sambuc   assert(PPBranchLevel < (int)PPLevelBranchIndex.size());
526f4a2713aSLionel Sambuc   if (!PPChainBranchIndex.empty())
527f4a2713aSLionel Sambuc     ++PPChainBranchIndex.top();
528*0a6a1f1dSLionel Sambuc   conditionalCompilationCondition(
529*0a6a1f1dSLionel Sambuc       PPBranchLevel >= 0 && !PPChainBranchIndex.empty() &&
530*0a6a1f1dSLionel Sambuc       PPLevelBranchIndex[PPBranchLevel] != PPChainBranchIndex.top());
531f4a2713aSLionel Sambuc }
532f4a2713aSLionel Sambuc 
conditionalCompilationEnd()533*0a6a1f1dSLionel Sambuc void UnwrappedLineParser::conditionalCompilationEnd() {
534f4a2713aSLionel Sambuc   assert(PPBranchLevel < (int)PPLevelBranchIndex.size());
535f4a2713aSLionel Sambuc   if (PPBranchLevel >= 0 && !PPChainBranchIndex.empty()) {
536f4a2713aSLionel Sambuc     if (PPChainBranchIndex.top() + 1 > PPLevelBranchCount[PPBranchLevel]) {
537f4a2713aSLionel Sambuc       PPLevelBranchCount[PPBranchLevel] = PPChainBranchIndex.top() + 1;
538f4a2713aSLionel Sambuc     }
539f4a2713aSLionel Sambuc   }
540*0a6a1f1dSLionel Sambuc   // Guard against #endif's without #if.
541*0a6a1f1dSLionel Sambuc   if (PPBranchLevel > 0)
542f4a2713aSLionel Sambuc     --PPBranchLevel;
543f4a2713aSLionel Sambuc   if (!PPChainBranchIndex.empty())
544f4a2713aSLionel Sambuc     PPChainBranchIndex.pop();
545f4a2713aSLionel Sambuc   if (!PPStack.empty())
546f4a2713aSLionel Sambuc     PPStack.pop_back();
547*0a6a1f1dSLionel Sambuc }
548*0a6a1f1dSLionel Sambuc 
parsePPIf(bool IfDef)549*0a6a1f1dSLionel Sambuc void UnwrappedLineParser::parsePPIf(bool IfDef) {
550*0a6a1f1dSLionel Sambuc   nextToken();
551*0a6a1f1dSLionel Sambuc   bool IsLiteralFalse = (FormatTok->Tok.isLiteral() &&
552*0a6a1f1dSLionel Sambuc                          StringRef(FormatTok->Tok.getLiteralData(),
553*0a6a1f1dSLionel Sambuc                                    FormatTok->Tok.getLength()) == "0") ||
554*0a6a1f1dSLionel Sambuc                         FormatTok->Tok.is(tok::kw_false);
555*0a6a1f1dSLionel Sambuc   conditionalCompilationStart(!IfDef && IsLiteralFalse);
556*0a6a1f1dSLionel Sambuc   parsePPUnknown();
557*0a6a1f1dSLionel Sambuc }
558*0a6a1f1dSLionel Sambuc 
parsePPElse()559*0a6a1f1dSLionel Sambuc void UnwrappedLineParser::parsePPElse() {
560*0a6a1f1dSLionel Sambuc   conditionalCompilationAlternative();
561*0a6a1f1dSLionel Sambuc   parsePPUnknown();
562*0a6a1f1dSLionel Sambuc }
563*0a6a1f1dSLionel Sambuc 
parsePPElIf()564*0a6a1f1dSLionel Sambuc void UnwrappedLineParser::parsePPElIf() { parsePPElse(); }
565*0a6a1f1dSLionel Sambuc 
parsePPEndIf()566*0a6a1f1dSLionel Sambuc void UnwrappedLineParser::parsePPEndIf() {
567*0a6a1f1dSLionel Sambuc   conditionalCompilationEnd();
568f4a2713aSLionel Sambuc   parsePPUnknown();
569f4a2713aSLionel Sambuc }
570f4a2713aSLionel Sambuc 
parsePPDefine()571f4a2713aSLionel Sambuc void UnwrappedLineParser::parsePPDefine() {
572f4a2713aSLionel Sambuc   nextToken();
573f4a2713aSLionel Sambuc 
574f4a2713aSLionel Sambuc   if (FormatTok->Tok.getKind() != tok::identifier) {
575f4a2713aSLionel Sambuc     parsePPUnknown();
576f4a2713aSLionel Sambuc     return;
577f4a2713aSLionel Sambuc   }
578f4a2713aSLionel Sambuc   nextToken();
579f4a2713aSLionel Sambuc   if (FormatTok->Tok.getKind() == tok::l_paren &&
580f4a2713aSLionel Sambuc       FormatTok->WhitespaceRange.getBegin() ==
581f4a2713aSLionel Sambuc           FormatTok->WhitespaceRange.getEnd()) {
582f4a2713aSLionel Sambuc     parseParens();
583f4a2713aSLionel Sambuc   }
584f4a2713aSLionel Sambuc   addUnwrappedLine();
585f4a2713aSLionel Sambuc   Line->Level = 1;
586f4a2713aSLionel Sambuc 
587f4a2713aSLionel Sambuc   // Errors during a preprocessor directive can only affect the layout of the
588f4a2713aSLionel Sambuc   // preprocessor directive, and thus we ignore them. An alternative approach
589f4a2713aSLionel Sambuc   // would be to use the same approach we use on the file level (no
590f4a2713aSLionel Sambuc   // re-indentation if there was a structural error) within the macro
591f4a2713aSLionel Sambuc   // definition.
592f4a2713aSLionel Sambuc   parseFile();
593f4a2713aSLionel Sambuc }
594f4a2713aSLionel Sambuc 
parsePPUnknown()595f4a2713aSLionel Sambuc void UnwrappedLineParser::parsePPUnknown() {
596f4a2713aSLionel Sambuc   do {
597f4a2713aSLionel Sambuc     nextToken();
598f4a2713aSLionel Sambuc   } while (!eof());
599f4a2713aSLionel Sambuc   addUnwrappedLine();
600f4a2713aSLionel Sambuc }
601f4a2713aSLionel Sambuc 
602f4a2713aSLionel Sambuc // Here we blacklist certain tokens that are not usually the first token in an
603f4a2713aSLionel Sambuc // unwrapped line. This is used in attempt to distinguish macro calls without
604f4a2713aSLionel Sambuc // trailing semicolons from other constructs split to several lines.
tokenCanStartNewLine(clang::Token Tok)605f4a2713aSLionel Sambuc bool tokenCanStartNewLine(clang::Token Tok) {
606f4a2713aSLionel Sambuc   // Semicolon can be a null-statement, l_square can be a start of a macro or
607f4a2713aSLionel Sambuc   // a C++11 attribute, but this doesn't seem to be common.
608f4a2713aSLionel Sambuc   return Tok.isNot(tok::semi) && Tok.isNot(tok::l_brace) &&
609f4a2713aSLionel Sambuc          Tok.isNot(tok::l_square) &&
610f4a2713aSLionel Sambuc          // Tokens that can only be used as binary operators and a part of
611f4a2713aSLionel Sambuc          // overloaded operator names.
612f4a2713aSLionel Sambuc          Tok.isNot(tok::period) && Tok.isNot(tok::periodstar) &&
613f4a2713aSLionel Sambuc          Tok.isNot(tok::arrow) && Tok.isNot(tok::arrowstar) &&
614f4a2713aSLionel Sambuc          Tok.isNot(tok::less) && Tok.isNot(tok::greater) &&
615f4a2713aSLionel Sambuc          Tok.isNot(tok::slash) && Tok.isNot(tok::percent) &&
616f4a2713aSLionel Sambuc          Tok.isNot(tok::lessless) && Tok.isNot(tok::greatergreater) &&
617f4a2713aSLionel Sambuc          Tok.isNot(tok::equal) && Tok.isNot(tok::plusequal) &&
618f4a2713aSLionel Sambuc          Tok.isNot(tok::minusequal) && Tok.isNot(tok::starequal) &&
619f4a2713aSLionel Sambuc          Tok.isNot(tok::slashequal) && Tok.isNot(tok::percentequal) &&
620f4a2713aSLionel Sambuc          Tok.isNot(tok::ampequal) && Tok.isNot(tok::pipeequal) &&
621f4a2713aSLionel Sambuc          Tok.isNot(tok::caretequal) && Tok.isNot(tok::greatergreaterequal) &&
622f4a2713aSLionel Sambuc          Tok.isNot(tok::lesslessequal) &&
623f4a2713aSLionel Sambuc          // Colon is used in labels, base class lists, initializer lists,
624f4a2713aSLionel Sambuc          // range-based for loops, ternary operator, but should never be the
625f4a2713aSLionel Sambuc          // first token in an unwrapped line.
626*0a6a1f1dSLionel Sambuc          Tok.isNot(tok::colon) &&
627*0a6a1f1dSLionel Sambuc          // 'noexcept' is a trailing annotation.
628*0a6a1f1dSLionel Sambuc          Tok.isNot(tok::kw_noexcept);
629f4a2713aSLionel Sambuc }
630f4a2713aSLionel Sambuc 
parseStructuralElement()631f4a2713aSLionel Sambuc void UnwrappedLineParser::parseStructuralElement() {
632f4a2713aSLionel Sambuc   assert(!FormatTok->Tok.is(tok::l_brace));
633f4a2713aSLionel Sambuc   switch (FormatTok->Tok.getKind()) {
634f4a2713aSLionel Sambuc   case tok::at:
635f4a2713aSLionel Sambuc     nextToken();
636f4a2713aSLionel Sambuc     if (FormatTok->Tok.is(tok::l_brace)) {
637f4a2713aSLionel Sambuc       parseBracedList();
638f4a2713aSLionel Sambuc       break;
639f4a2713aSLionel Sambuc     }
640f4a2713aSLionel Sambuc     switch (FormatTok->Tok.getObjCKeywordID()) {
641f4a2713aSLionel Sambuc     case tok::objc_public:
642f4a2713aSLionel Sambuc     case tok::objc_protected:
643f4a2713aSLionel Sambuc     case tok::objc_package:
644f4a2713aSLionel Sambuc     case tok::objc_private:
645f4a2713aSLionel Sambuc       return parseAccessSpecifier();
646f4a2713aSLionel Sambuc     case tok::objc_interface:
647f4a2713aSLionel Sambuc     case tok::objc_implementation:
648f4a2713aSLionel Sambuc       return parseObjCInterfaceOrImplementation();
649f4a2713aSLionel Sambuc     case tok::objc_protocol:
650f4a2713aSLionel Sambuc       return parseObjCProtocol();
651f4a2713aSLionel Sambuc     case tok::objc_end:
652f4a2713aSLionel Sambuc       return; // Handled by the caller.
653f4a2713aSLionel Sambuc     case tok::objc_optional:
654f4a2713aSLionel Sambuc     case tok::objc_required:
655f4a2713aSLionel Sambuc       nextToken();
656f4a2713aSLionel Sambuc       addUnwrappedLine();
657f4a2713aSLionel Sambuc       return;
658f4a2713aSLionel Sambuc     default:
659f4a2713aSLionel Sambuc       break;
660f4a2713aSLionel Sambuc     }
661f4a2713aSLionel Sambuc     break;
662*0a6a1f1dSLionel Sambuc   case tok::kw_asm:
663*0a6a1f1dSLionel Sambuc     nextToken();
664*0a6a1f1dSLionel Sambuc     if (FormatTok->is(tok::l_brace)) {
665*0a6a1f1dSLionel Sambuc       nextToken();
666*0a6a1f1dSLionel Sambuc       while (FormatTok && FormatTok->isNot(tok::eof)) {
667*0a6a1f1dSLionel Sambuc         if (FormatTok->is(tok::r_brace)) {
668*0a6a1f1dSLionel Sambuc           nextToken();
669*0a6a1f1dSLionel Sambuc           break;
670*0a6a1f1dSLionel Sambuc         }
671*0a6a1f1dSLionel Sambuc         FormatTok->Finalized = true;
672*0a6a1f1dSLionel Sambuc         nextToken();
673*0a6a1f1dSLionel Sambuc       }
674*0a6a1f1dSLionel Sambuc     }
675*0a6a1f1dSLionel Sambuc     break;
676f4a2713aSLionel Sambuc   case tok::kw_namespace:
677f4a2713aSLionel Sambuc     parseNamespace();
678f4a2713aSLionel Sambuc     return;
679f4a2713aSLionel Sambuc   case tok::kw_inline:
680f4a2713aSLionel Sambuc     nextToken();
681f4a2713aSLionel Sambuc     if (FormatTok->Tok.is(tok::kw_namespace)) {
682f4a2713aSLionel Sambuc       parseNamespace();
683f4a2713aSLionel Sambuc       return;
684f4a2713aSLionel Sambuc     }
685f4a2713aSLionel Sambuc     break;
686f4a2713aSLionel Sambuc   case tok::kw_public:
687f4a2713aSLionel Sambuc   case tok::kw_protected:
688f4a2713aSLionel Sambuc   case tok::kw_private:
689*0a6a1f1dSLionel Sambuc     if (Style.Language == FormatStyle::LK_Java)
690*0a6a1f1dSLionel Sambuc       nextToken();
691*0a6a1f1dSLionel Sambuc     else
692f4a2713aSLionel Sambuc       parseAccessSpecifier();
693f4a2713aSLionel Sambuc     return;
694f4a2713aSLionel Sambuc   case tok::kw_if:
695f4a2713aSLionel Sambuc     parseIfThenElse();
696f4a2713aSLionel Sambuc     return;
697f4a2713aSLionel Sambuc   case tok::kw_for:
698f4a2713aSLionel Sambuc   case tok::kw_while:
699f4a2713aSLionel Sambuc     parseForOrWhileLoop();
700f4a2713aSLionel Sambuc     return;
701f4a2713aSLionel Sambuc   case tok::kw_do:
702f4a2713aSLionel Sambuc     parseDoWhile();
703f4a2713aSLionel Sambuc     return;
704f4a2713aSLionel Sambuc   case tok::kw_switch:
705f4a2713aSLionel Sambuc     parseSwitch();
706f4a2713aSLionel Sambuc     return;
707f4a2713aSLionel Sambuc   case tok::kw_default:
708f4a2713aSLionel Sambuc     nextToken();
709f4a2713aSLionel Sambuc     parseLabel();
710f4a2713aSLionel Sambuc     return;
711f4a2713aSLionel Sambuc   case tok::kw_case:
712f4a2713aSLionel Sambuc     parseCaseLabel();
713f4a2713aSLionel Sambuc     return;
714*0a6a1f1dSLionel Sambuc   case tok::kw_try:
715*0a6a1f1dSLionel Sambuc     parseTryCatch();
716f4a2713aSLionel Sambuc     return;
717f4a2713aSLionel Sambuc   case tok::kw_extern:
718f4a2713aSLionel Sambuc     nextToken();
719f4a2713aSLionel Sambuc     if (FormatTok->Tok.is(tok::string_literal)) {
720f4a2713aSLionel Sambuc       nextToken();
721f4a2713aSLionel Sambuc       if (FormatTok->Tok.is(tok::l_brace)) {
722f4a2713aSLionel Sambuc         parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/false);
723f4a2713aSLionel Sambuc         addUnwrappedLine();
724f4a2713aSLionel Sambuc         return;
725f4a2713aSLionel Sambuc       }
726f4a2713aSLionel Sambuc     }
727*0a6a1f1dSLionel Sambuc     break;
728*0a6a1f1dSLionel Sambuc   case tok::identifier:
729*0a6a1f1dSLionel Sambuc     if (FormatTok->IsForEachMacro) {
730*0a6a1f1dSLionel Sambuc       parseForOrWhileLoop();
731*0a6a1f1dSLionel Sambuc       return;
732*0a6a1f1dSLionel Sambuc     }
733f4a2713aSLionel Sambuc     // In all other cases, parse the declaration.
734f4a2713aSLionel Sambuc     break;
735f4a2713aSLionel Sambuc   default:
736f4a2713aSLionel Sambuc     break;
737f4a2713aSLionel Sambuc   }
738f4a2713aSLionel Sambuc   do {
739f4a2713aSLionel Sambuc     switch (FormatTok->Tok.getKind()) {
740f4a2713aSLionel Sambuc     case tok::at:
741f4a2713aSLionel Sambuc       nextToken();
742f4a2713aSLionel Sambuc       if (FormatTok->Tok.is(tok::l_brace))
743f4a2713aSLionel Sambuc         parseBracedList();
744f4a2713aSLionel Sambuc       break;
745f4a2713aSLionel Sambuc     case tok::kw_enum:
746f4a2713aSLionel Sambuc       parseEnum();
747f4a2713aSLionel Sambuc       break;
748*0a6a1f1dSLionel Sambuc     case tok::kw_typedef:
749*0a6a1f1dSLionel Sambuc       nextToken();
750*0a6a1f1dSLionel Sambuc       if (FormatTok->isOneOf(Keywords.kw_NS_ENUM, Keywords.kw_NS_OPTIONS,
751*0a6a1f1dSLionel Sambuc                              Keywords.kw_CF_ENUM, Keywords.kw_CF_OPTIONS))
752*0a6a1f1dSLionel Sambuc         parseEnum();
753*0a6a1f1dSLionel Sambuc       break;
754f4a2713aSLionel Sambuc     case tok::kw_struct:
755f4a2713aSLionel Sambuc     case tok::kw_union:
756f4a2713aSLionel Sambuc     case tok::kw_class:
757f4a2713aSLionel Sambuc       parseRecord();
758f4a2713aSLionel Sambuc       // A record declaration or definition is always the start of a structural
759f4a2713aSLionel Sambuc       // element.
760f4a2713aSLionel Sambuc       break;
761*0a6a1f1dSLionel Sambuc     case tok::period:
762*0a6a1f1dSLionel Sambuc       nextToken();
763*0a6a1f1dSLionel Sambuc       // In Java, classes have an implicit static member "class".
764*0a6a1f1dSLionel Sambuc       if (Style.Language == FormatStyle::LK_Java && FormatTok &&
765*0a6a1f1dSLionel Sambuc           FormatTok->is(tok::kw_class))
766*0a6a1f1dSLionel Sambuc         nextToken();
767*0a6a1f1dSLionel Sambuc       break;
768f4a2713aSLionel Sambuc     case tok::semi:
769f4a2713aSLionel Sambuc       nextToken();
770f4a2713aSLionel Sambuc       addUnwrappedLine();
771f4a2713aSLionel Sambuc       return;
772f4a2713aSLionel Sambuc     case tok::r_brace:
773f4a2713aSLionel Sambuc       addUnwrappedLine();
774f4a2713aSLionel Sambuc       return;
775f4a2713aSLionel Sambuc     case tok::l_paren:
776f4a2713aSLionel Sambuc       parseParens();
777f4a2713aSLionel Sambuc       break;
778f4a2713aSLionel Sambuc     case tok::caret:
779f4a2713aSLionel Sambuc       nextToken();
780*0a6a1f1dSLionel Sambuc       if (FormatTok->Tok.isAnyIdentifier() ||
781*0a6a1f1dSLionel Sambuc           FormatTok->isSimpleTypeSpecifier())
782*0a6a1f1dSLionel Sambuc         nextToken();
783*0a6a1f1dSLionel Sambuc       if (FormatTok->is(tok::l_paren))
784*0a6a1f1dSLionel Sambuc         parseParens();
785*0a6a1f1dSLionel Sambuc       if (FormatTok->is(tok::l_brace))
786f4a2713aSLionel Sambuc         parseChildBlock();
787f4a2713aSLionel Sambuc       break;
788f4a2713aSLionel Sambuc     case tok::l_brace:
789f4a2713aSLionel Sambuc       if (!tryToParseBracedList()) {
790f4a2713aSLionel Sambuc         // A block outside of parentheses must be the last part of a
791f4a2713aSLionel Sambuc         // structural element.
792f4a2713aSLionel Sambuc         // FIXME: Figure out cases where this is not true, and add projections
793f4a2713aSLionel Sambuc         // for them (the one we know is missing are lambdas).
794*0a6a1f1dSLionel Sambuc         if (Style.BreakBeforeBraces != FormatStyle::BS_Attach)
795f4a2713aSLionel Sambuc           addUnwrappedLine();
796*0a6a1f1dSLionel Sambuc         FormatTok->Type = TT_FunctionLBrace;
797f4a2713aSLionel Sambuc         parseBlock(/*MustBeDeclaration=*/false);
798f4a2713aSLionel Sambuc         addUnwrappedLine();
799f4a2713aSLionel Sambuc         return;
800f4a2713aSLionel Sambuc       }
801f4a2713aSLionel Sambuc       // Otherwise this was a braced init list, and the structural
802f4a2713aSLionel Sambuc       // element continues.
803f4a2713aSLionel Sambuc       break;
804*0a6a1f1dSLionel Sambuc     case tok::kw_try:
805*0a6a1f1dSLionel Sambuc       // We arrive here when parsing function-try blocks.
806*0a6a1f1dSLionel Sambuc       parseTryCatch();
807*0a6a1f1dSLionel Sambuc       return;
808f4a2713aSLionel Sambuc     case tok::identifier: {
809f4a2713aSLionel Sambuc       StringRef Text = FormatTok->TokenText;
810*0a6a1f1dSLionel Sambuc       // Parse function literal unless 'function' is the first token in a line
811*0a6a1f1dSLionel Sambuc       // in which case this should be treated as a free-standing function.
812*0a6a1f1dSLionel Sambuc       if (Style.Language == FormatStyle::LK_JavaScript && Text == "function" &&
813*0a6a1f1dSLionel Sambuc           Line->Tokens.size() > 0) {
814*0a6a1f1dSLionel Sambuc         tryToParseJSFunction();
815*0a6a1f1dSLionel Sambuc         break;
816*0a6a1f1dSLionel Sambuc       }
817f4a2713aSLionel Sambuc       nextToken();
818f4a2713aSLionel Sambuc       if (Line->Tokens.size() == 1) {
819f4a2713aSLionel Sambuc         if (FormatTok->Tok.is(tok::colon)) {
820f4a2713aSLionel Sambuc           parseLabel();
821f4a2713aSLionel Sambuc           return;
822f4a2713aSLionel Sambuc         }
823*0a6a1f1dSLionel Sambuc         // Recognize function-like macro usages without trailing semicolon as
824*0a6a1f1dSLionel Sambuc         // well as free-standing macrose like Q_OBJECT.
825*0a6a1f1dSLionel Sambuc         bool FunctionLike = FormatTok->is(tok::l_paren);
826*0a6a1f1dSLionel Sambuc         if (FunctionLike)
827f4a2713aSLionel Sambuc           parseParens();
828*0a6a1f1dSLionel Sambuc         if (FormatTok->NewlinesBefore > 0 &&
829*0a6a1f1dSLionel Sambuc             (Text.size() >= 5 || FunctionLike) &&
830*0a6a1f1dSLionel Sambuc             tokenCanStartNewLine(FormatTok->Tok) && Text == Text.upper()) {
831f4a2713aSLionel Sambuc           addUnwrappedLine();
832f4a2713aSLionel Sambuc           return;
833f4a2713aSLionel Sambuc         }
834f4a2713aSLionel Sambuc       }
835f4a2713aSLionel Sambuc       break;
836f4a2713aSLionel Sambuc     }
837f4a2713aSLionel Sambuc     case tok::equal:
838f4a2713aSLionel Sambuc       nextToken();
839f4a2713aSLionel Sambuc       if (FormatTok->Tok.is(tok::l_brace)) {
840f4a2713aSLionel Sambuc         parseBracedList();
841f4a2713aSLionel Sambuc       }
842f4a2713aSLionel Sambuc       break;
843f4a2713aSLionel Sambuc     case tok::l_square:
844*0a6a1f1dSLionel Sambuc       parseSquare();
845f4a2713aSLionel Sambuc       break;
846f4a2713aSLionel Sambuc     default:
847f4a2713aSLionel Sambuc       nextToken();
848f4a2713aSLionel Sambuc       break;
849f4a2713aSLionel Sambuc     }
850f4a2713aSLionel Sambuc   } while (!eof());
851f4a2713aSLionel Sambuc }
852f4a2713aSLionel Sambuc 
tryToParseLambda()853*0a6a1f1dSLionel Sambuc bool UnwrappedLineParser::tryToParseLambda() {
854f4a2713aSLionel Sambuc   // FIXME: This is a dirty way to access the previous token. Find a better
855f4a2713aSLionel Sambuc   // solution.
856f4a2713aSLionel Sambuc   if (!Line->Tokens.empty() &&
857*0a6a1f1dSLionel Sambuc       (Line->Tokens.back().Tok->isOneOf(tok::identifier, tok::kw_operator,
858*0a6a1f1dSLionel Sambuc                                         tok::kw_new, tok::kw_delete) ||
859*0a6a1f1dSLionel Sambuc        Line->Tokens.back().Tok->closesScope() ||
860*0a6a1f1dSLionel Sambuc        Line->Tokens.back().Tok->isSimpleTypeSpecifier())) {
861f4a2713aSLionel Sambuc     nextToken();
862*0a6a1f1dSLionel Sambuc     return false;
863f4a2713aSLionel Sambuc   }
864f4a2713aSLionel Sambuc   assert(FormatTok->is(tok::l_square));
865f4a2713aSLionel Sambuc   FormatToken &LSquare = *FormatTok;
866f4a2713aSLionel Sambuc   if (!tryToParseLambdaIntroducer())
867*0a6a1f1dSLionel Sambuc     return false;
868f4a2713aSLionel Sambuc 
869f4a2713aSLionel Sambuc   while (FormatTok->isNot(tok::l_brace)) {
870*0a6a1f1dSLionel Sambuc     if (FormatTok->isSimpleTypeSpecifier()) {
871*0a6a1f1dSLionel Sambuc       nextToken();
872*0a6a1f1dSLionel Sambuc       continue;
873*0a6a1f1dSLionel Sambuc     }
874f4a2713aSLionel Sambuc     switch (FormatTok->Tok.getKind()) {
875f4a2713aSLionel Sambuc     case tok::l_brace:
876f4a2713aSLionel Sambuc       break;
877f4a2713aSLionel Sambuc     case tok::l_paren:
878f4a2713aSLionel Sambuc       parseParens();
879f4a2713aSLionel Sambuc       break;
880*0a6a1f1dSLionel Sambuc     case tok::amp:
881*0a6a1f1dSLionel Sambuc     case tok::star:
882*0a6a1f1dSLionel Sambuc     case tok::kw_const:
883*0a6a1f1dSLionel Sambuc     case tok::comma:
884*0a6a1f1dSLionel Sambuc     case tok::less:
885*0a6a1f1dSLionel Sambuc     case tok::greater:
886f4a2713aSLionel Sambuc     case tok::identifier:
887*0a6a1f1dSLionel Sambuc     case tok::coloncolon:
888f4a2713aSLionel Sambuc     case tok::kw_mutable:
889f4a2713aSLionel Sambuc       nextToken();
890f4a2713aSLionel Sambuc       break;
891*0a6a1f1dSLionel Sambuc     case tok::arrow:
892*0a6a1f1dSLionel Sambuc       FormatTok->Type = TT_TrailingReturnArrow;
893*0a6a1f1dSLionel Sambuc       nextToken();
894*0a6a1f1dSLionel Sambuc       break;
895f4a2713aSLionel Sambuc     default:
896*0a6a1f1dSLionel Sambuc       return true;
897f4a2713aSLionel Sambuc     }
898f4a2713aSLionel Sambuc   }
899f4a2713aSLionel Sambuc   LSquare.Type = TT_LambdaLSquare;
900f4a2713aSLionel Sambuc   parseChildBlock();
901*0a6a1f1dSLionel Sambuc   return true;
902f4a2713aSLionel Sambuc }
903f4a2713aSLionel Sambuc 
tryToParseLambdaIntroducer()904f4a2713aSLionel Sambuc bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
905f4a2713aSLionel Sambuc   nextToken();
906f4a2713aSLionel Sambuc   if (FormatTok->is(tok::equal)) {
907f4a2713aSLionel Sambuc     nextToken();
908f4a2713aSLionel Sambuc     if (FormatTok->is(tok::r_square)) {
909f4a2713aSLionel Sambuc       nextToken();
910f4a2713aSLionel Sambuc       return true;
911f4a2713aSLionel Sambuc     }
912f4a2713aSLionel Sambuc     if (FormatTok->isNot(tok::comma))
913f4a2713aSLionel Sambuc       return false;
914f4a2713aSLionel Sambuc     nextToken();
915f4a2713aSLionel Sambuc   } else if (FormatTok->is(tok::amp)) {
916f4a2713aSLionel Sambuc     nextToken();
917f4a2713aSLionel Sambuc     if (FormatTok->is(tok::r_square)) {
918f4a2713aSLionel Sambuc       nextToken();
919f4a2713aSLionel Sambuc       return true;
920f4a2713aSLionel Sambuc     }
921f4a2713aSLionel Sambuc     if (!FormatTok->isOneOf(tok::comma, tok::identifier)) {
922f4a2713aSLionel Sambuc       return false;
923f4a2713aSLionel Sambuc     }
924f4a2713aSLionel Sambuc     if (FormatTok->is(tok::comma))
925f4a2713aSLionel Sambuc       nextToken();
926f4a2713aSLionel Sambuc   } else if (FormatTok->is(tok::r_square)) {
927f4a2713aSLionel Sambuc     nextToken();
928f4a2713aSLionel Sambuc     return true;
929f4a2713aSLionel Sambuc   }
930f4a2713aSLionel Sambuc   do {
931f4a2713aSLionel Sambuc     if (FormatTok->is(tok::amp))
932f4a2713aSLionel Sambuc       nextToken();
933f4a2713aSLionel Sambuc     if (!FormatTok->isOneOf(tok::identifier, tok::kw_this))
934f4a2713aSLionel Sambuc       return false;
935f4a2713aSLionel Sambuc     nextToken();
936*0a6a1f1dSLionel Sambuc     if (FormatTok->is(tok::ellipsis))
937*0a6a1f1dSLionel Sambuc       nextToken();
938f4a2713aSLionel Sambuc     if (FormatTok->is(tok::comma)) {
939f4a2713aSLionel Sambuc       nextToken();
940f4a2713aSLionel Sambuc     } else if (FormatTok->is(tok::r_square)) {
941f4a2713aSLionel Sambuc       nextToken();
942f4a2713aSLionel Sambuc       return true;
943f4a2713aSLionel Sambuc     } else {
944f4a2713aSLionel Sambuc       return false;
945f4a2713aSLionel Sambuc     }
946f4a2713aSLionel Sambuc   } while (!eof());
947f4a2713aSLionel Sambuc   return false;
948f4a2713aSLionel Sambuc }
949f4a2713aSLionel Sambuc 
tryToParseJSFunction()950*0a6a1f1dSLionel Sambuc void UnwrappedLineParser::tryToParseJSFunction() {
951*0a6a1f1dSLionel Sambuc   nextToken();
952*0a6a1f1dSLionel Sambuc 
953*0a6a1f1dSLionel Sambuc   // Consume function name.
954*0a6a1f1dSLionel Sambuc   if (FormatTok->is(tok::identifier))
955*0a6a1f1dSLionel Sambuc       nextToken();
956*0a6a1f1dSLionel Sambuc 
957*0a6a1f1dSLionel Sambuc   if (FormatTok->isNot(tok::l_paren))
958*0a6a1f1dSLionel Sambuc     return;
959*0a6a1f1dSLionel Sambuc   nextToken();
960*0a6a1f1dSLionel Sambuc   while (FormatTok->isNot(tok::l_brace)) {
961*0a6a1f1dSLionel Sambuc     // Err on the side of caution in order to avoid consuming the full file in
962*0a6a1f1dSLionel Sambuc     // case of incomplete code.
963*0a6a1f1dSLionel Sambuc     if (!FormatTok->isOneOf(tok::identifier, tok::comma, tok::r_paren,
964*0a6a1f1dSLionel Sambuc                             tok::comment))
965*0a6a1f1dSLionel Sambuc       return;
966*0a6a1f1dSLionel Sambuc     nextToken();
967*0a6a1f1dSLionel Sambuc   }
968*0a6a1f1dSLionel Sambuc   parseChildBlock();
969*0a6a1f1dSLionel Sambuc }
970*0a6a1f1dSLionel Sambuc 
tryToParseBracedList()971f4a2713aSLionel Sambuc bool UnwrappedLineParser::tryToParseBracedList() {
972f4a2713aSLionel Sambuc   if (FormatTok->BlockKind == BK_Unknown)
973f4a2713aSLionel Sambuc     calculateBraceTypes();
974f4a2713aSLionel Sambuc   assert(FormatTok->BlockKind != BK_Unknown);
975f4a2713aSLionel Sambuc   if (FormatTok->BlockKind == BK_Block)
976f4a2713aSLionel Sambuc     return false;
977f4a2713aSLionel Sambuc   parseBracedList();
978f4a2713aSLionel Sambuc   return true;
979f4a2713aSLionel Sambuc }
980f4a2713aSLionel Sambuc 
parseBracedList(bool ContinueOnSemicolons)981f4a2713aSLionel Sambuc bool UnwrappedLineParser::parseBracedList(bool ContinueOnSemicolons) {
982f4a2713aSLionel Sambuc   bool HasError = false;
983f4a2713aSLionel Sambuc   nextToken();
984f4a2713aSLionel Sambuc 
985f4a2713aSLionel Sambuc   // FIXME: Once we have an expression parser in the UnwrappedLineParser,
986f4a2713aSLionel Sambuc   // replace this by using parseAssigmentExpression() inside.
987f4a2713aSLionel Sambuc   do {
988*0a6a1f1dSLionel Sambuc     if (Style.Language == FormatStyle::LK_JavaScript &&
989*0a6a1f1dSLionel Sambuc         FormatTok->is(Keywords.kw_function)) {
990*0a6a1f1dSLionel Sambuc       tryToParseJSFunction();
991*0a6a1f1dSLionel Sambuc       continue;
992*0a6a1f1dSLionel Sambuc     }
993f4a2713aSLionel Sambuc     switch (FormatTok->Tok.getKind()) {
994f4a2713aSLionel Sambuc     case tok::caret:
995f4a2713aSLionel Sambuc       nextToken();
996f4a2713aSLionel Sambuc       if (FormatTok->is(tok::l_brace)) {
997f4a2713aSLionel Sambuc         parseChildBlock();
998f4a2713aSLionel Sambuc       }
999f4a2713aSLionel Sambuc       break;
1000f4a2713aSLionel Sambuc     case tok::l_square:
1001f4a2713aSLionel Sambuc       tryToParseLambda();
1002f4a2713aSLionel Sambuc       break;
1003f4a2713aSLionel Sambuc     case tok::l_brace:
1004f4a2713aSLionel Sambuc       // Assume there are no blocks inside a braced init list apart
1005f4a2713aSLionel Sambuc       // from the ones we explicitly parse out (like lambdas).
1006f4a2713aSLionel Sambuc       FormatTok->BlockKind = BK_BracedInit;
1007f4a2713aSLionel Sambuc       parseBracedList();
1008f4a2713aSLionel Sambuc       break;
1009f4a2713aSLionel Sambuc     case tok::r_brace:
1010f4a2713aSLionel Sambuc       nextToken();
1011f4a2713aSLionel Sambuc       return !HasError;
1012f4a2713aSLionel Sambuc     case tok::semi:
1013f4a2713aSLionel Sambuc       HasError = true;
1014f4a2713aSLionel Sambuc       if (!ContinueOnSemicolons)
1015f4a2713aSLionel Sambuc         return !HasError;
1016f4a2713aSLionel Sambuc       nextToken();
1017f4a2713aSLionel Sambuc       break;
1018f4a2713aSLionel Sambuc     case tok::comma:
1019f4a2713aSLionel Sambuc       nextToken();
1020f4a2713aSLionel Sambuc       break;
1021f4a2713aSLionel Sambuc     default:
1022f4a2713aSLionel Sambuc       nextToken();
1023f4a2713aSLionel Sambuc       break;
1024f4a2713aSLionel Sambuc     }
1025f4a2713aSLionel Sambuc   } while (!eof());
1026f4a2713aSLionel Sambuc   return false;
1027f4a2713aSLionel Sambuc }
1028f4a2713aSLionel Sambuc 
parseParens()1029f4a2713aSLionel Sambuc void UnwrappedLineParser::parseParens() {
1030f4a2713aSLionel Sambuc   assert(FormatTok->Tok.is(tok::l_paren) && "'(' expected.");
1031f4a2713aSLionel Sambuc   nextToken();
1032f4a2713aSLionel Sambuc   do {
1033f4a2713aSLionel Sambuc     switch (FormatTok->Tok.getKind()) {
1034f4a2713aSLionel Sambuc     case tok::l_paren:
1035f4a2713aSLionel Sambuc       parseParens();
1036*0a6a1f1dSLionel Sambuc       if (Style.Language == FormatStyle::LK_Java && FormatTok->is(tok::l_brace))
1037*0a6a1f1dSLionel Sambuc         parseChildBlock();
1038f4a2713aSLionel Sambuc       break;
1039f4a2713aSLionel Sambuc     case tok::r_paren:
1040f4a2713aSLionel Sambuc       nextToken();
1041f4a2713aSLionel Sambuc       return;
1042f4a2713aSLionel Sambuc     case tok::r_brace:
1043f4a2713aSLionel Sambuc       // A "}" inside parenthesis is an error if there wasn't a matching "{".
1044f4a2713aSLionel Sambuc       return;
1045f4a2713aSLionel Sambuc     case tok::l_square:
1046f4a2713aSLionel Sambuc       tryToParseLambda();
1047f4a2713aSLionel Sambuc       break;
1048*0a6a1f1dSLionel Sambuc     case tok::l_brace:
1049*0a6a1f1dSLionel Sambuc       if (!tryToParseBracedList()) {
1050*0a6a1f1dSLionel Sambuc         parseChildBlock();
1051*0a6a1f1dSLionel Sambuc       }
1052*0a6a1f1dSLionel Sambuc       break;
1053*0a6a1f1dSLionel Sambuc     case tok::at:
1054*0a6a1f1dSLionel Sambuc       nextToken();
1055*0a6a1f1dSLionel Sambuc       if (FormatTok->Tok.is(tok::l_brace))
1056*0a6a1f1dSLionel Sambuc         parseBracedList();
1057*0a6a1f1dSLionel Sambuc       break;
1058*0a6a1f1dSLionel Sambuc     case tok::identifier:
1059*0a6a1f1dSLionel Sambuc       if (Style.Language == FormatStyle::LK_JavaScript &&
1060*0a6a1f1dSLionel Sambuc           FormatTok->is(Keywords.kw_function))
1061*0a6a1f1dSLionel Sambuc         tryToParseJSFunction();
1062*0a6a1f1dSLionel Sambuc       else
1063*0a6a1f1dSLionel Sambuc         nextToken();
1064*0a6a1f1dSLionel Sambuc       break;
1065*0a6a1f1dSLionel Sambuc     default:
1066*0a6a1f1dSLionel Sambuc       nextToken();
1067*0a6a1f1dSLionel Sambuc       break;
1068*0a6a1f1dSLionel Sambuc     }
1069*0a6a1f1dSLionel Sambuc   } while (!eof());
1070*0a6a1f1dSLionel Sambuc }
1071*0a6a1f1dSLionel Sambuc 
parseSquare()1072*0a6a1f1dSLionel Sambuc void UnwrappedLineParser::parseSquare() {
1073*0a6a1f1dSLionel Sambuc   assert(FormatTok->Tok.is(tok::l_square) && "'[' expected.");
1074*0a6a1f1dSLionel Sambuc   if (tryToParseLambda())
1075*0a6a1f1dSLionel Sambuc     return;
1076*0a6a1f1dSLionel Sambuc   do {
1077*0a6a1f1dSLionel Sambuc     switch (FormatTok->Tok.getKind()) {
1078*0a6a1f1dSLionel Sambuc     case tok::l_paren:
1079*0a6a1f1dSLionel Sambuc       parseParens();
1080*0a6a1f1dSLionel Sambuc       break;
1081*0a6a1f1dSLionel Sambuc     case tok::r_square:
1082*0a6a1f1dSLionel Sambuc       nextToken();
1083*0a6a1f1dSLionel Sambuc       return;
1084*0a6a1f1dSLionel Sambuc     case tok::r_brace:
1085*0a6a1f1dSLionel Sambuc       // A "}" inside parenthesis is an error if there wasn't a matching "{".
1086*0a6a1f1dSLionel Sambuc       return;
1087*0a6a1f1dSLionel Sambuc     case tok::l_square:
1088*0a6a1f1dSLionel Sambuc       parseSquare();
1089*0a6a1f1dSLionel Sambuc       break;
1090f4a2713aSLionel Sambuc     case tok::l_brace: {
1091f4a2713aSLionel Sambuc       if (!tryToParseBracedList()) {
1092f4a2713aSLionel Sambuc         parseChildBlock();
1093f4a2713aSLionel Sambuc       }
1094f4a2713aSLionel Sambuc       break;
1095f4a2713aSLionel Sambuc     }
1096f4a2713aSLionel Sambuc     case tok::at:
1097f4a2713aSLionel Sambuc       nextToken();
1098f4a2713aSLionel Sambuc       if (FormatTok->Tok.is(tok::l_brace))
1099f4a2713aSLionel Sambuc         parseBracedList();
1100f4a2713aSLionel Sambuc       break;
1101f4a2713aSLionel Sambuc     default:
1102f4a2713aSLionel Sambuc       nextToken();
1103f4a2713aSLionel Sambuc       break;
1104f4a2713aSLionel Sambuc     }
1105f4a2713aSLionel Sambuc   } while (!eof());
1106f4a2713aSLionel Sambuc }
1107f4a2713aSLionel Sambuc 
parseIfThenElse()1108f4a2713aSLionel Sambuc void UnwrappedLineParser::parseIfThenElse() {
1109f4a2713aSLionel Sambuc   assert(FormatTok->Tok.is(tok::kw_if) && "'if' expected");
1110f4a2713aSLionel Sambuc   nextToken();
1111f4a2713aSLionel Sambuc   if (FormatTok->Tok.is(tok::l_paren))
1112f4a2713aSLionel Sambuc     parseParens();
1113f4a2713aSLionel Sambuc   bool NeedsUnwrappedLine = false;
1114f4a2713aSLionel Sambuc   if (FormatTok->Tok.is(tok::l_brace)) {
1115*0a6a1f1dSLionel Sambuc     CompoundStatementIndenter Indenter(this, Style, Line->Level);
1116f4a2713aSLionel Sambuc     parseBlock(/*MustBeDeclaration=*/false);
1117*0a6a1f1dSLionel Sambuc     if (Style.BreakBeforeBraces == FormatStyle::BS_Allman ||
1118*0a6a1f1dSLionel Sambuc         Style.BreakBeforeBraces == FormatStyle::BS_GNU) {
1119f4a2713aSLionel Sambuc       addUnwrappedLine();
1120*0a6a1f1dSLionel Sambuc     } else {
1121f4a2713aSLionel Sambuc       NeedsUnwrappedLine = true;
1122*0a6a1f1dSLionel Sambuc     }
1123f4a2713aSLionel Sambuc   } else {
1124f4a2713aSLionel Sambuc     addUnwrappedLine();
1125f4a2713aSLionel Sambuc     ++Line->Level;
1126f4a2713aSLionel Sambuc     parseStructuralElement();
1127f4a2713aSLionel Sambuc     --Line->Level;
1128f4a2713aSLionel Sambuc   }
1129f4a2713aSLionel Sambuc   if (FormatTok->Tok.is(tok::kw_else)) {
1130*0a6a1f1dSLionel Sambuc     if (Style.BreakBeforeBraces == FormatStyle::BS_Stroustrup)
1131*0a6a1f1dSLionel Sambuc       addUnwrappedLine();
1132f4a2713aSLionel Sambuc     nextToken();
1133f4a2713aSLionel Sambuc     if (FormatTok->Tok.is(tok::l_brace)) {
1134*0a6a1f1dSLionel Sambuc       CompoundStatementIndenter Indenter(this, Style, Line->Level);
1135f4a2713aSLionel Sambuc       parseBlock(/*MustBeDeclaration=*/false);
1136f4a2713aSLionel Sambuc       addUnwrappedLine();
1137f4a2713aSLionel Sambuc     } else if (FormatTok->Tok.is(tok::kw_if)) {
1138f4a2713aSLionel Sambuc       parseIfThenElse();
1139f4a2713aSLionel Sambuc     } else {
1140f4a2713aSLionel Sambuc       addUnwrappedLine();
1141f4a2713aSLionel Sambuc       ++Line->Level;
1142f4a2713aSLionel Sambuc       parseStructuralElement();
1143f4a2713aSLionel Sambuc       --Line->Level;
1144f4a2713aSLionel Sambuc     }
1145f4a2713aSLionel Sambuc   } else if (NeedsUnwrappedLine) {
1146f4a2713aSLionel Sambuc     addUnwrappedLine();
1147f4a2713aSLionel Sambuc   }
1148f4a2713aSLionel Sambuc }
1149f4a2713aSLionel Sambuc 
parseTryCatch()1150*0a6a1f1dSLionel Sambuc void UnwrappedLineParser::parseTryCatch() {
1151*0a6a1f1dSLionel Sambuc   assert(FormatTok->is(tok::kw_try) && "'try' expected");
1152*0a6a1f1dSLionel Sambuc   nextToken();
1153*0a6a1f1dSLionel Sambuc   bool NeedsUnwrappedLine = false;
1154*0a6a1f1dSLionel Sambuc   if (FormatTok->is(tok::colon)) {
1155*0a6a1f1dSLionel Sambuc     // We are in a function try block, what comes is an initializer list.
1156*0a6a1f1dSLionel Sambuc     nextToken();
1157*0a6a1f1dSLionel Sambuc     while (FormatTok->is(tok::identifier)) {
1158*0a6a1f1dSLionel Sambuc       nextToken();
1159*0a6a1f1dSLionel Sambuc       if (FormatTok->is(tok::l_paren))
1160*0a6a1f1dSLionel Sambuc         parseParens();
1161*0a6a1f1dSLionel Sambuc       else
1162*0a6a1f1dSLionel Sambuc         StructuralError = true;
1163*0a6a1f1dSLionel Sambuc       if (FormatTok->is(tok::comma))
1164*0a6a1f1dSLionel Sambuc         nextToken();
1165*0a6a1f1dSLionel Sambuc     }
1166*0a6a1f1dSLionel Sambuc   }
1167*0a6a1f1dSLionel Sambuc   // Parse try with resource.
1168*0a6a1f1dSLionel Sambuc   if (Style.Language == FormatStyle::LK_Java && FormatTok->is(tok::l_paren)) {
1169*0a6a1f1dSLionel Sambuc     parseParens();
1170*0a6a1f1dSLionel Sambuc   }
1171*0a6a1f1dSLionel Sambuc   if (FormatTok->is(tok::l_brace)) {
1172*0a6a1f1dSLionel Sambuc     CompoundStatementIndenter Indenter(this, Style, Line->Level);
1173*0a6a1f1dSLionel Sambuc     parseBlock(/*MustBeDeclaration=*/false);
1174*0a6a1f1dSLionel Sambuc     if (Style.BreakBeforeBraces == FormatStyle::BS_Allman ||
1175*0a6a1f1dSLionel Sambuc         Style.BreakBeforeBraces == FormatStyle::BS_GNU ||
1176*0a6a1f1dSLionel Sambuc         Style.BreakBeforeBraces == FormatStyle::BS_Stroustrup) {
1177*0a6a1f1dSLionel Sambuc       addUnwrappedLine();
1178*0a6a1f1dSLionel Sambuc     } else {
1179*0a6a1f1dSLionel Sambuc       NeedsUnwrappedLine = true;
1180*0a6a1f1dSLionel Sambuc     }
1181*0a6a1f1dSLionel Sambuc   } else if (!FormatTok->is(tok::kw_catch)) {
1182*0a6a1f1dSLionel Sambuc     // The C++ standard requires a compound-statement after a try.
1183*0a6a1f1dSLionel Sambuc     // If there's none, we try to assume there's a structuralElement
1184*0a6a1f1dSLionel Sambuc     // and try to continue.
1185*0a6a1f1dSLionel Sambuc     StructuralError = true;
1186*0a6a1f1dSLionel Sambuc     addUnwrappedLine();
1187*0a6a1f1dSLionel Sambuc     ++Line->Level;
1188*0a6a1f1dSLionel Sambuc     parseStructuralElement();
1189*0a6a1f1dSLionel Sambuc     --Line->Level;
1190*0a6a1f1dSLionel Sambuc   }
1191*0a6a1f1dSLionel Sambuc   while (FormatTok->is(tok::kw_catch) ||
1192*0a6a1f1dSLionel Sambuc          ((Style.Language == FormatStyle::LK_Java ||
1193*0a6a1f1dSLionel Sambuc            Style.Language == FormatStyle::LK_JavaScript) &&
1194*0a6a1f1dSLionel Sambuc           FormatTok->is(Keywords.kw_finally))) {
1195*0a6a1f1dSLionel Sambuc     nextToken();
1196*0a6a1f1dSLionel Sambuc     while (FormatTok->isNot(tok::l_brace)) {
1197*0a6a1f1dSLionel Sambuc       if (FormatTok->is(tok::l_paren)) {
1198*0a6a1f1dSLionel Sambuc         parseParens();
1199*0a6a1f1dSLionel Sambuc         continue;
1200*0a6a1f1dSLionel Sambuc       }
1201*0a6a1f1dSLionel Sambuc       if (FormatTok->isOneOf(tok::semi, tok::r_brace))
1202*0a6a1f1dSLionel Sambuc         return;
1203*0a6a1f1dSLionel Sambuc       nextToken();
1204*0a6a1f1dSLionel Sambuc     }
1205*0a6a1f1dSLionel Sambuc     NeedsUnwrappedLine = false;
1206*0a6a1f1dSLionel Sambuc     CompoundStatementIndenter Indenter(this, Style, Line->Level);
1207*0a6a1f1dSLionel Sambuc     parseBlock(/*MustBeDeclaration=*/false);
1208*0a6a1f1dSLionel Sambuc     if (Style.BreakBeforeBraces == FormatStyle::BS_Allman ||
1209*0a6a1f1dSLionel Sambuc         Style.BreakBeforeBraces == FormatStyle::BS_GNU ||
1210*0a6a1f1dSLionel Sambuc         Style.BreakBeforeBraces == FormatStyle::BS_Stroustrup) {
1211*0a6a1f1dSLionel Sambuc       addUnwrappedLine();
1212*0a6a1f1dSLionel Sambuc     } else {
1213*0a6a1f1dSLionel Sambuc       NeedsUnwrappedLine = true;
1214*0a6a1f1dSLionel Sambuc     }
1215*0a6a1f1dSLionel Sambuc   }
1216*0a6a1f1dSLionel Sambuc   if (NeedsUnwrappedLine) {
1217*0a6a1f1dSLionel Sambuc     addUnwrappedLine();
1218*0a6a1f1dSLionel Sambuc   }
1219*0a6a1f1dSLionel Sambuc }
1220*0a6a1f1dSLionel Sambuc 
parseNamespace()1221f4a2713aSLionel Sambuc void UnwrappedLineParser::parseNamespace() {
1222f4a2713aSLionel Sambuc   assert(FormatTok->Tok.is(tok::kw_namespace) && "'namespace' expected");
1223*0a6a1f1dSLionel Sambuc 
1224*0a6a1f1dSLionel Sambuc   const FormatToken &InitialToken = *FormatTok;
1225f4a2713aSLionel Sambuc   nextToken();
1226f4a2713aSLionel Sambuc   if (FormatTok->Tok.is(tok::identifier))
1227f4a2713aSLionel Sambuc     nextToken();
1228f4a2713aSLionel Sambuc   if (FormatTok->Tok.is(tok::l_brace)) {
1229*0a6a1f1dSLionel Sambuc     if (ShouldBreakBeforeBrace(Style, InitialToken))
1230f4a2713aSLionel Sambuc       addUnwrappedLine();
1231f4a2713aSLionel Sambuc 
1232f4a2713aSLionel Sambuc     bool AddLevel = Style.NamespaceIndentation == FormatStyle::NI_All ||
1233f4a2713aSLionel Sambuc                     (Style.NamespaceIndentation == FormatStyle::NI_Inner &&
1234f4a2713aSLionel Sambuc                      DeclarationScopeStack.size() > 1);
1235f4a2713aSLionel Sambuc     parseBlock(/*MustBeDeclaration=*/true, AddLevel);
1236f4a2713aSLionel Sambuc     // Munch the semicolon after a namespace. This is more common than one would
1237f4a2713aSLionel Sambuc     // think. Puttin the semicolon into its own line is very ugly.
1238f4a2713aSLionel Sambuc     if (FormatTok->Tok.is(tok::semi))
1239f4a2713aSLionel Sambuc       nextToken();
1240f4a2713aSLionel Sambuc     addUnwrappedLine();
1241f4a2713aSLionel Sambuc   }
1242f4a2713aSLionel Sambuc   // FIXME: Add error handling.
1243f4a2713aSLionel Sambuc }
1244f4a2713aSLionel Sambuc 
parseForOrWhileLoop()1245f4a2713aSLionel Sambuc void UnwrappedLineParser::parseForOrWhileLoop() {
1246*0a6a1f1dSLionel Sambuc   assert((FormatTok->Tok.is(tok::kw_for) || FormatTok->Tok.is(tok::kw_while) ||
1247*0a6a1f1dSLionel Sambuc           FormatTok->IsForEachMacro) &&
1248*0a6a1f1dSLionel Sambuc          "'for', 'while' or foreach macro expected");
1249f4a2713aSLionel Sambuc   nextToken();
1250f4a2713aSLionel Sambuc   if (FormatTok->Tok.is(tok::l_paren))
1251f4a2713aSLionel Sambuc     parseParens();
1252f4a2713aSLionel Sambuc   if (FormatTok->Tok.is(tok::l_brace)) {
1253*0a6a1f1dSLionel Sambuc     CompoundStatementIndenter Indenter(this, Style, Line->Level);
1254f4a2713aSLionel Sambuc     parseBlock(/*MustBeDeclaration=*/false);
1255f4a2713aSLionel Sambuc     addUnwrappedLine();
1256f4a2713aSLionel Sambuc   } else {
1257f4a2713aSLionel Sambuc     addUnwrappedLine();
1258f4a2713aSLionel Sambuc     ++Line->Level;
1259f4a2713aSLionel Sambuc     parseStructuralElement();
1260f4a2713aSLionel Sambuc     --Line->Level;
1261f4a2713aSLionel Sambuc   }
1262f4a2713aSLionel Sambuc }
1263f4a2713aSLionel Sambuc 
parseDoWhile()1264f4a2713aSLionel Sambuc void UnwrappedLineParser::parseDoWhile() {
1265f4a2713aSLionel Sambuc   assert(FormatTok->Tok.is(tok::kw_do) && "'do' expected");
1266f4a2713aSLionel Sambuc   nextToken();
1267f4a2713aSLionel Sambuc   if (FormatTok->Tok.is(tok::l_brace)) {
1268*0a6a1f1dSLionel Sambuc     CompoundStatementIndenter Indenter(this, Style, Line->Level);
1269f4a2713aSLionel Sambuc     parseBlock(/*MustBeDeclaration=*/false);
1270*0a6a1f1dSLionel Sambuc     if (Style.BreakBeforeBraces == FormatStyle::BS_GNU)
1271*0a6a1f1dSLionel Sambuc       addUnwrappedLine();
1272f4a2713aSLionel Sambuc   } else {
1273f4a2713aSLionel Sambuc     addUnwrappedLine();
1274f4a2713aSLionel Sambuc     ++Line->Level;
1275f4a2713aSLionel Sambuc     parseStructuralElement();
1276f4a2713aSLionel Sambuc     --Line->Level;
1277f4a2713aSLionel Sambuc   }
1278f4a2713aSLionel Sambuc 
1279f4a2713aSLionel Sambuc   // FIXME: Add error handling.
1280f4a2713aSLionel Sambuc   if (!FormatTok->Tok.is(tok::kw_while)) {
1281f4a2713aSLionel Sambuc     addUnwrappedLine();
1282f4a2713aSLionel Sambuc     return;
1283f4a2713aSLionel Sambuc   }
1284f4a2713aSLionel Sambuc 
1285f4a2713aSLionel Sambuc   nextToken();
1286f4a2713aSLionel Sambuc   parseStructuralElement();
1287f4a2713aSLionel Sambuc }
1288f4a2713aSLionel Sambuc 
parseLabel()1289f4a2713aSLionel Sambuc void UnwrappedLineParser::parseLabel() {
1290f4a2713aSLionel Sambuc   nextToken();
1291f4a2713aSLionel Sambuc   unsigned OldLineLevel = Line->Level;
1292f4a2713aSLionel Sambuc   if (Line->Level > 1 || (!Line->InPPDirective && Line->Level > 0))
1293f4a2713aSLionel Sambuc     --Line->Level;
1294f4a2713aSLionel Sambuc   if (CommentsBeforeNextToken.empty() && FormatTok->Tok.is(tok::l_brace)) {
1295*0a6a1f1dSLionel Sambuc     CompoundStatementIndenter Indenter(this, Style, Line->Level);
1296f4a2713aSLionel Sambuc     parseBlock(/*MustBeDeclaration=*/false);
1297f4a2713aSLionel Sambuc     if (FormatTok->Tok.is(tok::kw_break)) {
1298*0a6a1f1dSLionel Sambuc       // "break;" after "}" on its own line only for BS_Allman and BS_GNU
1299*0a6a1f1dSLionel Sambuc       if (Style.BreakBeforeBraces == FormatStyle::BS_Allman ||
1300*0a6a1f1dSLionel Sambuc           Style.BreakBeforeBraces == FormatStyle::BS_GNU) {
1301f4a2713aSLionel Sambuc         addUnwrappedLine();
1302*0a6a1f1dSLionel Sambuc       }
1303f4a2713aSLionel Sambuc       parseStructuralElement();
1304f4a2713aSLionel Sambuc     }
1305f4a2713aSLionel Sambuc     addUnwrappedLine();
1306*0a6a1f1dSLionel Sambuc   } else {
1307*0a6a1f1dSLionel Sambuc     addUnwrappedLine();
1308*0a6a1f1dSLionel Sambuc   }
1309f4a2713aSLionel Sambuc   Line->Level = OldLineLevel;
1310f4a2713aSLionel Sambuc }
1311f4a2713aSLionel Sambuc 
parseCaseLabel()1312f4a2713aSLionel Sambuc void UnwrappedLineParser::parseCaseLabel() {
1313f4a2713aSLionel Sambuc   assert(FormatTok->Tok.is(tok::kw_case) && "'case' expected");
1314f4a2713aSLionel Sambuc   // FIXME: fix handling of complex expressions here.
1315f4a2713aSLionel Sambuc   do {
1316f4a2713aSLionel Sambuc     nextToken();
1317f4a2713aSLionel Sambuc   } while (!eof() && !FormatTok->Tok.is(tok::colon));
1318f4a2713aSLionel Sambuc   parseLabel();
1319f4a2713aSLionel Sambuc }
1320f4a2713aSLionel Sambuc 
parseSwitch()1321f4a2713aSLionel Sambuc void UnwrappedLineParser::parseSwitch() {
1322f4a2713aSLionel Sambuc   assert(FormatTok->Tok.is(tok::kw_switch) && "'switch' expected");
1323f4a2713aSLionel Sambuc   nextToken();
1324f4a2713aSLionel Sambuc   if (FormatTok->Tok.is(tok::l_paren))
1325f4a2713aSLionel Sambuc     parseParens();
1326f4a2713aSLionel Sambuc   if (FormatTok->Tok.is(tok::l_brace)) {
1327*0a6a1f1dSLionel Sambuc     CompoundStatementIndenter Indenter(this, Style, Line->Level);
1328f4a2713aSLionel Sambuc     parseBlock(/*MustBeDeclaration=*/false);
1329f4a2713aSLionel Sambuc     addUnwrappedLine();
1330f4a2713aSLionel Sambuc   } else {
1331f4a2713aSLionel Sambuc     addUnwrappedLine();
1332f4a2713aSLionel Sambuc     ++Line->Level;
1333f4a2713aSLionel Sambuc     parseStructuralElement();
1334f4a2713aSLionel Sambuc     --Line->Level;
1335f4a2713aSLionel Sambuc   }
1336f4a2713aSLionel Sambuc }
1337f4a2713aSLionel Sambuc 
parseAccessSpecifier()1338f4a2713aSLionel Sambuc void UnwrappedLineParser::parseAccessSpecifier() {
1339f4a2713aSLionel Sambuc   nextToken();
1340*0a6a1f1dSLionel Sambuc   // Understand Qt's slots.
1341*0a6a1f1dSLionel Sambuc   if (FormatTok->is(tok::identifier) &&
1342*0a6a1f1dSLionel Sambuc       (FormatTok->TokenText == "slots" || FormatTok->TokenText == "Q_SLOTS"))
1343*0a6a1f1dSLionel Sambuc     nextToken();
1344f4a2713aSLionel Sambuc   // Otherwise, we don't know what it is, and we'd better keep the next token.
1345f4a2713aSLionel Sambuc   if (FormatTok->Tok.is(tok::colon))
1346f4a2713aSLionel Sambuc     nextToken();
1347f4a2713aSLionel Sambuc   addUnwrappedLine();
1348f4a2713aSLionel Sambuc }
1349f4a2713aSLionel Sambuc 
parseEnum()1350f4a2713aSLionel Sambuc void UnwrappedLineParser::parseEnum() {
1351*0a6a1f1dSLionel Sambuc   // Won't be 'enum' for NS_ENUMs.
1352*0a6a1f1dSLionel Sambuc   if (FormatTok->Tok.is(tok::kw_enum))
1353f4a2713aSLionel Sambuc     nextToken();
1354*0a6a1f1dSLionel Sambuc 
1355f4a2713aSLionel Sambuc   // Eat up enum class ...
1356*0a6a1f1dSLionel Sambuc   if (FormatTok->Tok.is(tok::kw_class) || FormatTok->Tok.is(tok::kw_struct))
1357f4a2713aSLionel Sambuc     nextToken();
1358f4a2713aSLionel Sambuc   while (FormatTok->Tok.getIdentifierInfo() ||
1359*0a6a1f1dSLionel Sambuc          FormatTok->isOneOf(tok::colon, tok::coloncolon, tok::less,
1360*0a6a1f1dSLionel Sambuc                             tok::greater, tok::comma, tok::question)) {
1361f4a2713aSLionel Sambuc     nextToken();
1362f4a2713aSLionel Sambuc     // We can have macros or attributes in between 'enum' and the enum name.
1363*0a6a1f1dSLionel Sambuc     if (FormatTok->is(tok::l_paren))
1364f4a2713aSLionel Sambuc       parseParens();
1365*0a6a1f1dSLionel Sambuc     if (FormatTok->is(tok::identifier))
1366f4a2713aSLionel Sambuc       nextToken();
1367f4a2713aSLionel Sambuc   }
1368*0a6a1f1dSLionel Sambuc 
1369*0a6a1f1dSLionel Sambuc   // Just a declaration or something is wrong.
1370*0a6a1f1dSLionel Sambuc   if (FormatTok->isNot(tok::l_brace))
1371*0a6a1f1dSLionel Sambuc     return;
1372f4a2713aSLionel Sambuc   FormatTok->BlockKind = BK_Block;
1373*0a6a1f1dSLionel Sambuc 
1374*0a6a1f1dSLionel Sambuc   if (Style.Language == FormatStyle::LK_Java) {
1375*0a6a1f1dSLionel Sambuc     // Java enums are different.
1376*0a6a1f1dSLionel Sambuc     parseJavaEnumBody();
1377*0a6a1f1dSLionel Sambuc     return;
1378*0a6a1f1dSLionel Sambuc   }
1379*0a6a1f1dSLionel Sambuc 
1380*0a6a1f1dSLionel Sambuc   // Parse enum body.
1381f4a2713aSLionel Sambuc   bool HasError = !parseBracedList(/*ContinueOnSemicolons=*/true);
1382f4a2713aSLionel Sambuc   if (HasError) {
1383f4a2713aSLionel Sambuc     if (FormatTok->is(tok::semi))
1384f4a2713aSLionel Sambuc       nextToken();
1385f4a2713aSLionel Sambuc     addUnwrappedLine();
1386f4a2713aSLionel Sambuc   }
1387*0a6a1f1dSLionel Sambuc 
1388f4a2713aSLionel Sambuc   // We fall through to parsing a structural element afterwards, so that in
1389f4a2713aSLionel Sambuc   // enum A {} n, m;
1390f4a2713aSLionel Sambuc   // "} n, m;" will end up in one unwrapped line.
1391f4a2713aSLionel Sambuc }
1392f4a2713aSLionel Sambuc 
parseJavaEnumBody()1393*0a6a1f1dSLionel Sambuc void UnwrappedLineParser::parseJavaEnumBody() {
1394*0a6a1f1dSLionel Sambuc   // Determine whether the enum is simple, i.e. does not have a semicolon or
1395*0a6a1f1dSLionel Sambuc   // constants with class bodies. Simple enums can be formatted like braced
1396*0a6a1f1dSLionel Sambuc   // lists, contracted to a single line, etc.
1397*0a6a1f1dSLionel Sambuc   unsigned StoredPosition = Tokens->getPosition();
1398*0a6a1f1dSLionel Sambuc   bool IsSimple = true;
1399*0a6a1f1dSLionel Sambuc   FormatToken *Tok = Tokens->getNextToken();
1400*0a6a1f1dSLionel Sambuc   while (Tok) {
1401*0a6a1f1dSLionel Sambuc     if (Tok->is(tok::r_brace))
1402*0a6a1f1dSLionel Sambuc       break;
1403*0a6a1f1dSLionel Sambuc     if (Tok->isOneOf(tok::l_brace, tok::semi)) {
1404*0a6a1f1dSLionel Sambuc       IsSimple = false;
1405*0a6a1f1dSLionel Sambuc       break;
1406*0a6a1f1dSLionel Sambuc     }
1407*0a6a1f1dSLionel Sambuc     // FIXME: This will also mark enums with braces in the arguments to enum
1408*0a6a1f1dSLionel Sambuc     // constants as "not simple". This is probably fine in practice, though.
1409*0a6a1f1dSLionel Sambuc     Tok = Tokens->getNextToken();
1410*0a6a1f1dSLionel Sambuc   }
1411*0a6a1f1dSLionel Sambuc   FormatTok = Tokens->setPosition(StoredPosition);
1412*0a6a1f1dSLionel Sambuc 
1413*0a6a1f1dSLionel Sambuc   if (IsSimple) {
1414*0a6a1f1dSLionel Sambuc     parseBracedList();
1415*0a6a1f1dSLionel Sambuc     addUnwrappedLine();
1416*0a6a1f1dSLionel Sambuc     return;
1417*0a6a1f1dSLionel Sambuc   }
1418*0a6a1f1dSLionel Sambuc 
1419*0a6a1f1dSLionel Sambuc   // Parse the body of a more complex enum.
1420*0a6a1f1dSLionel Sambuc   // First add a line for everything up to the "{".
1421f4a2713aSLionel Sambuc   nextToken();
1422*0a6a1f1dSLionel Sambuc   addUnwrappedLine();
1423*0a6a1f1dSLionel Sambuc   ++Line->Level;
1424*0a6a1f1dSLionel Sambuc 
1425*0a6a1f1dSLionel Sambuc   // Parse the enum constants.
1426*0a6a1f1dSLionel Sambuc   while (FormatTok) {
1427*0a6a1f1dSLionel Sambuc     if (FormatTok->is(tok::l_brace)) {
1428*0a6a1f1dSLionel Sambuc       // Parse the constant's class body.
1429*0a6a1f1dSLionel Sambuc       parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/true,
1430*0a6a1f1dSLionel Sambuc                  /*MunchSemi=*/false);
1431*0a6a1f1dSLionel Sambuc     } else if (FormatTok->is(tok::l_paren)) {
1432*0a6a1f1dSLionel Sambuc       parseParens();
1433*0a6a1f1dSLionel Sambuc     } else if (FormatTok->is(tok::comma)) {
1434*0a6a1f1dSLionel Sambuc       nextToken();
1435*0a6a1f1dSLionel Sambuc       addUnwrappedLine();
1436*0a6a1f1dSLionel Sambuc     } else if (FormatTok->is(tok::semi)) {
1437*0a6a1f1dSLionel Sambuc       nextToken();
1438*0a6a1f1dSLionel Sambuc       addUnwrappedLine();
1439*0a6a1f1dSLionel Sambuc       break;
1440*0a6a1f1dSLionel Sambuc     } else if (FormatTok->is(tok::r_brace)) {
1441*0a6a1f1dSLionel Sambuc       addUnwrappedLine();
1442*0a6a1f1dSLionel Sambuc       break;
1443*0a6a1f1dSLionel Sambuc     } else {
1444*0a6a1f1dSLionel Sambuc       nextToken();
1445*0a6a1f1dSLionel Sambuc     }
1446*0a6a1f1dSLionel Sambuc   }
1447*0a6a1f1dSLionel Sambuc 
1448*0a6a1f1dSLionel Sambuc   // Parse the class body after the enum's ";" if any.
1449*0a6a1f1dSLionel Sambuc   parseLevel(/*HasOpeningBrace=*/true);
1450*0a6a1f1dSLionel Sambuc   nextToken();
1451*0a6a1f1dSLionel Sambuc   --Line->Level;
1452*0a6a1f1dSLionel Sambuc   addUnwrappedLine();
1453*0a6a1f1dSLionel Sambuc }
1454*0a6a1f1dSLionel Sambuc 
parseRecord()1455*0a6a1f1dSLionel Sambuc void UnwrappedLineParser::parseRecord() {
1456*0a6a1f1dSLionel Sambuc   const FormatToken &InitialToken = *FormatTok;
1457*0a6a1f1dSLionel Sambuc   nextToken();
1458*0a6a1f1dSLionel Sambuc   if (FormatTok->isOneOf(tok::identifier, tok::coloncolon, tok::kw___attribute,
1459*0a6a1f1dSLionel Sambuc                          tok::kw___declspec, tok::kw_alignas)) {
1460f4a2713aSLionel Sambuc     nextToken();
1461f4a2713aSLionel Sambuc     // We can have macros or attributes in between 'class' and the class name.
1462f4a2713aSLionel Sambuc     if (FormatTok->Tok.is(tok::l_paren)) {
1463f4a2713aSLionel Sambuc       parseParens();
1464f4a2713aSLionel Sambuc     }
1465f4a2713aSLionel Sambuc     // The actual identifier can be a nested name specifier, and in macros
1466f4a2713aSLionel Sambuc     // it is often token-pasted.
1467*0a6a1f1dSLionel Sambuc     while (FormatTok->is(tok::identifier) || FormatTok->is(tok::coloncolon) ||
1468*0a6a1f1dSLionel Sambuc            FormatTok->is(tok::hashhash) ||
1469*0a6a1f1dSLionel Sambuc            (Style.Language == FormatStyle::LK_Java &&
1470*0a6a1f1dSLionel Sambuc             FormatTok->isOneOf(tok::period, tok::comma)))
1471f4a2713aSLionel Sambuc       nextToken();
1472f4a2713aSLionel Sambuc 
1473f4a2713aSLionel Sambuc     // Note that parsing away template declarations here leads to incorrectly
1474f4a2713aSLionel Sambuc     // accepting function declarations as record declarations.
1475f4a2713aSLionel Sambuc     // In general, we cannot solve this problem. Consider:
1476f4a2713aSLionel Sambuc     // class A<int> B() {}
1477f4a2713aSLionel Sambuc     // which can be a function definition or a class definition when B() is a
1478f4a2713aSLionel Sambuc     // macro. If we find enough real-world cases where this is a problem, we
1479f4a2713aSLionel Sambuc     // can parse for the 'template' keyword in the beginning of the statement,
1480f4a2713aSLionel Sambuc     // and thus rule out the record production in case there is no template
1481f4a2713aSLionel Sambuc     // (this would still leave us with an ambiguity between template function
1482f4a2713aSLionel Sambuc     // and class declarations).
1483f4a2713aSLionel Sambuc     if (FormatTok->Tok.is(tok::colon) || FormatTok->Tok.is(tok::less)) {
1484f4a2713aSLionel Sambuc       while (!eof() && FormatTok->Tok.isNot(tok::l_brace)) {
1485f4a2713aSLionel Sambuc         if (FormatTok->Tok.is(tok::semi))
1486f4a2713aSLionel Sambuc           return;
1487f4a2713aSLionel Sambuc         nextToken();
1488f4a2713aSLionel Sambuc       }
1489f4a2713aSLionel Sambuc     }
1490f4a2713aSLionel Sambuc   }
1491f4a2713aSLionel Sambuc   if (FormatTok->Tok.is(tok::l_brace)) {
1492*0a6a1f1dSLionel Sambuc     if (ShouldBreakBeforeBrace(Style, InitialToken))
1493f4a2713aSLionel Sambuc       addUnwrappedLine();
1494f4a2713aSLionel Sambuc 
1495*0a6a1f1dSLionel Sambuc     parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/true,
1496f4a2713aSLionel Sambuc                /*MunchSemi=*/false);
1497f4a2713aSLionel Sambuc   }
1498f4a2713aSLionel Sambuc   // We fall through to parsing a structural element afterwards, so
1499f4a2713aSLionel Sambuc   // class A {} n, m;
1500f4a2713aSLionel Sambuc   // will end up in one unwrapped line.
1501*0a6a1f1dSLionel Sambuc   // This does not apply for Java.
1502*0a6a1f1dSLionel Sambuc   if (Style.Language == FormatStyle::LK_Java)
1503*0a6a1f1dSLionel Sambuc     addUnwrappedLine();
1504f4a2713aSLionel Sambuc }
1505f4a2713aSLionel Sambuc 
parseObjCProtocolList()1506f4a2713aSLionel Sambuc void UnwrappedLineParser::parseObjCProtocolList() {
1507f4a2713aSLionel Sambuc   assert(FormatTok->Tok.is(tok::less) && "'<' expected.");
1508f4a2713aSLionel Sambuc   do
1509f4a2713aSLionel Sambuc     nextToken();
1510f4a2713aSLionel Sambuc   while (!eof() && FormatTok->Tok.isNot(tok::greater));
1511f4a2713aSLionel Sambuc   nextToken(); // Skip '>'.
1512f4a2713aSLionel Sambuc }
1513f4a2713aSLionel Sambuc 
parseObjCUntilAtEnd()1514f4a2713aSLionel Sambuc void UnwrappedLineParser::parseObjCUntilAtEnd() {
1515f4a2713aSLionel Sambuc   do {
1516f4a2713aSLionel Sambuc     if (FormatTok->Tok.isObjCAtKeyword(tok::objc_end)) {
1517f4a2713aSLionel Sambuc       nextToken();
1518f4a2713aSLionel Sambuc       addUnwrappedLine();
1519f4a2713aSLionel Sambuc       break;
1520f4a2713aSLionel Sambuc     }
1521f4a2713aSLionel Sambuc     if (FormatTok->is(tok::l_brace)) {
1522f4a2713aSLionel Sambuc       parseBlock(/*MustBeDeclaration=*/false);
1523f4a2713aSLionel Sambuc       // In ObjC interfaces, nothing should be following the "}".
1524f4a2713aSLionel Sambuc       addUnwrappedLine();
1525*0a6a1f1dSLionel Sambuc     } else if (FormatTok->is(tok::r_brace)) {
1526*0a6a1f1dSLionel Sambuc       // Ignore stray "}". parseStructuralElement doesn't consume them.
1527*0a6a1f1dSLionel Sambuc       nextToken();
1528*0a6a1f1dSLionel Sambuc       addUnwrappedLine();
1529f4a2713aSLionel Sambuc     } else {
1530f4a2713aSLionel Sambuc       parseStructuralElement();
1531f4a2713aSLionel Sambuc     }
1532f4a2713aSLionel Sambuc   } while (!eof());
1533f4a2713aSLionel Sambuc }
1534f4a2713aSLionel Sambuc 
parseObjCInterfaceOrImplementation()1535f4a2713aSLionel Sambuc void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
1536f4a2713aSLionel Sambuc   nextToken();
1537f4a2713aSLionel Sambuc   nextToken(); // interface name
1538f4a2713aSLionel Sambuc 
1539f4a2713aSLionel Sambuc   // @interface can be followed by either a base class, or a category.
1540f4a2713aSLionel Sambuc   if (FormatTok->Tok.is(tok::colon)) {
1541f4a2713aSLionel Sambuc     nextToken();
1542f4a2713aSLionel Sambuc     nextToken(); // base class name
1543f4a2713aSLionel Sambuc   } else if (FormatTok->Tok.is(tok::l_paren))
1544f4a2713aSLionel Sambuc     // Skip category, if present.
1545f4a2713aSLionel Sambuc     parseParens();
1546f4a2713aSLionel Sambuc 
1547f4a2713aSLionel Sambuc   if (FormatTok->Tok.is(tok::less))
1548f4a2713aSLionel Sambuc     parseObjCProtocolList();
1549f4a2713aSLionel Sambuc 
1550*0a6a1f1dSLionel Sambuc   if (FormatTok->Tok.is(tok::l_brace)) {
1551*0a6a1f1dSLionel Sambuc     if (Style.BreakBeforeBraces == FormatStyle::BS_Allman ||
1552*0a6a1f1dSLionel Sambuc         Style.BreakBeforeBraces == FormatStyle::BS_GNU)
1553*0a6a1f1dSLionel Sambuc       addUnwrappedLine();
1554f4a2713aSLionel Sambuc     parseBlock(/*MustBeDeclaration=*/true);
1555*0a6a1f1dSLionel Sambuc   }
1556f4a2713aSLionel Sambuc 
1557f4a2713aSLionel Sambuc   // With instance variables, this puts '}' on its own line.  Without instance
1558f4a2713aSLionel Sambuc   // variables, this ends the @interface line.
1559f4a2713aSLionel Sambuc   addUnwrappedLine();
1560f4a2713aSLionel Sambuc 
1561f4a2713aSLionel Sambuc   parseObjCUntilAtEnd();
1562f4a2713aSLionel Sambuc }
1563f4a2713aSLionel Sambuc 
parseObjCProtocol()1564f4a2713aSLionel Sambuc void UnwrappedLineParser::parseObjCProtocol() {
1565f4a2713aSLionel Sambuc   nextToken();
1566f4a2713aSLionel Sambuc   nextToken(); // protocol name
1567f4a2713aSLionel Sambuc 
1568f4a2713aSLionel Sambuc   if (FormatTok->Tok.is(tok::less))
1569f4a2713aSLionel Sambuc     parseObjCProtocolList();
1570f4a2713aSLionel Sambuc 
1571f4a2713aSLionel Sambuc   // Check for protocol declaration.
1572f4a2713aSLionel Sambuc   if (FormatTok->Tok.is(tok::semi)) {
1573f4a2713aSLionel Sambuc     nextToken();
1574f4a2713aSLionel Sambuc     return addUnwrappedLine();
1575f4a2713aSLionel Sambuc   }
1576f4a2713aSLionel Sambuc 
1577f4a2713aSLionel Sambuc   addUnwrappedLine();
1578f4a2713aSLionel Sambuc   parseObjCUntilAtEnd();
1579f4a2713aSLionel Sambuc }
1580f4a2713aSLionel Sambuc 
printDebugInfo(const UnwrappedLine & Line,StringRef Prefix="")1581f4a2713aSLionel Sambuc LLVM_ATTRIBUTE_UNUSED static void printDebugInfo(const UnwrappedLine &Line,
1582f4a2713aSLionel Sambuc                                                  StringRef Prefix = "") {
1583f4a2713aSLionel Sambuc   llvm::dbgs() << Prefix << "Line(" << Line.Level << ")"
1584f4a2713aSLionel Sambuc                << (Line.InPPDirective ? " MACRO" : "") << ": ";
1585f4a2713aSLionel Sambuc   for (std::list<UnwrappedLineNode>::const_iterator I = Line.Tokens.begin(),
1586f4a2713aSLionel Sambuc                                                     E = Line.Tokens.end();
1587f4a2713aSLionel Sambuc        I != E; ++I) {
1588f4a2713aSLionel Sambuc     llvm::dbgs() << I->Tok->Tok.getName() << "[" << I->Tok->Type << "] ";
1589f4a2713aSLionel Sambuc   }
1590f4a2713aSLionel Sambuc   for (std::list<UnwrappedLineNode>::const_iterator I = Line.Tokens.begin(),
1591f4a2713aSLionel Sambuc                                                     E = Line.Tokens.end();
1592f4a2713aSLionel Sambuc        I != E; ++I) {
1593f4a2713aSLionel Sambuc     const UnwrappedLineNode &Node = *I;
1594f4a2713aSLionel Sambuc     for (SmallVectorImpl<UnwrappedLine>::const_iterator
1595f4a2713aSLionel Sambuc              I = Node.Children.begin(),
1596f4a2713aSLionel Sambuc              E = Node.Children.end();
1597f4a2713aSLionel Sambuc          I != E; ++I) {
1598f4a2713aSLionel Sambuc       printDebugInfo(*I, "\nChild: ");
1599f4a2713aSLionel Sambuc     }
1600f4a2713aSLionel Sambuc   }
1601f4a2713aSLionel Sambuc   llvm::dbgs() << "\n";
1602f4a2713aSLionel Sambuc }
1603f4a2713aSLionel Sambuc 
addUnwrappedLine()1604f4a2713aSLionel Sambuc void UnwrappedLineParser::addUnwrappedLine() {
1605f4a2713aSLionel Sambuc   if (Line->Tokens.empty())
1606f4a2713aSLionel Sambuc     return;
1607f4a2713aSLionel Sambuc   DEBUG({
1608f4a2713aSLionel Sambuc     if (CurrentLines == &Lines)
1609f4a2713aSLionel Sambuc       printDebugInfo(*Line);
1610f4a2713aSLionel Sambuc   });
1611f4a2713aSLionel Sambuc   CurrentLines->push_back(*Line);
1612f4a2713aSLionel Sambuc   Line->Tokens.clear();
1613f4a2713aSLionel Sambuc   if (CurrentLines == &Lines && !PreprocessorDirectives.empty()) {
1614f4a2713aSLionel Sambuc     for (SmallVectorImpl<UnwrappedLine>::iterator
1615f4a2713aSLionel Sambuc              I = PreprocessorDirectives.begin(),
1616f4a2713aSLionel Sambuc              E = PreprocessorDirectives.end();
1617f4a2713aSLionel Sambuc          I != E; ++I) {
1618f4a2713aSLionel Sambuc       CurrentLines->push_back(*I);
1619f4a2713aSLionel Sambuc     }
1620f4a2713aSLionel Sambuc     PreprocessorDirectives.clear();
1621f4a2713aSLionel Sambuc   }
1622f4a2713aSLionel Sambuc }
1623f4a2713aSLionel Sambuc 
eof() const1624f4a2713aSLionel Sambuc bool UnwrappedLineParser::eof() const { return FormatTok->Tok.is(tok::eof); }
1625f4a2713aSLionel Sambuc 
isOnNewLine(const FormatToken & FormatTok)1626*0a6a1f1dSLionel Sambuc bool UnwrappedLineParser::isOnNewLine(const FormatToken &FormatTok) {
1627*0a6a1f1dSLionel Sambuc   return (Line->InPPDirective || FormatTok.HasUnescapedNewline) &&
1628*0a6a1f1dSLionel Sambuc          FormatTok.NewlinesBefore > 0;
1629*0a6a1f1dSLionel Sambuc }
1630*0a6a1f1dSLionel Sambuc 
flushComments(bool NewlineBeforeNext)1631f4a2713aSLionel Sambuc void UnwrappedLineParser::flushComments(bool NewlineBeforeNext) {
1632f4a2713aSLionel Sambuc   bool JustComments = Line->Tokens.empty();
1633f4a2713aSLionel Sambuc   for (SmallVectorImpl<FormatToken *>::const_iterator
1634f4a2713aSLionel Sambuc            I = CommentsBeforeNextToken.begin(),
1635f4a2713aSLionel Sambuc            E = CommentsBeforeNextToken.end();
1636f4a2713aSLionel Sambuc        I != E; ++I) {
1637*0a6a1f1dSLionel Sambuc     if (isOnNewLine(**I) && JustComments) {
1638f4a2713aSLionel Sambuc       addUnwrappedLine();
1639f4a2713aSLionel Sambuc     }
1640f4a2713aSLionel Sambuc     pushToken(*I);
1641f4a2713aSLionel Sambuc   }
1642f4a2713aSLionel Sambuc   if (NewlineBeforeNext && JustComments) {
1643f4a2713aSLionel Sambuc     addUnwrappedLine();
1644f4a2713aSLionel Sambuc   }
1645f4a2713aSLionel Sambuc   CommentsBeforeNextToken.clear();
1646f4a2713aSLionel Sambuc }
1647f4a2713aSLionel Sambuc 
nextToken()1648f4a2713aSLionel Sambuc void UnwrappedLineParser::nextToken() {
1649f4a2713aSLionel Sambuc   if (eof())
1650f4a2713aSLionel Sambuc     return;
1651*0a6a1f1dSLionel Sambuc   flushComments(isOnNewLine(*FormatTok));
1652f4a2713aSLionel Sambuc   pushToken(FormatTok);
1653f4a2713aSLionel Sambuc   readToken();
1654f4a2713aSLionel Sambuc }
1655f4a2713aSLionel Sambuc 
readToken()1656f4a2713aSLionel Sambuc void UnwrappedLineParser::readToken() {
1657f4a2713aSLionel Sambuc   bool CommentsInCurrentLine = true;
1658f4a2713aSLionel Sambuc   do {
1659f4a2713aSLionel Sambuc     FormatTok = Tokens->getNextToken();
1660*0a6a1f1dSLionel Sambuc     assert(FormatTok);
1661f4a2713aSLionel Sambuc     while (!Line->InPPDirective && FormatTok->Tok.is(tok::hash) &&
1662f4a2713aSLionel Sambuc            (FormatTok->HasUnescapedNewline || FormatTok->IsFirst)) {
1663f4a2713aSLionel Sambuc       // If there is an unfinished unwrapped line, we flush the preprocessor
1664f4a2713aSLionel Sambuc       // directives only after that unwrapped line was finished later.
1665f4a2713aSLionel Sambuc       bool SwitchToPreprocessorLines =
1666f4a2713aSLionel Sambuc           !Line->Tokens.empty() && CurrentLines == &Lines;
1667f4a2713aSLionel Sambuc       ScopedLineState BlockState(*this, SwitchToPreprocessorLines);
1668f4a2713aSLionel Sambuc       // Comments stored before the preprocessor directive need to be output
1669f4a2713aSLionel Sambuc       // before the preprocessor directive, at the same level as the
1670f4a2713aSLionel Sambuc       // preprocessor directive, as we consider them to apply to the directive.
1671*0a6a1f1dSLionel Sambuc       flushComments(isOnNewLine(*FormatTok));
1672f4a2713aSLionel Sambuc       parsePPDirective();
1673f4a2713aSLionel Sambuc     }
1674*0a6a1f1dSLionel Sambuc     while (FormatTok->Type == TT_ConflictStart ||
1675*0a6a1f1dSLionel Sambuc            FormatTok->Type == TT_ConflictEnd ||
1676*0a6a1f1dSLionel Sambuc            FormatTok->Type == TT_ConflictAlternative) {
1677*0a6a1f1dSLionel Sambuc       if (FormatTok->Type == TT_ConflictStart) {
1678*0a6a1f1dSLionel Sambuc         conditionalCompilationStart(/*Unreachable=*/false);
1679*0a6a1f1dSLionel Sambuc       } else if (FormatTok->Type == TT_ConflictAlternative) {
1680*0a6a1f1dSLionel Sambuc         conditionalCompilationAlternative();
1681*0a6a1f1dSLionel Sambuc       } else if (FormatTok->Type == TT_ConflictEnd) {
1682*0a6a1f1dSLionel Sambuc         conditionalCompilationEnd();
1683*0a6a1f1dSLionel Sambuc       }
1684*0a6a1f1dSLionel Sambuc       FormatTok = Tokens->getNextToken();
1685*0a6a1f1dSLionel Sambuc       FormatTok->MustBreakBefore = true;
1686*0a6a1f1dSLionel Sambuc     }
1687f4a2713aSLionel Sambuc 
1688f4a2713aSLionel Sambuc     if (!PPStack.empty() && (PPStack.back() == PP_Unreachable) &&
1689f4a2713aSLionel Sambuc         !Line->InPPDirective) {
1690f4a2713aSLionel Sambuc       continue;
1691f4a2713aSLionel Sambuc     }
1692f4a2713aSLionel Sambuc 
1693f4a2713aSLionel Sambuc     if (!FormatTok->Tok.is(tok::comment))
1694f4a2713aSLionel Sambuc       return;
1695*0a6a1f1dSLionel Sambuc     if (isOnNewLine(*FormatTok) || FormatTok->IsFirst) {
1696f4a2713aSLionel Sambuc       CommentsInCurrentLine = false;
1697f4a2713aSLionel Sambuc     }
1698f4a2713aSLionel Sambuc     if (CommentsInCurrentLine) {
1699f4a2713aSLionel Sambuc       pushToken(FormatTok);
1700f4a2713aSLionel Sambuc     } else {
1701f4a2713aSLionel Sambuc       CommentsBeforeNextToken.push_back(FormatTok);
1702f4a2713aSLionel Sambuc     }
1703f4a2713aSLionel Sambuc   } while (!eof());
1704f4a2713aSLionel Sambuc }
1705f4a2713aSLionel Sambuc 
pushToken(FormatToken * Tok)1706f4a2713aSLionel Sambuc void UnwrappedLineParser::pushToken(FormatToken *Tok) {
1707f4a2713aSLionel Sambuc   Line->Tokens.push_back(UnwrappedLineNode(Tok));
1708f4a2713aSLionel Sambuc   if (MustBreakBeforeNextToken) {
1709f4a2713aSLionel Sambuc     Line->Tokens.back().Tok->MustBreakBefore = true;
1710f4a2713aSLionel Sambuc     MustBreakBeforeNextToken = false;
1711f4a2713aSLionel Sambuc   }
1712f4a2713aSLionel Sambuc }
1713f4a2713aSLionel Sambuc 
1714f4a2713aSLionel Sambuc } // end namespace format
1715f4a2713aSLionel Sambuc } // end namespace clang
1716