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