blob: 2bcb2d496523c281161bdc8074ae4848fabb893a [file] [log] [blame]
Daniel Jasperf7935112012-12-03 18:12:45 +00001//===--- UnwrappedLineParser.cpp - Format C++ code ------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file
11/// \brief This file contains the implementation of the UnwrappedLineParser,
12/// which turns a stream of tokens into UnwrappedLines.
13///
Daniel Jasperf7935112012-12-03 18:12:45 +000014//===----------------------------------------------------------------------===//
15
Chandler Carruth4b417452013-01-19 08:09:44 +000016#include "UnwrappedLineParser.h"
Benjamin Kramer33335df2015-03-01 21:36:40 +000017#include "llvm/ADT/STLExtras.h"
Manuel Klimekab3dc002013-01-16 12:31:12 +000018#include "llvm/Support/Debug.h"
Benjamin Kramer53f5e892015-03-23 18:05:43 +000019#include "llvm/Support/raw_ostream.h"
Manuel Klimekab3dc002013-01-16 12:31:12 +000020
Chandler Carruth10346662014-04-22 03:17:02 +000021#define DEBUG_TYPE "format-parser"
22
Daniel Jasperf7935112012-12-03 18:12:45 +000023namespace clang {
24namespace format {
25
Manuel Klimek15dfe7a2013-05-28 11:55:06 +000026class FormatTokenSource {
27public:
Angel Garcia Gomez637d1e62015-10-20 13:23:58 +000028 virtual ~FormatTokenSource() {}
Manuel Klimek15dfe7a2013-05-28 11:55:06 +000029 virtual FormatToken *getNextToken() = 0;
30
31 virtual unsigned getPosition() = 0;
32 virtual FormatToken *setPosition(unsigned Position) = 0;
33};
34
Craig Topper69665e12013-07-01 04:21:54 +000035namespace {
36
Manuel Klimek0a3a3c92013-01-23 09:32:48 +000037class ScopedDeclarationState {
38public:
39 ScopedDeclarationState(UnwrappedLine &Line, std::vector<bool> &Stack,
40 bool MustBeDeclaration)
41 : Line(Line), Stack(Stack) {
Manuel Klimek0a3a3c92013-01-23 09:32:48 +000042 Line.MustBeDeclaration = MustBeDeclaration;
Manuel Klimek39080572013-01-23 11:03:04 +000043 Stack.push_back(MustBeDeclaration);
Manuel Klimek0a3a3c92013-01-23 09:32:48 +000044 }
45 ~ScopedDeclarationState() {
Manuel Klimek0a3a3c92013-01-23 09:32:48 +000046 Stack.pop_back();
Manuel Klimekc1237a82013-01-23 14:08:21 +000047 if (!Stack.empty())
48 Line.MustBeDeclaration = Stack.back();
49 else
50 Line.MustBeDeclaration = true;
Manuel Klimek0a3a3c92013-01-23 09:32:48 +000051 }
Daniel Jasper393564f2013-05-31 14:56:29 +000052
Manuel Klimek0a3a3c92013-01-23 09:32:48 +000053private:
54 UnwrappedLine &Line;
55 std::vector<bool> &Stack;
56};
57
Krasimir Georgieva1c30932017-05-19 10:34:57 +000058static bool isLineComment(const FormatToken &FormatTok) {
59 return FormatTok.is(tok::comment) &&
60 FormatTok.TokenText.startswith("//");
61}
62
Manuel Klimek1abf7892013-01-04 23:34:14 +000063class ScopedMacroState : public FormatTokenSource {
64public:
65 ScopedMacroState(UnwrappedLine &Line, FormatTokenSource *&TokenSource,
Manuel Klimek20e0af62015-05-06 11:56:29 +000066 FormatToken *&ResetToken)
Manuel Klimek1abf7892013-01-04 23:34:14 +000067 : Line(Line), TokenSource(TokenSource), ResetToken(ResetToken),
Manuel Klimek1a18c402013-04-12 14:13:36 +000068 PreviousLineLevel(Line.Level), PreviousTokenSource(TokenSource),
Krasimir Georgieva1c30932017-05-19 10:34:57 +000069 Token(nullptr), PreviousToken(nullptr) {
Manuel Klimek1abf7892013-01-04 23:34:14 +000070 TokenSource = this;
Manuel Klimekef2cfb12013-01-05 22:14:16 +000071 Line.Level = 0;
Manuel Klimek1abf7892013-01-04 23:34:14 +000072 Line.InPPDirective = true;
73 }
74
Alexander Kornienko34eb2072015-04-11 02:00:23 +000075 ~ScopedMacroState() override {
Manuel Klimek1abf7892013-01-04 23:34:14 +000076 TokenSource = PreviousTokenSource;
77 ResetToken = Token;
78 Line.InPPDirective = false;
Manuel Klimekef2cfb12013-01-05 22:14:16 +000079 Line.Level = PreviousLineLevel;
Manuel Klimek1abf7892013-01-04 23:34:14 +000080 }
81
Craig Topperfb6b25b2014-03-15 04:29:04 +000082 FormatToken *getNextToken() override {
Manuel Klimek78725712013-01-07 10:03:37 +000083 // The \c UnwrappedLineParser guards against this by never calling
84 // \c getNextToken() after it has encountered the first eof token.
85 assert(!eof());
Krasimir Georgieva1c30932017-05-19 10:34:57 +000086 PreviousToken = Token;
Manuel Klimek1abf7892013-01-04 23:34:14 +000087 Token = PreviousTokenSource->getNextToken();
88 if (eof())
Manuel Klimek15dfe7a2013-05-28 11:55:06 +000089 return getFakeEOF();
Manuel Klimek1abf7892013-01-04 23:34:14 +000090 return Token;
91 }
92
Craig Topperfb6b25b2014-03-15 04:29:04 +000093 unsigned getPosition() override { return PreviousTokenSource->getPosition(); }
Manuel Klimekab419912013-05-23 09:41:43 +000094
Craig Topperfb6b25b2014-03-15 04:29:04 +000095 FormatToken *setPosition(unsigned Position) override {
Krasimir Georgieva1c30932017-05-19 10:34:57 +000096 PreviousToken = nullptr;
Manuel Klimekab419912013-05-23 09:41:43 +000097 Token = PreviousTokenSource->setPosition(Position);
98 return Token;
99 }
100
Manuel Klimek1abf7892013-01-04 23:34:14 +0000101private:
Krasimir Georgieva1c30932017-05-19 10:34:57 +0000102 bool eof() {
103 return Token && Token->HasUnescapedNewline &&
104 !(PreviousToken && isLineComment(*PreviousToken) &&
105 isLineComment(*Token) && Token->NewlinesBefore == 1);
106 }
Manuel Klimek1abf7892013-01-04 23:34:14 +0000107
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000108 FormatToken *getFakeEOF() {
109 static bool EOFInitialized = false;
110 static FormatToken FormatTok;
111 if (!EOFInitialized) {
112 FormatTok.Tok.startToken();
113 FormatTok.Tok.setKind(tok::eof);
114 EOFInitialized = true;
115 }
116 return &FormatTok;
Manuel Klimek1abf7892013-01-04 23:34:14 +0000117 }
118
119 UnwrappedLine &Line;
120 FormatTokenSource *&TokenSource;
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000121 FormatToken *&ResetToken;
Manuel Klimekef2cfb12013-01-05 22:14:16 +0000122 unsigned PreviousLineLevel;
Manuel Klimek1abf7892013-01-04 23:34:14 +0000123 FormatTokenSource *PreviousTokenSource;
124
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000125 FormatToken *Token;
Krasimir Georgieva1c30932017-05-19 10:34:57 +0000126 FormatToken *PreviousToken;
Manuel Klimek1abf7892013-01-04 23:34:14 +0000127};
128
Craig Topper69665e12013-07-01 04:21:54 +0000129} // end anonymous namespace
130
Manuel Klimek8e07a1b2013-01-10 11:52:21 +0000131class ScopedLineState {
132public:
Manuel Klimekd3b92fa2013-01-18 14:04:34 +0000133 ScopedLineState(UnwrappedLineParser &Parser,
134 bool SwitchToPreprocessorLines = false)
David Blaikieefb6eb22014-08-09 20:02:07 +0000135 : Parser(Parser), OriginalLines(Parser.CurrentLines) {
Manuel Klimekd3b92fa2013-01-18 14:04:34 +0000136 if (SwitchToPreprocessorLines)
137 Parser.CurrentLines = &Parser.PreprocessorDirectives;
Daniel Jasper9fe0e8d2013-09-05 09:29:45 +0000138 else if (!Parser.Line->Tokens.empty())
139 Parser.CurrentLines = &Parser.Line->Tokens.back().Children;
David Blaikieefb6eb22014-08-09 20:02:07 +0000140 PreBlockLine = std::move(Parser.Line);
141 Parser.Line = llvm::make_unique<UnwrappedLine>();
Daniel Jasperdaffc0d2013-01-16 09:10:19 +0000142 Parser.Line->Level = PreBlockLine->Level;
143 Parser.Line->InPPDirective = PreBlockLine->InPPDirective;
Manuel Klimek8e07a1b2013-01-10 11:52:21 +0000144 }
145
146 ~ScopedLineState() {
Daniel Jasperdaffc0d2013-01-16 09:10:19 +0000147 if (!Parser.Line->Tokens.empty()) {
Manuel Klimek8e07a1b2013-01-10 11:52:21 +0000148 Parser.addUnwrappedLine();
149 }
Daniel Jasperdaffc0d2013-01-16 09:10:19 +0000150 assert(Parser.Line->Tokens.empty());
David Blaikieefb6eb22014-08-09 20:02:07 +0000151 Parser.Line = std::move(PreBlockLine);
Daniel Jasper9fe0e8d2013-09-05 09:29:45 +0000152 if (Parser.CurrentLines == &Parser.PreprocessorDirectives)
153 Parser.MustBreakBeforeNextToken = true;
154 Parser.CurrentLines = OriginalLines;
Manuel Klimek8e07a1b2013-01-10 11:52:21 +0000155 }
156
157private:
158 UnwrappedLineParser &Parser;
159
David Blaikieefb6eb22014-08-09 20:02:07 +0000160 std::unique_ptr<UnwrappedLine> PreBlockLine;
Daniel Jasper9fe0e8d2013-09-05 09:29:45 +0000161 SmallVectorImpl<UnwrappedLine> *OriginalLines;
Manuel Klimek8e07a1b2013-01-10 11:52:21 +0000162};
163
Alexander Kornienko3a33f022013-12-12 09:49:52 +0000164class CompoundStatementIndenter {
165public:
166 CompoundStatementIndenter(UnwrappedLineParser *Parser,
167 const FormatStyle &Style, unsigned &LineLevel)
168 : LineLevel(LineLevel), OldLineLevel(LineLevel) {
Daniel Jasperc1bc38e2015-09-29 14:57:55 +0000169 if (Style.BraceWrapping.AfterControlStatement)
Alexander Kornienko3a33f022013-12-12 09:49:52 +0000170 Parser->addUnwrappedLine();
Daniel Jasperc1bc38e2015-09-29 14:57:55 +0000171 if (Style.BraceWrapping.IndentBraces)
Alexander Kornienko3a33f022013-12-12 09:49:52 +0000172 ++LineLevel;
Alexander Kornienko3a33f022013-12-12 09:49:52 +0000173 }
Daniel Jasperb05a81d2014-05-09 13:11:16 +0000174 ~CompoundStatementIndenter() { LineLevel = OldLineLevel; }
Alexander Kornienko3a33f022013-12-12 09:49:52 +0000175
176private:
177 unsigned &LineLevel;
178 unsigned OldLineLevel;
179};
180
Craig Topper69665e12013-07-01 04:21:54 +0000181namespace {
182
Manuel Klimekab419912013-05-23 09:41:43 +0000183class IndexedTokenSource : public FormatTokenSource {
184public:
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000185 IndexedTokenSource(ArrayRef<FormatToken *> Tokens)
Manuel Klimekab419912013-05-23 09:41:43 +0000186 : Tokens(Tokens), Position(-1) {}
187
Craig Topperfb6b25b2014-03-15 04:29:04 +0000188 FormatToken *getNextToken() override {
Manuel Klimekab419912013-05-23 09:41:43 +0000189 ++Position;
190 return Tokens[Position];
191 }
192
Craig Topperfb6b25b2014-03-15 04:29:04 +0000193 unsigned getPosition() override {
Manuel Klimekab419912013-05-23 09:41:43 +0000194 assert(Position >= 0);
195 return Position;
196 }
197
Craig Topperfb6b25b2014-03-15 04:29:04 +0000198 FormatToken *setPosition(unsigned P) override {
Manuel Klimekab419912013-05-23 09:41:43 +0000199 Position = P;
200 return Tokens[Position];
201 }
202
Manuel Klimek71814b42013-10-11 21:25:45 +0000203 void reset() { Position = -1; }
204
Manuel Klimekab419912013-05-23 09:41:43 +0000205private:
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000206 ArrayRef<FormatToken *> Tokens;
Manuel Klimekab419912013-05-23 09:41:43 +0000207 int Position;
208};
209
Craig Topper69665e12013-07-01 04:21:54 +0000210} // end anonymous namespace
211
Daniel Jasperd2ae41a2013-05-15 08:14:19 +0000212UnwrappedLineParser::UnwrappedLineParser(const FormatStyle &Style,
Daniel Jasperd0ec0d62014-11-04 12:41:02 +0000213 const AdditionalKeywords &Keywords,
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000214 ArrayRef<FormatToken *> Tokens,
Daniel Jasperd2ae41a2013-05-15 08:14:19 +0000215 UnwrappedLineConsumer &Callback)
Daniel Jasperb05a81d2014-05-09 13:11:16 +0000216 : Line(new UnwrappedLine), MustBreakBeforeNextToken(false),
Krasimir Georgiev00c5c722017-02-02 15:32:19 +0000217 CurrentLines(&Lines), Style(Style), Keywords(Keywords),
218 CommentPragmasRegex(Style.CommentPragmas), Tokens(nullptr),
Manuel Klimek20e0af62015-05-06 11:56:29 +0000219 Callback(Callback), AllTokens(Tokens), PPBranchLevel(-1) {}
Manuel Klimek71814b42013-10-11 21:25:45 +0000220
221void UnwrappedLineParser::reset() {
222 PPBranchLevel = -1;
223 Line.reset(new UnwrappedLine);
224 CommentsBeforeNextToken.clear();
Craig Topper2145bc02014-05-09 08:15:10 +0000225 FormatTok = nullptr;
Manuel Klimek71814b42013-10-11 21:25:45 +0000226 MustBreakBeforeNextToken = false;
227 PreprocessorDirectives.clear();
228 CurrentLines = &Lines;
229 DeclarationScopeStack.clear();
Manuel Klimek71814b42013-10-11 21:25:45 +0000230 PPStack.clear();
231}
Daniel Jasperf7935112012-12-03 18:12:45 +0000232
Manuel Klimek20e0af62015-05-06 11:56:29 +0000233void UnwrappedLineParser::parse() {
Manuel Klimekab419912013-05-23 09:41:43 +0000234 IndexedTokenSource TokenSource(AllTokens);
Manuel Klimek71814b42013-10-11 21:25:45 +0000235 do {
236 DEBUG(llvm::dbgs() << "----\n");
237 reset();
238 Tokens = &TokenSource;
239 TokenSource.reset();
Daniel Jaspera79064a2013-03-01 18:11:39 +0000240
Manuel Klimek71814b42013-10-11 21:25:45 +0000241 readToken();
242 parseFile();
243 // Create line with eof token.
244 pushToken(FormatTok);
245 addUnwrappedLine();
246
247 for (SmallVectorImpl<UnwrappedLine>::iterator I = Lines.begin(),
248 E = Lines.end();
249 I != E; ++I) {
250 Callback.consumeUnwrappedLine(*I);
251 }
252 Callback.finishRun();
253 Lines.clear();
254 while (!PPLevelBranchIndex.empty() &&
Daniel Jasper53bd1672013-10-12 13:32:56 +0000255 PPLevelBranchIndex.back() + 1 >= PPLevelBranchCount.back()) {
Manuel Klimek71814b42013-10-11 21:25:45 +0000256 PPLevelBranchIndex.resize(PPLevelBranchIndex.size() - 1);
257 PPLevelBranchCount.resize(PPLevelBranchCount.size() - 1);
258 }
259 if (!PPLevelBranchIndex.empty()) {
260 ++PPLevelBranchIndex.back();
261 assert(PPLevelBranchIndex.size() == PPLevelBranchCount.size());
262 assert(PPLevelBranchIndex.back() <= PPLevelBranchCount.back());
263 }
264 } while (!PPLevelBranchIndex.empty());
Manuel Klimek1abf7892013-01-04 23:34:14 +0000265}
266
Manuel Klimek1a18c402013-04-12 14:13:36 +0000267void UnwrappedLineParser::parseFile() {
Daniel Jasper9326f912015-05-05 08:40:32 +0000268 // The top-level context in a file always has declarations, except for pre-
269 // processor directives and JavaScript files.
270 bool MustBeDeclaration =
271 !Line->InPPDirective && Style.Language != FormatStyle::LK_JavaScript;
272 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
273 MustBeDeclaration);
Nico Weber9096fc02013-06-26 00:30:14 +0000274 parseLevel(/*HasOpeningBrace=*/false);
Manuel Klimek1abf7892013-01-04 23:34:14 +0000275 // Make sure to format the remaining tokens.
Manuel Klimekf92f7bc2013-01-22 16:31:55 +0000276 flushComments(true);
Manuel Klimek1abf7892013-01-04 23:34:14 +0000277 addUnwrappedLine();
Daniel Jasperf7935112012-12-03 18:12:45 +0000278}
279
Manuel Klimek1a18c402013-04-12 14:13:36 +0000280void UnwrappedLineParser::parseLevel(bool HasOpeningBrace) {
Daniel Jasper516d7972013-07-25 11:31:57 +0000281 bool SwitchLabelEncountered = false;
Daniel Jasperf7935112012-12-03 18:12:45 +0000282 do {
Birunthan Mohanathasb001a0b2015-07-03 17:25:16 +0000283 tok::TokenKind kind = FormatTok->Tok.getKind();
284 if (FormatTok->Type == TT_MacroBlockBegin) {
285 kind = tok::l_brace;
286 } else if (FormatTok->Type == TT_MacroBlockEnd) {
287 kind = tok::r_brace;
288 }
289
290 switch (kind) {
Daniel Jasperf7935112012-12-03 18:12:45 +0000291 case tok::comment:
Daniel Jaspere25509f2012-12-17 11:29:41 +0000292 nextToken();
293 addUnwrappedLine();
Daniel Jasperf7935112012-12-03 18:12:45 +0000294 break;
295 case tok::l_brace:
Manuel Klimek0a3a3c92013-01-23 09:32:48 +0000296 // FIXME: Add parameter whether this can happen - if this happens, we must
297 // be in a non-declaration context.
Daniel Jasperb86e2722015-08-24 13:23:37 +0000298 if (!FormatTok->is(TT_MacroBlockBegin) && tryToParseBracedList())
299 continue;
Nico Weber9096fc02013-06-26 00:30:14 +0000300 parseBlock(/*MustBeDeclaration=*/false);
Daniel Jasperf7935112012-12-03 18:12:45 +0000301 addUnwrappedLine();
302 break;
303 case tok::r_brace:
Manuel Klimek1a18c402013-04-12 14:13:36 +0000304 if (HasOpeningBrace)
305 return;
Manuel Klimek1a18c402013-04-12 14:13:36 +0000306 nextToken();
307 addUnwrappedLine();
Manuel Klimek1058d982013-01-06 20:07:31 +0000308 break;
Daniel Jasper516d7972013-07-25 11:31:57 +0000309 case tok::kw_default:
310 case tok::kw_case:
Daniel Jasper72407622013-09-02 08:26:29 +0000311 if (!SwitchLabelEncountered &&
312 (Style.IndentCaseLabels || (Line->InPPDirective && Line->Level == 1)))
313 ++Line->Level;
Daniel Jasper516d7972013-07-25 11:31:57 +0000314 SwitchLabelEncountered = true;
315 parseStructuralElement();
316 break;
Daniel Jasperf7935112012-12-03 18:12:45 +0000317 default:
Manuel Klimek6b9eeba2013-01-07 14:56:16 +0000318 parseStructuralElement();
Daniel Jasperf7935112012-12-03 18:12:45 +0000319 break;
320 }
321 } while (!eof());
322}
323
Daniel Jasperadba2aa2015-05-18 12:52:00 +0000324void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {
Manuel Klimekab419912013-05-23 09:41:43 +0000325 // We'll parse forward through the tokens until we hit
326 // a closing brace or eof - note that getNextToken() will
327 // parse macros, so this will magically work inside macro
328 // definitions, too.
329 unsigned StoredPosition = Tokens->getPosition();
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000330 FormatToken *Tok = FormatTok;
Daniel Jasperb9a49902016-01-09 15:56:28 +0000331 const FormatToken *PrevTok = getPreviousToken();
Manuel Klimekab419912013-05-23 09:41:43 +0000332 // Keep a stack of positions of lbrace tokens. We will
333 // update information about whether an lbrace starts a
334 // braced init list or a different block during the loop.
Daniel Jasperb1f74a82013-07-09 09:06:29 +0000335 SmallVector<FormatToken *, 8> LBraceStack;
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000336 assert(Tok->Tok.is(tok::l_brace));
Manuel Klimekab419912013-05-23 09:41:43 +0000337 do {
Daniel Jaspereb65e912015-12-21 18:31:15 +0000338 // Get next non-comment token.
Daniel Jasper7f5d53e2013-07-01 09:15:46 +0000339 FormatToken *NextTok;
Daniel Jasperca7bd722013-07-01 16:43:38 +0000340 unsigned ReadTokens = 0;
Daniel Jasper7f5d53e2013-07-01 09:15:46 +0000341 do {
342 NextTok = Tokens->getNextToken();
Daniel Jasperca7bd722013-07-01 16:43:38 +0000343 ++ReadTokens;
Daniel Jasper7f5d53e2013-07-01 09:15:46 +0000344 } while (NextTok->is(tok::comment));
345
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000346 switch (Tok->Tok.getKind()) {
Manuel Klimekab419912013-05-23 09:41:43 +0000347 case tok::l_brace:
Daniel Jasperb9a49902016-01-09 15:56:28 +0000348 if (Style.Language == FormatStyle::LK_JavaScript && PrevTok &&
349 PrevTok->is(tok::colon))
Martin Probst8e3eba02017-02-07 16:33:13 +0000350 // A colon indicates this code is in a type, or a braced list following
351 // a label in an object literal ({a: {b: 1}}).
352 // The code below could be confused by semicolons between the individual
353 // members in a type member list, which would normally trigger BK_Block.
354 // In both cases, this must be parsed as an inline braced init.
Daniel Jasperb9a49902016-01-09 15:56:28 +0000355 Tok->BlockKind = BK_BracedInit;
356 else
357 Tok->BlockKind = BK_Unknown;
Daniel Jasperb1f74a82013-07-09 09:06:29 +0000358 LBraceStack.push_back(Tok);
Manuel Klimekab419912013-05-23 09:41:43 +0000359 break;
360 case tok::r_brace:
Daniel Jasperb9a49902016-01-09 15:56:28 +0000361 if (LBraceStack.empty())
362 break;
363 if (LBraceStack.back()->BlockKind == BK_Unknown) {
364 bool ProbablyBracedList = false;
365 if (Style.Language == FormatStyle::LK_Proto) {
366 ProbablyBracedList = NextTok->isOneOf(tok::comma, tok::r_square);
367 } else {
368 // Using OriginalColumn to distinguish between ObjC methods and
369 // binary operators is a bit hacky.
370 bool NextIsObjCMethod = NextTok->isOneOf(tok::plus, tok::minus) &&
371 NextTok->OriginalColumn == 0;
Daniel Jasper91b032a2014-05-22 12:46:38 +0000372
Daniel Jasperb9a49902016-01-09 15:56:28 +0000373 // If there is a comma, semicolon or right paren after the closing
374 // brace, we assume this is a braced initializer list. Note that
375 // regardless how we mark inner braces here, we will overwrite the
376 // BlockKind later if we parse a braced list (where all blocks
377 // inside are by default braced lists), or when we explicitly detect
378 // blocks (for example while parsing lambdas).
Daniel Jasperb9a49902016-01-09 15:56:28 +0000379 ProbablyBracedList =
Daniel Jasperacffeb82016-03-05 18:34:26 +0000380 (Style.Language == FormatStyle::LK_JavaScript &&
Martin Probste1e12a72016-08-19 14:35:01 +0000381 NextTok->isOneOf(Keywords.kw_of, Keywords.kw_in,
382 Keywords.kw_as)) ||
Martin Probstb7fb2672017-05-10 13:53:29 +0000383 (Style.isCpp() && NextTok->is(tok::l_paren)) ||
Daniel Jasperb9a49902016-01-09 15:56:28 +0000384 NextTok->isOneOf(tok::comma, tok::period, tok::colon,
385 tok::r_paren, tok::r_square, tok::l_brace,
Martin Probstb7fb2672017-05-10 13:53:29 +0000386 tok::l_square, tok::ellipsis) ||
Daniel Jaspere4ada022016-12-13 10:05:03 +0000387 (NextTok->is(tok::identifier) &&
388 !PrevTok->isOneOf(tok::semi, tok::r_brace, tok::l_brace)) ||
Daniel Jasperb9a49902016-01-09 15:56:28 +0000389 (NextTok->is(tok::semi) &&
390 (!ExpectClassBody || LBraceStack.size() != 1)) ||
391 (NextTok->isBinaryOperator() && !NextIsObjCMethod);
Manuel Klimekab419912013-05-23 09:41:43 +0000392 }
Daniel Jasperb9a49902016-01-09 15:56:28 +0000393 if (ProbablyBracedList) {
394 Tok->BlockKind = BK_BracedInit;
395 LBraceStack.back()->BlockKind = BK_BracedInit;
396 } else {
397 Tok->BlockKind = BK_Block;
398 LBraceStack.back()->BlockKind = BK_Block;
399 }
Manuel Klimekab419912013-05-23 09:41:43 +0000400 }
Daniel Jasperb9a49902016-01-09 15:56:28 +0000401 LBraceStack.pop_back();
Manuel Klimekab419912013-05-23 09:41:43 +0000402 break;
Daniel Jasperac7e34e2014-03-13 10:11:17 +0000403 case tok::at:
Manuel Klimekab419912013-05-23 09:41:43 +0000404 case tok::semi:
405 case tok::kw_if:
406 case tok::kw_while:
407 case tok::kw_for:
408 case tok::kw_switch:
409 case tok::kw_try:
Nico Weberfac23712015-02-04 15:26:27 +0000410 case tok::kw___try:
Daniel Jasperb9a49902016-01-09 15:56:28 +0000411 if (!LBraceStack.empty() && LBraceStack.back()->BlockKind == BK_Unknown)
Daniel Jasperb1f74a82013-07-09 09:06:29 +0000412 LBraceStack.back()->BlockKind = BK_Block;
Manuel Klimekab419912013-05-23 09:41:43 +0000413 break;
414 default:
415 break;
416 }
Daniel Jasperb9a49902016-01-09 15:56:28 +0000417 PrevTok = Tok;
Manuel Klimekab419912013-05-23 09:41:43 +0000418 Tok = NextTok;
Manuel Klimekbab25fd2013-09-04 08:20:47 +0000419 } while (Tok->Tok.isNot(tok::eof) && !LBraceStack.empty());
Daniel Jasperb9a49902016-01-09 15:56:28 +0000420
Manuel Klimekab419912013-05-23 09:41:43 +0000421 // Assume other blocks for all unclosed opening braces.
422 for (unsigned i = 0, e = LBraceStack.size(); i != e; ++i) {
Daniel Jasperb1f74a82013-07-09 09:06:29 +0000423 if (LBraceStack[i]->BlockKind == BK_Unknown)
424 LBraceStack[i]->BlockKind = BK_Block;
Manuel Klimekab419912013-05-23 09:41:43 +0000425 }
Manuel Klimekbab25fd2013-09-04 08:20:47 +0000426
Manuel Klimekab419912013-05-23 09:41:43 +0000427 FormatTok = Tokens->setPosition(StoredPosition);
428}
429
Manuel Klimekb212f3b2013-10-12 22:46:56 +0000430void UnwrappedLineParser::parseBlock(bool MustBeDeclaration, bool AddLevel,
431 bool MunchSemi) {
Birunthan Mohanathasb001a0b2015-07-03 17:25:16 +0000432 assert(FormatTok->isOneOf(tok::l_brace, TT_MacroBlockBegin) &&
433 "'{' or macro block token expected");
434 const bool MacroBlock = FormatTok->is(TT_MacroBlockBegin);
Daniel Jaspereb65e912015-12-21 18:31:15 +0000435 FormatTok->BlockKind = BK_Block;
Birunthan Mohanathasb001a0b2015-07-03 17:25:16 +0000436
Daniel Jasper516d7972013-07-25 11:31:57 +0000437 unsigned InitialLevel = Line->Level;
Daniel Jasperf7935112012-12-03 18:12:45 +0000438 nextToken();
439
Birunthan Mohanathasb001a0b2015-07-03 17:25:16 +0000440 if (MacroBlock && FormatTok->is(tok::l_paren))
441 parseParens();
442
Manuel Klimeka4fe1c12013-01-21 16:42:44 +0000443 addUnwrappedLine();
Krasimir Georgiev9f5608a2017-05-18 15:16:24 +0000444 size_t OpeningLineIndex = CurrentLines->empty()
445 ? (UnwrappedLine::kInvalidIndex)
446 : (CurrentLines->size() - 1);
Daniel Jasperf7935112012-12-03 18:12:45 +0000447
Manuel Klimek0a3a3c92013-01-23 09:32:48 +0000448 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
449 MustBeDeclaration);
Daniel Jasper65ee3472013-07-31 23:16:02 +0000450 if (AddLevel)
451 ++Line->Level;
Nico Weber9096fc02013-06-26 00:30:14 +0000452 parseLevel(/*HasOpeningBrace=*/true);
Alexander Kornienko578fdd82012-12-06 18:03:27 +0000453
Marianne Mailhot-Sarrasin03137c62016-04-14 14:56:49 +0000454 if (eof())
455 return;
456
Birunthan Mohanathasb001a0b2015-07-03 17:25:16 +0000457 if (MacroBlock ? !FormatTok->is(TT_MacroBlockEnd)
458 : !FormatTok->is(tok::r_brace)) {
Daniel Jasper516d7972013-07-25 11:31:57 +0000459 Line->Level = InitialLevel;
Daniel Jaspereb65e912015-12-21 18:31:15 +0000460 FormatTok->BlockKind = BK_Block;
Manuel Klimek1a18c402013-04-12 14:13:36 +0000461 return;
Manuel Klimekf92f7bc2013-01-22 16:31:55 +0000462 }
Alexander Kornienko0ea8e102012-12-04 15:40:36 +0000463
Daniel Jasperd1ae3582013-03-20 12:37:50 +0000464 nextToken(); // Munch the closing brace.
Birunthan Mohanathasb001a0b2015-07-03 17:25:16 +0000465
466 if (MacroBlock && FormatTok->is(tok::l_paren))
467 parseParens();
468
Manuel Klimekb212f3b2013-10-12 22:46:56 +0000469 if (MunchSemi && FormatTok->Tok.is(tok::semi))
470 nextToken();
Daniel Jasper516d7972013-07-25 11:31:57 +0000471 Line->Level = InitialLevel;
Krasimir Georgiev7cb267a2017-02-27 13:28:36 +0000472 Line->MatchingOpeningBlockLineIndex = OpeningLineIndex;
Daniel Jasperf7935112012-12-03 18:12:45 +0000473}
474
Daniel Jasper02c7bca2015-03-30 09:56:50 +0000475static bool isGoogScope(const UnwrappedLine &Line) {
Daniel Jasper616de8642014-11-23 16:46:28 +0000476 // FIXME: Closure-library specific stuff should not be hard-coded but be
477 // configurable.
Daniel Jasper4a39c842014-05-06 13:54:10 +0000478 if (Line.Tokens.size() < 4)
479 return false;
480 auto I = Line.Tokens.begin();
481 if (I->Tok->TokenText != "goog")
482 return false;
483 ++I;
484 if (I->Tok->isNot(tok::period))
485 return false;
486 ++I;
487 if (I->Tok->TokenText != "scope")
488 return false;
489 ++I;
490 return I->Tok->is(tok::l_paren);
491}
492
Martin Probst101ec892017-05-09 20:04:09 +0000493static bool isIIFE(const UnwrappedLine &Line,
494 const AdditionalKeywords &Keywords) {
495 // Look for the start of an immediately invoked anonymous function.
496 // https://en.wikipedia.org/wiki/Immediately-invoked_function_expression
497 // This is commonly done in JavaScript to create a new, anonymous scope.
498 // Example: (function() { ... })()
499 if (Line.Tokens.size() < 3)
500 return false;
501 auto I = Line.Tokens.begin();
502 if (I->Tok->isNot(tok::l_paren))
503 return false;
504 ++I;
505 if (I->Tok->isNot(Keywords.kw_function))
506 return false;
507 ++I;
508 return I->Tok->is(tok::l_paren);
509}
510
Roman Kashitsyna043ced2014-08-11 12:18:01 +0000511static bool ShouldBreakBeforeBrace(const FormatStyle &Style,
512 const FormatToken &InitialToken) {
Daniel Jasperc1bc38e2015-09-29 14:57:55 +0000513 if (InitialToken.is(tok::kw_namespace))
514 return Style.BraceWrapping.AfterNamespace;
515 if (InitialToken.is(tok::kw_class))
516 return Style.BraceWrapping.AfterClass;
517 if (InitialToken.is(tok::kw_union))
518 return Style.BraceWrapping.AfterUnion;
519 if (InitialToken.is(tok::kw_struct))
520 return Style.BraceWrapping.AfterStruct;
521 return false;
Roman Kashitsyna043ced2014-08-11 12:18:01 +0000522}
523
Manuel Klimek516e0542013-09-04 13:25:30 +0000524void UnwrappedLineParser::parseChildBlock() {
525 FormatTok->BlockKind = BK_Block;
526 nextToken();
527 {
Martin Probst101ec892017-05-09 20:04:09 +0000528 bool SkipIndent =
529 (Style.Language == FormatStyle::LK_JavaScript &&
530 (isGoogScope(*Line) || isIIFE(*Line, Keywords)));
Manuel Klimek516e0542013-09-04 13:25:30 +0000531 ScopedLineState LineState(*this);
532 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
533 /*MustBeDeclaration=*/false);
Martin Probst101ec892017-05-09 20:04:09 +0000534 Line->Level += SkipIndent ? 0 : 1;
Manuel Klimek516e0542013-09-04 13:25:30 +0000535 parseLevel(/*HasOpeningBrace=*/true);
Daniel Jasper02c7bca2015-03-30 09:56:50 +0000536 flushComments(isOnNewLine(*FormatTok));
Martin Probst101ec892017-05-09 20:04:09 +0000537 Line->Level -= SkipIndent ? 0 : 1;
Manuel Klimek516e0542013-09-04 13:25:30 +0000538 }
539 nextToken();
540}
541
Daniel Jasperf7935112012-12-03 18:12:45 +0000542void UnwrappedLineParser::parsePPDirective() {
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000543 assert(FormatTok->Tok.is(tok::hash) && "'#' expected");
Manuel Klimek20e0af62015-05-06 11:56:29 +0000544 ScopedMacroState MacroState(*Line, Tokens, FormatTok);
Manuel Klimeka71e5d82013-01-02 16:30:12 +0000545 nextToken();
546
Craig Topper2145bc02014-05-09 08:15:10 +0000547 if (!FormatTok->Tok.getIdentifierInfo()) {
Manuel Klimek591b5802013-01-31 15:58:48 +0000548 parsePPUnknown();
Manuel Klimeka71e5d82013-01-02 16:30:12 +0000549 return;
Daniel Jasperf7935112012-12-03 18:12:45 +0000550 }
Manuel Klimeka71e5d82013-01-02 16:30:12 +0000551
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000552 switch (FormatTok->Tok.getIdentifierInfo()->getPPKeywordID()) {
Manuel Klimek1abf7892013-01-04 23:34:14 +0000553 case tok::pp_define:
554 parsePPDefine();
Alexander Kornienkof2e02122013-05-24 18:24:24 +0000555 return;
556 case tok::pp_if:
Manuel Klimek71814b42013-10-11 21:25:45 +0000557 parsePPIf(/*IfDef=*/false);
Alexander Kornienkof2e02122013-05-24 18:24:24 +0000558 break;
559 case tok::pp_ifdef:
560 case tok::pp_ifndef:
Manuel Klimek71814b42013-10-11 21:25:45 +0000561 parsePPIf(/*IfDef=*/true);
Alexander Kornienkof2e02122013-05-24 18:24:24 +0000562 break;
563 case tok::pp_else:
564 parsePPElse();
565 break;
566 case tok::pp_elif:
567 parsePPElIf();
568 break;
569 case tok::pp_endif:
570 parsePPEndIf();
Manuel Klimek1abf7892013-01-04 23:34:14 +0000571 break;
572 default:
573 parsePPUnknown();
574 break;
575 }
576}
577
Manuel Klimek68b03042014-04-14 09:14:11 +0000578void UnwrappedLineParser::conditionalCompilationCondition(bool Unreachable) {
579 if (Unreachable || (!PPStack.empty() && PPStack.back() == PP_Unreachable))
Alexander Kornienkof2e02122013-05-24 18:24:24 +0000580 PPStack.push_back(PP_Unreachable);
581 else
582 PPStack.push_back(PP_Conditional);
583}
584
Manuel Klimek68b03042014-04-14 09:14:11 +0000585void UnwrappedLineParser::conditionalCompilationStart(bool Unreachable) {
Manuel Klimek71814b42013-10-11 21:25:45 +0000586 ++PPBranchLevel;
587 assert(PPBranchLevel >= 0 && PPBranchLevel <= (int)PPLevelBranchIndex.size());
588 if (PPBranchLevel == (int)PPLevelBranchIndex.size()) {
589 PPLevelBranchIndex.push_back(0);
590 PPLevelBranchCount.push_back(0);
591 }
592 PPChainBranchIndex.push(0);
Manuel Klimek68b03042014-04-14 09:14:11 +0000593 bool Skip = PPLevelBranchIndex[PPBranchLevel] > 0;
594 conditionalCompilationCondition(Unreachable || Skip);
Alexander Kornienkof2e02122013-05-24 18:24:24 +0000595}
596
Manuel Klimek68b03042014-04-14 09:14:11 +0000597void UnwrappedLineParser::conditionalCompilationAlternative() {
Alexander Kornienkof2e02122013-05-24 18:24:24 +0000598 if (!PPStack.empty())
599 PPStack.pop_back();
Manuel Klimek71814b42013-10-11 21:25:45 +0000600 assert(PPBranchLevel < (int)PPLevelBranchIndex.size());
601 if (!PPChainBranchIndex.empty())
602 ++PPChainBranchIndex.top();
Manuel Klimek68b03042014-04-14 09:14:11 +0000603 conditionalCompilationCondition(
604 PPBranchLevel >= 0 && !PPChainBranchIndex.empty() &&
605 PPLevelBranchIndex[PPBranchLevel] != PPChainBranchIndex.top());
Alexander Kornienkof2e02122013-05-24 18:24:24 +0000606}
607
Manuel Klimek68b03042014-04-14 09:14:11 +0000608void UnwrappedLineParser::conditionalCompilationEnd() {
Manuel Klimek71814b42013-10-11 21:25:45 +0000609 assert(PPBranchLevel < (int)PPLevelBranchIndex.size());
610 if (PPBranchLevel >= 0 && !PPChainBranchIndex.empty()) {
611 if (PPChainBranchIndex.top() + 1 > PPLevelBranchCount[PPBranchLevel]) {
Manuel Klimek71814b42013-10-11 21:25:45 +0000612 PPLevelBranchCount[PPBranchLevel] = PPChainBranchIndex.top() + 1;
613 }
614 }
Manuel Klimek14bd9172014-01-29 08:49:02 +0000615 // Guard against #endif's without #if.
616 if (PPBranchLevel > 0)
617 --PPBranchLevel;
Manuel Klimek71814b42013-10-11 21:25:45 +0000618 if (!PPChainBranchIndex.empty())
619 PPChainBranchIndex.pop();
Alexander Kornienkof2e02122013-05-24 18:24:24 +0000620 if (!PPStack.empty())
621 PPStack.pop_back();
Manuel Klimek68b03042014-04-14 09:14:11 +0000622}
623
624void UnwrappedLineParser::parsePPIf(bool IfDef) {
Daniel Jasper62703eb2017-03-01 11:10:11 +0000625 bool IfNDef = FormatTok->is(tok::pp_ifndef);
Manuel Klimek68b03042014-04-14 09:14:11 +0000626 nextToken();
Daniel Jaspereab6cd42017-03-01 10:47:52 +0000627 bool Unreachable = false;
628 if (!IfDef && (FormatTok->is(tok::kw_false) || FormatTok->TokenText == "0"))
629 Unreachable = true;
Daniel Jasper62703eb2017-03-01 11:10:11 +0000630 if (IfDef && !IfNDef && FormatTok->TokenText == "SWIG")
Daniel Jaspereab6cd42017-03-01 10:47:52 +0000631 Unreachable = true;
632 conditionalCompilationStart(Unreachable);
Manuel Klimek68b03042014-04-14 09:14:11 +0000633 parsePPUnknown();
634}
635
636void UnwrappedLineParser::parsePPElse() {
637 conditionalCompilationAlternative();
638 parsePPUnknown();
639}
640
641void UnwrappedLineParser::parsePPElIf() { parsePPElse(); }
642
643void UnwrappedLineParser::parsePPEndIf() {
644 conditionalCompilationEnd();
Alexander Kornienkof2e02122013-05-24 18:24:24 +0000645 parsePPUnknown();
646}
647
Manuel Klimek1abf7892013-01-04 23:34:14 +0000648void UnwrappedLineParser::parsePPDefine() {
649 nextToken();
650
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000651 if (FormatTok->Tok.getKind() != tok::identifier) {
Manuel Klimek1abf7892013-01-04 23:34:14 +0000652 parsePPUnknown();
653 return;
654 }
655 nextToken();
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000656 if (FormatTok->Tok.getKind() == tok::l_paren &&
657 FormatTok->WhitespaceRange.getBegin() ==
658 FormatTok->WhitespaceRange.getEnd()) {
Manuel Klimek1abf7892013-01-04 23:34:14 +0000659 parseParens();
660 }
661 addUnwrappedLine();
Manuel Klimek52b15152013-01-09 15:25:02 +0000662 Line->Level = 1;
Manuel Klimek1b896292013-01-07 09:34:28 +0000663
664 // Errors during a preprocessor directive can only affect the layout of the
665 // preprocessor directive, and thus we ignore them. An alternative approach
666 // would be to use the same approach we use on the file level (no
667 // re-indentation if there was a structural error) within the macro
668 // definition.
Manuel Klimek1abf7892013-01-04 23:34:14 +0000669 parseFile();
670}
671
672void UnwrappedLineParser::parsePPUnknown() {
Manuel Klimeka71e5d82013-01-02 16:30:12 +0000673 do {
Manuel Klimeka71e5d82013-01-02 16:30:12 +0000674 nextToken();
675 } while (!eof());
676 addUnwrappedLine();
Daniel Jasperf7935112012-12-03 18:12:45 +0000677}
678
Alexander Kornienkoa04e5e22013-04-09 16:15:19 +0000679// Here we blacklist certain tokens that are not usually the first token in an
680// unwrapped line. This is used in attempt to distinguish macro calls without
681// trailing semicolons from other constructs split to several lines.
Benjamin Kramer8407df72015-03-09 16:47:52 +0000682static bool tokenCanStartNewLine(const clang::Token &Tok) {
Alexander Kornienkoa04e5e22013-04-09 16:15:19 +0000683 // Semicolon can be a null-statement, l_square can be a start of a macro or
684 // a C++11 attribute, but this doesn't seem to be common.
685 return Tok.isNot(tok::semi) && Tok.isNot(tok::l_brace) &&
686 Tok.isNot(tok::l_square) &&
687 // Tokens that can only be used as binary operators and a part of
688 // overloaded operator names.
689 Tok.isNot(tok::period) && Tok.isNot(tok::periodstar) &&
690 Tok.isNot(tok::arrow) && Tok.isNot(tok::arrowstar) &&
691 Tok.isNot(tok::less) && Tok.isNot(tok::greater) &&
692 Tok.isNot(tok::slash) && Tok.isNot(tok::percent) &&
693 Tok.isNot(tok::lessless) && Tok.isNot(tok::greatergreater) &&
694 Tok.isNot(tok::equal) && Tok.isNot(tok::plusequal) &&
695 Tok.isNot(tok::minusequal) && Tok.isNot(tok::starequal) &&
696 Tok.isNot(tok::slashequal) && Tok.isNot(tok::percentequal) &&
697 Tok.isNot(tok::ampequal) && Tok.isNot(tok::pipeequal) &&
698 Tok.isNot(tok::caretequal) && Tok.isNot(tok::greatergreaterequal) &&
699 Tok.isNot(tok::lesslessequal) &&
700 // Colon is used in labels, base class lists, initializer lists,
701 // range-based for loops, ternary operator, but should never be the
702 // first token in an unwrapped line.
Daniel Jasper5ebb2f32014-05-21 13:08:17 +0000703 Tok.isNot(tok::colon) &&
704 // 'noexcept' is a trailing annotation.
705 Tok.isNot(tok::kw_noexcept);
Alexander Kornienkoa04e5e22013-04-09 16:15:19 +0000706}
707
Martin Probst533965c2016-04-19 18:19:06 +0000708static bool mustBeJSIdent(const AdditionalKeywords &Keywords,
709 const FormatToken *FormatTok) {
Daniel Jasper1dcbbcfc2016-03-14 19:21:36 +0000710 // FIXME: This returns true for C/C++ keywords like 'struct'.
711 return FormatTok->is(tok::identifier) &&
712 (FormatTok->Tok.getIdentifierInfo() == nullptr ||
Martin Probst3dbbefa2016-11-10 16:21:02 +0000713 !FormatTok->isOneOf(
714 Keywords.kw_in, Keywords.kw_of, Keywords.kw_as, Keywords.kw_async,
715 Keywords.kw_await, Keywords.kw_yield, Keywords.kw_finally,
716 Keywords.kw_function, Keywords.kw_import, Keywords.kw_is,
717 Keywords.kw_let, Keywords.kw_var, tok::kw_const,
718 Keywords.kw_abstract, Keywords.kw_extends, Keywords.kw_implements,
719 Keywords.kw_instanceof, Keywords.kw_interface,
720 Keywords.kw_throws));
Daniel Jasper1dcbbcfc2016-03-14 19:21:36 +0000721}
722
Martin Probst533965c2016-04-19 18:19:06 +0000723static bool mustBeJSIdentOrValue(const AdditionalKeywords &Keywords,
724 const FormatToken *FormatTok) {
Martin Probstb9316ff2016-09-18 17:21:52 +0000725 return FormatTok->Tok.isLiteral() ||
726 FormatTok->isOneOf(tok::kw_true, tok::kw_false) ||
727 mustBeJSIdent(Keywords, FormatTok);
Martin Probst533965c2016-04-19 18:19:06 +0000728}
729
Daniel Jasper1dcbbcfc2016-03-14 19:21:36 +0000730// isJSDeclOrStmt returns true if |FormatTok| starts a declaration or statement
731// when encountered after a value (see mustBeJSIdentOrValue).
732static bool isJSDeclOrStmt(const AdditionalKeywords &Keywords,
733 const FormatToken *FormatTok) {
734 return FormatTok->isOneOf(
Martin Probst5f8445b2016-04-24 22:05:09 +0000735 tok::kw_return, Keywords.kw_yield,
Daniel Jasper1dcbbcfc2016-03-14 19:21:36 +0000736 // conditionals
737 tok::kw_if, tok::kw_else,
738 // loops
739 tok::kw_for, tok::kw_while, tok::kw_do, tok::kw_continue, tok::kw_break,
740 // switch/case
741 tok::kw_switch, tok::kw_case,
742 // exceptions
743 tok::kw_throw, tok::kw_try, tok::kw_catch, Keywords.kw_finally,
744 // declaration
745 tok::kw_const, tok::kw_class, Keywords.kw_var, Keywords.kw_let,
Martin Probst5f8445b2016-04-24 22:05:09 +0000746 Keywords.kw_async, Keywords.kw_function,
747 // import/export
748 Keywords.kw_import, tok::kw_export);
Daniel Jasper1dcbbcfc2016-03-14 19:21:36 +0000749}
750
751// readTokenWithJavaScriptASI reads the next token and terminates the current
752// line if JavaScript Automatic Semicolon Insertion must
753// happen between the current token and the next token.
754//
755// This method is conservative - it cannot cover all edge cases of JavaScript,
756// but only aims to correctly handle certain well known cases. It *must not*
757// return true in speculative cases.
758void UnwrappedLineParser::readTokenWithJavaScriptASI() {
759 FormatToken *Previous = FormatTok;
760 readToken();
761 FormatToken *Next = FormatTok;
762
763 bool IsOnSameLine =
764 CommentsBeforeNextToken.empty()
765 ? Next->NewlinesBefore == 0
766 : CommentsBeforeNextToken.front()->NewlinesBefore == 0;
767 if (IsOnSameLine)
768 return;
769
770 bool PreviousMustBeValue = mustBeJSIdentOrValue(Keywords, Previous);
Martin Probst717f6dc2016-10-21 05:11:38 +0000771 bool PreviousStartsTemplateExpr =
772 Previous->is(TT_TemplateString) && Previous->TokenText.endswith("${");
Martin Probstbbffeac2016-04-11 07:35:57 +0000773 if (PreviousMustBeValue && Line && Line->Tokens.size() > 1) {
774 // If the token before the previous one is an '@', the previous token is an
775 // annotation and can precede another identifier/value.
Benjamin Kramer5ffc24e2016-04-11 12:19:19 +0000776 const FormatToken *PrePrevious = std::prev(Line->Tokens.end(), 2)->Tok;
Martin Probstbbffeac2016-04-11 07:35:57 +0000777 if (PrePrevious->is(tok::at))
778 return;
779 }
Daniel Jasper1dcbbcfc2016-03-14 19:21:36 +0000780 if (Next->is(tok::exclaim) && PreviousMustBeValue)
Martin Probstd40bca42017-01-09 08:56:36 +0000781 return addUnwrappedLine();
Daniel Jasper1dcbbcfc2016-03-14 19:21:36 +0000782 bool NextMustBeValue = mustBeJSIdentOrValue(Keywords, Next);
Martin Probst717f6dc2016-10-21 05:11:38 +0000783 bool NextEndsTemplateExpr =
784 Next->is(TT_TemplateString) && Next->TokenText.startswith("}");
785 if (NextMustBeValue && !NextEndsTemplateExpr && !PreviousStartsTemplateExpr &&
786 (PreviousMustBeValue ||
787 Previous->isOneOf(tok::r_square, tok::r_paren, tok::plusplus,
788 tok::minusminus)))
Martin Probstd40bca42017-01-09 08:56:36 +0000789 return addUnwrappedLine();
Martin Probste6b5b342017-01-16 09:52:40 +0000790 if (PreviousMustBeValue && isJSDeclOrStmt(Keywords, Next))
Martin Probstd40bca42017-01-09 08:56:36 +0000791 return addUnwrappedLine();
Daniel Jasper1dcbbcfc2016-03-14 19:21:36 +0000792}
793
Manuel Klimek6b9eeba2013-01-07 14:56:16 +0000794void UnwrappedLineParser::parseStructuralElement() {
Daniel Jasper498f5582015-12-25 08:53:31 +0000795 assert(!FormatTok->is(tok::l_brace));
796 if (Style.Language == FormatStyle::LK_TableGen &&
797 FormatTok->is(tok::pp_include)) {
798 nextToken();
799 if (FormatTok->is(tok::string_literal))
800 nextToken();
801 addUnwrappedLine();
802 return;
803 }
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000804 switch (FormatTok->Tok.getKind()) {
Nico Weber04e9f1a2013-01-07 19:05:19 +0000805 case tok::at:
806 nextToken();
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000807 if (FormatTok->Tok.is(tok::l_brace)) {
Nico Weber372d8dc2013-02-10 20:35:35 +0000808 parseBracedList();
809 break;
810 }
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000811 switch (FormatTok->Tok.getObjCKeywordID()) {
Nico Weber04e9f1a2013-01-07 19:05:19 +0000812 case tok::objc_public:
813 case tok::objc_protected:
814 case tok::objc_package:
815 case tok::objc_private:
816 return parseAccessSpecifier();
Nico Weber7eecf4b2013-01-09 20:25:35 +0000817 case tok::objc_interface:
Nico Weber2ce0ac52013-01-09 23:25:37 +0000818 case tok::objc_implementation:
819 return parseObjCInterfaceOrImplementation();
Nico Weber8696a8d2013-01-09 21:15:03 +0000820 case tok::objc_protocol:
821 return parseObjCProtocol();
Nico Weberd8ffe752013-01-09 21:42:32 +0000822 case tok::objc_end:
823 return; // Handled by the caller.
Nico Weber51306d22013-01-10 00:25:19 +0000824 case tok::objc_optional:
825 case tok::objc_required:
826 nextToken();
827 addUnwrappedLine();
828 return;
Nico Weber45c48122015-06-28 01:06:16 +0000829 case tok::objc_autoreleasepool:
830 nextToken();
831 if (FormatTok->Tok.is(tok::l_brace)) {
Daniel Jasperc1bc38e2015-09-29 14:57:55 +0000832 if (Style.BraceWrapping.AfterObjCDeclaration)
Nico Weber45c48122015-06-28 01:06:16 +0000833 addUnwrappedLine();
834 parseBlock(/*MustBeDeclaration=*/false);
835 }
836 addUnwrappedLine();
837 return;
Nico Weber33381f52015-02-07 01:57:32 +0000838 case tok::objc_try:
839 // This branch isn't strictly necessary (the kw_try case below would
840 // do this too after the tok::at is parsed above). But be explicit.
841 parseTryCatch();
842 return;
Nico Weber04e9f1a2013-01-07 19:05:19 +0000843 default:
844 break;
845 }
846 break;
Daniel Jasper8f463652014-08-26 23:15:12 +0000847 case tok::kw_asm:
Daniel Jasper8f463652014-08-26 23:15:12 +0000848 nextToken();
849 if (FormatTok->is(tok::l_brace)) {
Daniel Jasperc6366072015-05-10 08:42:04 +0000850 FormatTok->Type = TT_InlineASMBrace;
Daniel Jasper2337f282015-01-12 10:14:56 +0000851 nextToken();
Daniel Jasper4429f142014-08-27 17:16:46 +0000852 while (FormatTok && FormatTok->isNot(tok::eof)) {
Daniel Jasper8f463652014-08-26 23:15:12 +0000853 if (FormatTok->is(tok::r_brace)) {
Daniel Jasperc6366072015-05-10 08:42:04 +0000854 FormatTok->Type = TT_InlineASMBrace;
Daniel Jasper8f463652014-08-26 23:15:12 +0000855 nextToken();
Daniel Jasper790d4f92015-05-11 11:59:46 +0000856 addUnwrappedLine();
Daniel Jasper8f463652014-08-26 23:15:12 +0000857 break;
858 }
Daniel Jasper2337f282015-01-12 10:14:56 +0000859 FormatTok->Finalized = true;
Daniel Jasper8f463652014-08-26 23:15:12 +0000860 nextToken();
861 }
862 }
863 break;
Alexander Kornienko578fdd82012-12-06 18:03:27 +0000864 case tok::kw_namespace:
865 parseNamespace();
866 return;
Dmitri Gribenko58d64e22012-12-30 21:27:25 +0000867 case tok::kw_inline:
868 nextToken();
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000869 if (FormatTok->Tok.is(tok::kw_namespace)) {
Dmitri Gribenko58d64e22012-12-30 21:27:25 +0000870 parseNamespace();
871 return;
872 }
873 break;
Alexander Kornienkob7076a22012-12-04 14:46:19 +0000874 case tok::kw_public:
875 case tok::kw_protected:
876 case tok::kw_private:
Daniel Jasper83709082015-02-18 17:14:05 +0000877 if (Style.Language == FormatStyle::LK_Java ||
878 Style.Language == FormatStyle::LK_JavaScript)
Daniel Jasperc58c70e2014-09-15 11:21:46 +0000879 nextToken();
880 else
881 parseAccessSpecifier();
Daniel Jasperf7935112012-12-03 18:12:45 +0000882 return;
Alexander Kornienkob7076a22012-12-04 14:46:19 +0000883 case tok::kw_if:
884 parseIfThenElse();
Daniel Jasperf7935112012-12-03 18:12:45 +0000885 return;
Alexander Kornienko37d6c942012-12-05 15:06:06 +0000886 case tok::kw_for:
887 case tok::kw_while:
888 parseForOrWhileLoop();
889 return;
Alexander Kornienkob7076a22012-12-04 14:46:19 +0000890 case tok::kw_do:
891 parseDoWhile();
892 return;
893 case tok::kw_switch:
894 parseSwitch();
895 return;
896 case tok::kw_default:
897 nextToken();
898 parseLabel();
899 return;
900 case tok::kw_case:
901 parseCaseLabel();
902 return;
Daniel Jasper04a71a42014-05-08 11:58:24 +0000903 case tok::kw_try:
Nico Weberfac23712015-02-04 15:26:27 +0000904 case tok::kw___try:
Daniel Jasper04a71a42014-05-08 11:58:24 +0000905 parseTryCatch();
906 return;
Manuel Klimekae610d12013-01-21 14:32:05 +0000907 case tok::kw_extern:
908 nextToken();
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000909 if (FormatTok->Tok.is(tok::string_literal)) {
Manuel Klimekae610d12013-01-21 14:32:05 +0000910 nextToken();
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000911 if (FormatTok->Tok.is(tok::l_brace)) {
Daniel Jasper65ee3472013-07-31 23:16:02 +0000912 parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/false);
Manuel Klimekae610d12013-01-21 14:32:05 +0000913 addUnwrappedLine();
914 return;
915 }
916 }
Daniel Jaspere1e43192014-04-01 12:55:11 +0000917 break;
Daniel Jasperfca735c2015-02-19 16:14:18 +0000918 case tok::kw_export:
919 if (Style.Language == FormatStyle::LK_JavaScript) {
920 parseJavaScriptEs6ImportExport();
921 return;
922 }
923 break;
Daniel Jaspere1e43192014-04-01 12:55:11 +0000924 case tok::identifier:
Daniel Jasper66cb8c52015-05-04 09:22:29 +0000925 if (FormatTok->is(TT_ForEachMacro)) {
Daniel Jaspere1e43192014-04-01 12:55:11 +0000926 parseForOrWhileLoop();
927 return;
928 }
Birunthan Mohanathasb001a0b2015-07-03 17:25:16 +0000929 if (FormatTok->is(TT_MacroBlockBegin)) {
930 parseBlock(/*MustBeDeclaration=*/false, /*AddLevel=*/true,
931 /*MunchSemi=*/false);
932 return;
933 }
Daniel Jasper3d5a7d62016-06-20 18:20:38 +0000934 if (FormatTok->is(Keywords.kw_import)) {
935 if (Style.Language == FormatStyle::LK_JavaScript) {
936 parseJavaScriptEs6ImportExport();
937 return;
938 }
939 if (Style.Language == FormatStyle::LK_Proto) {
940 nextToken();
Daniel Jasper8b61d142016-06-20 20:39:53 +0000941 if (FormatTok->is(tok::kw_public))
942 nextToken();
Daniel Jasper3d5a7d62016-06-20 18:20:38 +0000943 if (!FormatTok->is(tok::string_literal))
944 return;
945 nextToken();
946 if (FormatTok->is(tok::semi))
947 nextToken();
948 addUnwrappedLine();
949 return;
950 }
Daniel Jasper354aa512015-02-19 16:07:32 +0000951 }
Daniel Jasper1dbc2102017-03-31 13:30:24 +0000952 if (Style.isCpp() &&
Daniel Jasper72b33572017-03-31 12:04:37 +0000953 FormatTok->isOneOf(Keywords.kw_signals, Keywords.kw_qsignals,
Daniel Jaspera00de632015-12-01 12:05:04 +0000954 Keywords.kw_slots, Keywords.kw_qslots)) {
Daniel Jasperde0d1f32015-04-24 07:50:34 +0000955 nextToken();
956 if (FormatTok->is(tok::colon)) {
957 nextToken();
958 addUnwrappedLine();
Daniel Jasper31343832016-07-27 10:13:24 +0000959 return;
Daniel Jasperde0d1f32015-04-24 07:50:34 +0000960 }
Daniel Jasper53395402015-04-07 15:04:40 +0000961 }
Manuel Klimekae610d12013-01-21 14:32:05 +0000962 // In all other cases, parse the declaration.
963 break;
Alexander Kornienkob7076a22012-12-04 14:46:19 +0000964 default:
965 break;
Daniel Jasperf7935112012-12-03 18:12:45 +0000966 }
Daniel Jasperf7935112012-12-03 18:12:45 +0000967 do {
Daniel Jaspera7900ad2016-05-08 18:12:22 +0000968 const FormatToken *Previous = getPreviousToken();
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000969 switch (FormatTok->Tok.getKind()) {
Nico Weber372d8dc2013-02-10 20:35:35 +0000970 case tok::at:
971 nextToken();
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000972 if (FormatTok->Tok.is(tok::l_brace))
Nico Weber372d8dc2013-02-10 20:35:35 +0000973 parseBracedList();
974 break;
Alexander Kornienkob7076a22012-12-04 14:46:19 +0000975 case tok::kw_enum:
Daniel Jaspera7900ad2016-05-08 18:12:22 +0000976 // Ignore if this is part of "template <enum ...".
977 if (Previous && Previous->is(tok::less)) {
978 nextToken();
979 break;
980 }
981
Daniel Jasper90cf3802015-06-17 09:44:02 +0000982 // parseEnum falls through and does not yet add an unwrapped line as an
983 // enum definition can start a structural element.
Daniel Jasper6f5a1932015-12-29 08:54:23 +0000984 if (!parseEnum())
985 break;
Daniel Jasperc6dd2732015-07-16 14:25:43 +0000986 // This only applies for C++.
Daniel Jasper1dbc2102017-03-31 13:30:24 +0000987 if (!Style.isCpp()) {
Daniel Jasper90cf3802015-06-17 09:44:02 +0000988 addUnwrappedLine();
989 return;
990 }
Manuel Klimek2cec0192013-01-21 19:17:52 +0000991 break;
Daniel Jaspera88f80a2014-01-30 14:38:37 +0000992 case tok::kw_typedef:
993 nextToken();
Daniel Jasper31f6c542014-12-05 10:42:21 +0000994 if (FormatTok->isOneOf(Keywords.kw_NS_ENUM, Keywords.kw_NS_OPTIONS,
995 Keywords.kw_CF_ENUM, Keywords.kw_CF_OPTIONS))
Daniel Jaspera88f80a2014-01-30 14:38:37 +0000996 parseEnum();
997 break;
Alexander Kornienko1231e062013-01-16 11:43:46 +0000998 case tok::kw_struct:
999 case tok::kw_union:
Manuel Klimek28cacc72013-01-07 18:10:23 +00001000 case tok::kw_class:
Daniel Jasper910807d2015-06-12 04:52:02 +00001001 // parseRecord falls through and does not yet add an unwrapped line as a
1002 // record declaration or definition can start a structural element.
Manuel Klimeke01bab52013-01-15 13:38:33 +00001003 parseRecord();
Daniel Jasper910807d2015-06-12 04:52:02 +00001004 // This does not apply for Java and JavaScript.
1005 if (Style.Language == FormatStyle::LK_Java ||
1006 Style.Language == FormatStyle::LK_JavaScript) {
Daniel Jasperd5ec65b2016-01-08 07:06:07 +00001007 if (FormatTok->is(tok::semi))
1008 nextToken();
Daniel Jasper910807d2015-06-12 04:52:02 +00001009 addUnwrappedLine();
1010 return;
1011 }
Manuel Klimeke01bab52013-01-15 13:38:33 +00001012 break;
Daniel Jaspere5d74862014-11-26 08:17:08 +00001013 case tok::period:
1014 nextToken();
1015 // In Java, classes have an implicit static member "class".
1016 if (Style.Language == FormatStyle::LK_Java && FormatTok &&
1017 FormatTok->is(tok::kw_class))
1018 nextToken();
Daniel Jasperba52fcb2015-09-28 14:29:45 +00001019 if (Style.Language == FormatStyle::LK_JavaScript && FormatTok &&
1020 FormatTok->Tok.getIdentifierInfo())
1021 // JavaScript only has pseudo keywords, all keywords are allowed to
1022 // appear in "IdentifierName" positions. See http://es5.github.io/#x7.6
1023 nextToken();
Daniel Jaspere5d74862014-11-26 08:17:08 +00001024 break;
Daniel Jasperf7935112012-12-03 18:12:45 +00001025 case tok::semi:
1026 nextToken();
1027 addUnwrappedLine();
1028 return;
Alexander Kornienko1231e062013-01-16 11:43:46 +00001029 case tok::r_brace:
1030 addUnwrappedLine();
1031 return;
Daniel Jasperf7935112012-12-03 18:12:45 +00001032 case tok::l_paren:
1033 parseParens();
1034 break;
Daniel Jasper5af04a42015-10-07 03:43:10 +00001035 case tok::kw_operator:
1036 nextToken();
1037 if (FormatTok->isBinaryOperator())
1038 nextToken();
1039 break;
Manuel Klimek516e0542013-09-04 13:25:30 +00001040 case tok::caret:
1041 nextToken();
Daniel Jasper395193c2014-03-28 07:48:59 +00001042 if (FormatTok->Tok.isAnyIdentifier() ||
1043 FormatTok->isSimpleTypeSpecifier())
1044 nextToken();
1045 if (FormatTok->is(tok::l_paren))
1046 parseParens();
1047 if (FormatTok->is(tok::l_brace))
Manuel Klimek516e0542013-09-04 13:25:30 +00001048 parseChildBlock();
Manuel Klimek516e0542013-09-04 13:25:30 +00001049 break;
Daniel Jasperf7935112012-12-03 18:12:45 +00001050 case tok::l_brace:
Manuel Klimekab419912013-05-23 09:41:43 +00001051 if (!tryToParseBracedList()) {
1052 // A block outside of parentheses must be the last part of a
1053 // structural element.
1054 // FIXME: Figure out cases where this is not true, and add projections
1055 // for them (the one we know is missing are lambdas).
Daniel Jasperc1bc38e2015-09-29 14:57:55 +00001056 if (Style.BraceWrapping.AfterFunction)
Manuel Klimekab419912013-05-23 09:41:43 +00001057 addUnwrappedLine();
Alexander Kornienko3cfa9732013-11-20 16:33:05 +00001058 FormatTok->Type = TT_FunctionLBrace;
Nico Weber9096fc02013-06-26 00:30:14 +00001059 parseBlock(/*MustBeDeclaration=*/false);
Manuel Klimeka8eb9142013-05-13 12:51:40 +00001060 addUnwrappedLine();
Manuel Klimekab419912013-05-23 09:41:43 +00001061 return;
1062 }
1063 // Otherwise this was a braced init list, and the structural
1064 // element continues.
1065 break;
Daniel Jasper04a71a42014-05-08 11:58:24 +00001066 case tok::kw_try:
1067 // We arrive here when parsing function-try blocks.
1068 parseTryCatch();
1069 return;
Daniel Jasper40e19212013-05-29 13:16:10 +00001070 case tok::identifier: {
Birunthan Mohanathasb001a0b2015-07-03 17:25:16 +00001071 if (FormatTok->is(TT_MacroBlockEnd)) {
1072 addUnwrappedLine();
1073 return;
1074 }
1075
Martin Probst973ff792017-04-27 13:07:24 +00001076 // Function declarations (as opposed to function expressions) are parsed
1077 // on their own unwrapped line by continuing this loop. Function
1078 // expressions (functions that are not on their own line) must not create
1079 // a new unwrapped line, so they are special cased below.
1080 size_t TokenCount = Line->Tokens.size();
Daniel Jasper9326f912015-05-05 08:40:32 +00001081 if (Style.Language == FormatStyle::LK_JavaScript &&
Martin Probst973ff792017-04-27 13:07:24 +00001082 FormatTok->is(Keywords.kw_function) &&
1083 (TokenCount > 1 || (TokenCount == 1 && !Line->Tokens.front().Tok->is(
1084 Keywords.kw_async)))) {
Daniel Jasper069e5f42014-05-20 11:14:57 +00001085 tryToParseJSFunction();
1086 break;
1087 }
Daniel Jasper9326f912015-05-05 08:40:32 +00001088 if ((Style.Language == FormatStyle::LK_JavaScript ||
1089 Style.Language == FormatStyle::LK_Java) &&
1090 FormatTok->is(Keywords.kw_interface)) {
Martin Probst1e8261e2016-04-19 18:18:59 +00001091 if (Style.Language == FormatStyle::LK_JavaScript) {
1092 // In JavaScript/TypeScript, "interface" can be used as a standalone
1093 // identifier, e.g. in `var interface = 1;`. If "interface" is
1094 // followed by another identifier, it is very like to be an actual
1095 // interface declaration.
1096 unsigned StoredPosition = Tokens->getPosition();
1097 FormatToken *Next = Tokens->getNextToken();
1098 FormatTok = Tokens->setPosition(StoredPosition);
Martin Probst533965c2016-04-19 18:19:06 +00001099 if (Next && !mustBeJSIdent(Keywords, Next)) {
Martin Probst1e8261e2016-04-19 18:18:59 +00001100 nextToken();
1101 break;
1102 }
1103 }
Daniel Jasper9326f912015-05-05 08:40:32 +00001104 parseRecord();
Daniel Jasper259188b2015-06-12 04:56:34 +00001105 addUnwrappedLine();
Daniel Jasper5c235c02015-07-06 14:26:04 +00001106 return;
Daniel Jasper9326f912015-05-05 08:40:32 +00001107 }
1108
Daniel Jasper1dcbbcfc2016-03-14 19:21:36 +00001109 // See if the following token should start a new unwrapped line.
Daniel Jasper9326f912015-05-05 08:40:32 +00001110 StringRef Text = FormatTok->TokenText;
Daniel Jasperf7935112012-12-03 18:12:45 +00001111 nextToken();
Daniel Jasper83709082015-02-18 17:14:05 +00001112 if (Line->Tokens.size() == 1 &&
1113 // JS doesn't have macros, and within classes colons indicate fields,
1114 // not labels.
Daniel Jasper676e5162015-04-07 14:36:33 +00001115 Style.Language != FormatStyle::LK_JavaScript) {
1116 if (FormatTok->Tok.is(tok::colon) && !Line->MustBeDeclaration) {
Daniel Jasper40609472016-04-06 15:02:46 +00001117 Line->Tokens.begin()->Tok->MustBreakBefore = true;
Alexander Kornienkode644272013-04-08 22:16:06 +00001118 parseLabel();
1119 return;
1120 }
Daniel Jasper680b09b2014-11-05 10:48:04 +00001121 // Recognize function-like macro usages without trailing semicolon as
Daniel Jasper83709082015-02-18 17:14:05 +00001122 // well as free-standing macros like Q_OBJECT.
Daniel Jasper680b09b2014-11-05 10:48:04 +00001123 bool FunctionLike = FormatTok->is(tok::l_paren);
1124 if (FunctionLike)
Alexander Kornienkode644272013-04-08 22:16:06 +00001125 parseParens();
Daniel Jaspere60cba12015-05-13 11:35:53 +00001126
1127 bool FollowedByNewline =
1128 CommentsBeforeNextToken.empty()
1129 ? FormatTok->NewlinesBefore > 0
1130 : CommentsBeforeNextToken.front()->NewlinesBefore > 0;
1131
Daniel Jaspere6fcf7d2015-06-17 13:08:06 +00001132 if (FollowedByNewline && (Text.size() >= 5 || FunctionLike) &&
Daniel Jasper680b09b2014-11-05 10:48:04 +00001133 tokenCanStartNewLine(FormatTok->Tok) && Text == Text.upper()) {
Daniel Jasper40e19212013-05-29 13:16:10 +00001134 addUnwrappedLine();
Daniel Jasper41a0f782013-05-29 14:09:17 +00001135 return;
Alexander Kornienkode644272013-04-08 22:16:06 +00001136 }
Daniel Jasperf7935112012-12-03 18:12:45 +00001137 }
1138 break;
Daniel Jasper40e19212013-05-29 13:16:10 +00001139 }
Daniel Jaspere25509f2012-12-17 11:29:41 +00001140 case tok::equal:
Manuel Klimek79e06082015-05-21 12:23:34 +00001141 // Fat arrows (=>) have tok::TokenKind tok::equal but TokenType
1142 // TT_JsFatArrow. The always start an expression or a child block if
1143 // followed by a curly.
1144 if (FormatTok->is(TT_JsFatArrow)) {
1145 nextToken();
Daniel Jasperbe520bd2015-05-31 08:51:54 +00001146 if (FormatTok->is(tok::l_brace))
Manuel Klimek79e06082015-05-21 12:23:34 +00001147 parseChildBlock();
Manuel Klimek79e06082015-05-21 12:23:34 +00001148 break;
1149 }
1150
Daniel Jaspere25509f2012-12-17 11:29:41 +00001151 nextToken();
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00001152 if (FormatTok->Tok.is(tok::l_brace)) {
Manuel Klimek8e07a1b2013-01-10 11:52:21 +00001153 parseBracedList();
1154 }
Daniel Jaspere25509f2012-12-17 11:29:41 +00001155 break;
Manuel Klimekffdeb592013-09-03 15:10:01 +00001156 case tok::l_square:
Daniel Jasperb88b25f2013-12-23 07:29:06 +00001157 parseSquare();
Manuel Klimekffdeb592013-09-03 15:10:01 +00001158 break;
Daniel Jasper6acf5132015-03-12 14:44:29 +00001159 case tok::kw_new:
1160 parseNew();
1161 break;
Alexander Kornienkob7076a22012-12-04 14:46:19 +00001162 default:
1163 nextToken();
1164 break;
Daniel Jasperf7935112012-12-03 18:12:45 +00001165 }
1166 } while (!eof());
1167}
1168
Daniel Jasperb88b25f2013-12-23 07:29:06 +00001169bool UnwrappedLineParser::tryToParseLambda() {
Daniel Jasper1dbc2102017-03-31 13:30:24 +00001170 if (!Style.isCpp()) {
Daniel Jasper1feab0f2015-06-02 15:31:37 +00001171 nextToken();
1172 return false;
1173 }
Daniel Jasperb9a49902016-01-09 15:56:28 +00001174 const FormatToken* Previous = getPreviousToken();
1175 if (Previous &&
1176 (Previous->isOneOf(tok::identifier, tok::kw_operator, tok::kw_new,
1177 tok::kw_delete) ||
1178 Previous->closesScope() || Previous->isSimpleTypeSpecifier())) {
Daniel Jasperbf02b2c12013-09-05 11:49:39 +00001179 nextToken();
Daniel Jasperb88b25f2013-12-23 07:29:06 +00001180 return false;
Daniel Jasperbf02b2c12013-09-05 11:49:39 +00001181 }
Daniel Jasper9fe0e8d2013-09-05 09:29:45 +00001182 assert(FormatTok->is(tok::l_square));
1183 FormatToken &LSquare = *FormatTok;
Daniel Jasper9a8d48b2013-09-05 10:04:31 +00001184 if (!tryToParseLambdaIntroducer())
Daniel Jasperb88b25f2013-12-23 07:29:06 +00001185 return false;
Manuel Klimekffdeb592013-09-03 15:10:01 +00001186
Alexander Kornienkoc2ee9cf2014-03-13 13:59:48 +00001187 while (FormatTok->isNot(tok::l_brace)) {
Daniel Jaspercb51cf42014-01-16 09:11:55 +00001188 if (FormatTok->isSimpleTypeSpecifier()) {
1189 nextToken();
1190 continue;
1191 }
Manuel Klimekffdeb592013-09-03 15:10:01 +00001192 switch (FormatTok->Tok.getKind()) {
Daniel Jasper9a8d48b2013-09-05 10:04:31 +00001193 case tok::l_brace:
1194 break;
1195 case tok::l_paren:
1196 parseParens();
1197 break;
Daniel Jasperbcb55ee2014-11-21 14:08:38 +00001198 case tok::amp:
1199 case tok::star:
1200 case tok::kw_const:
Daniel Jasper3431b752014-12-08 13:22:37 +00001201 case tok::comma:
Daniel Jaspercb51cf42014-01-16 09:11:55 +00001202 case tok::less:
1203 case tok::greater:
Daniel Jasper9a8d48b2013-09-05 10:04:31 +00001204 case tok::identifier:
Daniel Jasper5eaa0092015-08-13 13:37:08 +00001205 case tok::numeric_constant:
Daniel Jasper1067ab02014-02-11 10:16:55 +00001206 case tok::coloncolon:
Daniel Jasper9a8d48b2013-09-05 10:04:31 +00001207 case tok::kw_mutable:
Daniel Jasper81a20782014-03-10 10:02:02 +00001208 nextToken();
1209 break;
Daniel Jaspercb51cf42014-01-16 09:11:55 +00001210 case tok::arrow:
Daniel Jasper6f2b88a2015-06-05 13:18:09 +00001211 FormatTok->Type = TT_LambdaArrow;
Daniel Jasper9a8d48b2013-09-05 10:04:31 +00001212 nextToken();
1213 break;
1214 default:
Daniel Jasperb88b25f2013-12-23 07:29:06 +00001215 return true;
Manuel Klimekffdeb592013-09-03 15:10:01 +00001216 }
1217 }
Daniel Jasper9fe0e8d2013-09-05 09:29:45 +00001218 LSquare.Type = TT_LambdaLSquare;
Manuel Klimek516e0542013-09-04 13:25:30 +00001219 parseChildBlock();
Daniel Jasperb88b25f2013-12-23 07:29:06 +00001220 return true;
Manuel Klimekffdeb592013-09-03 15:10:01 +00001221}
1222
1223bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
1224 nextToken();
1225 if (FormatTok->is(tok::equal)) {
1226 nextToken();
Daniel Jasper9a8d48b2013-09-05 10:04:31 +00001227 if (FormatTok->is(tok::r_square)) {
1228 nextToken();
1229 return true;
1230 }
1231 if (FormatTok->isNot(tok::comma))
1232 return false;
Manuel Klimekffdeb592013-09-03 15:10:01 +00001233 nextToken();
1234 } else if (FormatTok->is(tok::amp)) {
1235 nextToken();
Daniel Jasper9a8d48b2013-09-05 10:04:31 +00001236 if (FormatTok->is(tok::r_square)) {
1237 nextToken();
1238 return true;
1239 }
Manuel Klimekffdeb592013-09-03 15:10:01 +00001240 if (!FormatTok->isOneOf(tok::comma, tok::identifier)) {
1241 return false;
1242 }
Daniel Jasper9a8d48b2013-09-05 10:04:31 +00001243 if (FormatTok->is(tok::comma))
1244 nextToken();
Manuel Klimekffdeb592013-09-03 15:10:01 +00001245 } else if (FormatTok->is(tok::r_square)) {
1246 nextToken();
1247 return true;
1248 }
1249 do {
Daniel Jasper9a8d48b2013-09-05 10:04:31 +00001250 if (FormatTok->is(tok::amp))
1251 nextToken();
1252 if (!FormatTok->isOneOf(tok::identifier, tok::kw_this))
1253 return false;
Manuel Klimekffdeb592013-09-03 15:10:01 +00001254 nextToken();
Daniel Jasperda18fd82014-06-10 06:39:03 +00001255 if (FormatTok->is(tok::ellipsis))
1256 nextToken();
Manuel Klimekffdeb592013-09-03 15:10:01 +00001257 if (FormatTok->is(tok::comma)) {
1258 nextToken();
1259 } else if (FormatTok->is(tok::r_square)) {
1260 nextToken();
1261 return true;
1262 } else {
1263 return false;
1264 }
1265 } while (!eof());
1266 return false;
1267}
1268
Daniel Jasperc03e16a2014-05-08 09:25:39 +00001269void UnwrappedLineParser::tryToParseJSFunction() {
Martin Probst409697e2016-05-29 14:41:07 +00001270 assert(FormatTok->is(Keywords.kw_function) ||
1271 FormatTok->startsSequence(Keywords.kw_async, Keywords.kw_function));
Martin Probst5f8445b2016-04-24 22:05:09 +00001272 if (FormatTok->is(Keywords.kw_async))
1273 nextToken();
1274 // Consume "function".
Daniel Jasperc03e16a2014-05-08 09:25:39 +00001275 nextToken();
Daniel Jasper5217a8b2014-06-13 07:02:04 +00001276
Daniel Jasper71e50af2016-11-01 06:22:59 +00001277 // Consume * (generator function). Treat it like C++'s overloaded operators.
1278 if (FormatTok->is(tok::star)) {
1279 FormatTok->Type = TT_OverloadedOperator;
Martin Probst5f8445b2016-04-24 22:05:09 +00001280 nextToken();
Daniel Jasper71e50af2016-11-01 06:22:59 +00001281 }
Martin Probst5f8445b2016-04-24 22:05:09 +00001282
Daniel Jasper5217a8b2014-06-13 07:02:04 +00001283 // Consume function name.
1284 if (FormatTok->is(tok::identifier))
Daniel Jasperfca735c2015-02-19 16:14:18 +00001285 nextToken();
Daniel Jasper5217a8b2014-06-13 07:02:04 +00001286
Daniel Jasperc03e16a2014-05-08 09:25:39 +00001287 if (FormatTok->isNot(tok::l_paren))
1288 return;
Manuel Klimek79e06082015-05-21 12:23:34 +00001289
1290 // Parse formal parameter list.
Daniel Jasperbe520bd2015-05-31 08:51:54 +00001291 parseParens();
Manuel Klimek79e06082015-05-21 12:23:34 +00001292
1293 if (FormatTok->is(tok::colon)) {
1294 // Parse a type definition.
1295 nextToken();
1296
1297 // Eat the type declaration. For braced inline object types, balance braces,
1298 // otherwise just parse until finding an l_brace for the function body.
Daniel Jasperbe520bd2015-05-31 08:51:54 +00001299 if (FormatTok->is(tok::l_brace))
1300 tryToParseBracedList();
1301 else
Martin Probstaf16c502017-01-04 13:36:43 +00001302 while (!FormatTok->isOneOf(tok::l_brace, tok::semi) && !eof())
Manuel Klimek79e06082015-05-21 12:23:34 +00001303 nextToken();
Manuel Klimek79e06082015-05-21 12:23:34 +00001304 }
1305
Martin Probstaf16c502017-01-04 13:36:43 +00001306 if (FormatTok->is(tok::semi))
1307 return;
1308
Manuel Klimek79e06082015-05-21 12:23:34 +00001309 parseChildBlock();
1310}
1311
Daniel Jasper3c883d12015-05-18 14:49:19 +00001312bool UnwrappedLineParser::tryToParseBracedList() {
Daniel Jasperb1f74a82013-07-09 09:06:29 +00001313 if (FormatTok->BlockKind == BK_Unknown)
Daniel Jasper3c883d12015-05-18 14:49:19 +00001314 calculateBraceTypes();
Daniel Jasperb1f74a82013-07-09 09:06:29 +00001315 assert(FormatTok->BlockKind != BK_Unknown);
1316 if (FormatTok->BlockKind == BK_Block)
Manuel Klimekab419912013-05-23 09:41:43 +00001317 return false;
1318 parseBracedList();
1319 return true;
1320}
1321
Daniel Jasper015ed022013-09-13 09:20:45 +00001322bool UnwrappedLineParser::parseBracedList(bool ContinueOnSemicolons) {
1323 bool HasError = false;
Manuel Klimek8e07a1b2013-01-10 11:52:21 +00001324 nextToken();
1325
Manuel Klimeka3ff45e2013-04-10 09:52:05 +00001326 // FIXME: Once we have an expression parser in the UnwrappedLineParser,
1327 // replace this by using parseAssigmentExpression() inside.
Manuel Klimek8e07a1b2013-01-10 11:52:21 +00001328 do {
Manuel Klimek79e06082015-05-21 12:23:34 +00001329 if (Style.Language == FormatStyle::LK_JavaScript) {
Martin Probst409697e2016-05-29 14:41:07 +00001330 if (FormatTok->is(Keywords.kw_function) ||
1331 FormatTok->startsSequence(Keywords.kw_async, Keywords.kw_function)) {
Manuel Klimek79e06082015-05-21 12:23:34 +00001332 tryToParseJSFunction();
1333 continue;
Daniel Jasperbe520bd2015-05-31 08:51:54 +00001334 }
1335 if (FormatTok->is(TT_JsFatArrow)) {
Manuel Klimek79e06082015-05-21 12:23:34 +00001336 nextToken();
1337 // Fat arrows can be followed by simple expressions or by child blocks
1338 // in curly braces.
Daniel Jaspere6fcf7d2015-06-17 13:08:06 +00001339 if (FormatTok->is(tok::l_brace)) {
Manuel Klimek79e06082015-05-21 12:23:34 +00001340 parseChildBlock();
1341 continue;
1342 }
1343 }
Martin Probst8e3eba02017-02-07 16:33:13 +00001344 if (FormatTok->is(tok::l_brace)) {
1345 // Could be a method inside of a braced list `{a() { return 1; }}`.
1346 if (tryToParseBracedList())
1347 continue;
1348 parseChildBlock();
1349 }
Daniel Jasperc03e16a2014-05-08 09:25:39 +00001350 }
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00001351 switch (FormatTok->Tok.getKind()) {
Manuel Klimek516e0542013-09-04 13:25:30 +00001352 case tok::caret:
1353 nextToken();
1354 if (FormatTok->is(tok::l_brace)) {
1355 parseChildBlock();
1356 }
1357 break;
1358 case tok::l_square:
1359 tryToParseLambda();
1360 break;
Daniel Jaspera87af7a2015-06-30 11:32:22 +00001361 case tok::l_paren:
1362 parseParens();
Daniel Jasperf46dec82015-03-31 14:34:15 +00001363 // JavaScript can just have free standing methods and getters/setters in
1364 // object literals. Detect them by a "{" following ")".
1365 if (Style.Language == FormatStyle::LK_JavaScript) {
Daniel Jasperf46dec82015-03-31 14:34:15 +00001366 if (FormatTok->is(tok::l_brace))
1367 parseChildBlock();
1368 break;
1369 }
Daniel Jasperf46dec82015-03-31 14:34:15 +00001370 break;
Martin Probst8e3eba02017-02-07 16:33:13 +00001371 case tok::l_brace:
1372 // Assume there are no blocks inside a braced init list apart
1373 // from the ones we explicitly parse out (like lambdas).
1374 FormatTok->BlockKind = BK_BracedInit;
1375 parseBracedList();
1376 break;
Manuel Klimek8e07a1b2013-01-10 11:52:21 +00001377 case tok::r_brace:
1378 nextToken();
Daniel Jasper015ed022013-09-13 09:20:45 +00001379 return !HasError;
Manuel Klimeka3ff45e2013-04-10 09:52:05 +00001380 case tok::semi:
Daniel Jasperb9a49902016-01-09 15:56:28 +00001381 // JavaScript (or more precisely TypeScript) can have semicolons in braced
1382 // lists (in so-called TypeMemberLists). Thus, the semicolon cannot be
1383 // used for error recovery if we have otherwise determined that this is
1384 // a braced list.
1385 if (Style.Language == FormatStyle::LK_JavaScript) {
1386 nextToken();
1387 break;
1388 }
Daniel Jasper015ed022013-09-13 09:20:45 +00001389 HasError = true;
1390 if (!ContinueOnSemicolons)
1391 return !HasError;
1392 nextToken();
1393 break;
Manuel Klimeka3ff45e2013-04-10 09:52:05 +00001394 case tok::comma:
1395 nextToken();
Manuel Klimeka3ff45e2013-04-10 09:52:05 +00001396 break;
Manuel Klimek8e07a1b2013-01-10 11:52:21 +00001397 default:
1398 nextToken();
1399 break;
1400 }
1401 } while (!eof());
Daniel Jasper015ed022013-09-13 09:20:45 +00001402 return false;
Manuel Klimek8e07a1b2013-01-10 11:52:21 +00001403}
1404
Daniel Jasperf7935112012-12-03 18:12:45 +00001405void UnwrappedLineParser::parseParens() {
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00001406 assert(FormatTok->Tok.is(tok::l_paren) && "'(' expected.");
Daniel Jasperf7935112012-12-03 18:12:45 +00001407 nextToken();
1408 do {
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00001409 switch (FormatTok->Tok.getKind()) {
Daniel Jasperf7935112012-12-03 18:12:45 +00001410 case tok::l_paren:
1411 parseParens();
Daniel Jasper5f1fa852015-01-04 20:40:51 +00001412 if (Style.Language == FormatStyle::LK_Java && FormatTok->is(tok::l_brace))
1413 parseChildBlock();
Daniel Jasperf7935112012-12-03 18:12:45 +00001414 break;
1415 case tok::r_paren:
1416 nextToken();
1417 return;
Daniel Jasper393564f2013-05-31 14:56:29 +00001418 case tok::r_brace:
1419 // A "}" inside parenthesis is an error if there wasn't a matching "{".
1420 return;
Daniel Jasper9a8d48b2013-09-05 10:04:31 +00001421 case tok::l_square:
1422 tryToParseLambda();
1423 break;
Daniel Jasper5f1fa852015-01-04 20:40:51 +00001424 case tok::l_brace:
Daniel Jasperadba2aa2015-05-18 12:52:00 +00001425 if (!tryToParseBracedList())
Manuel Klimekf017dc02013-09-04 13:34:14 +00001426 parseChildBlock();
Manuel Klimek8e07a1b2013-01-10 11:52:21 +00001427 break;
Nico Weber372d8dc2013-02-10 20:35:35 +00001428 case tok::at:
1429 nextToken();
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00001430 if (FormatTok->Tok.is(tok::l_brace))
Nico Weber372d8dc2013-02-10 20:35:35 +00001431 parseBracedList();
1432 break;
Martin Probst1027fb82017-02-07 14:05:30 +00001433 case tok::kw_class:
1434 if (Style.Language == FormatStyle::LK_JavaScript)
1435 parseRecord(/*ParseAsExpr=*/true);
1436 else
1437 nextToken();
1438 break;
Daniel Jasper3f69ba12014-09-05 08:42:27 +00001439 case tok::identifier:
1440 if (Style.Language == FormatStyle::LK_JavaScript &&
Martin Probst409697e2016-05-29 14:41:07 +00001441 (FormatTok->is(Keywords.kw_function) ||
1442 FormatTok->startsSequence(Keywords.kw_async, Keywords.kw_function)))
Daniel Jasper3f69ba12014-09-05 08:42:27 +00001443 tryToParseJSFunction();
1444 else
1445 nextToken();
1446 break;
Daniel Jasperf7935112012-12-03 18:12:45 +00001447 default:
1448 nextToken();
1449 break;
1450 }
1451 } while (!eof());
1452}
1453
Daniel Jasperb88b25f2013-12-23 07:29:06 +00001454void UnwrappedLineParser::parseSquare() {
1455 assert(FormatTok->Tok.is(tok::l_square) && "'[' expected.");
1456 if (tryToParseLambda())
1457 return;
1458 do {
Daniel Jasperb88b25f2013-12-23 07:29:06 +00001459 switch (FormatTok->Tok.getKind()) {
1460 case tok::l_paren:
1461 parseParens();
1462 break;
1463 case tok::r_square:
1464 nextToken();
1465 return;
1466 case tok::r_brace:
1467 // A "}" inside parenthesis is an error if there wasn't a matching "{".
1468 return;
1469 case tok::l_square:
1470 parseSquare();
1471 break;
1472 case tok::l_brace: {
Daniel Jasperadba2aa2015-05-18 12:52:00 +00001473 if (!tryToParseBracedList())
Daniel Jasperb88b25f2013-12-23 07:29:06 +00001474 parseChildBlock();
Daniel Jasperb88b25f2013-12-23 07:29:06 +00001475 break;
1476 }
1477 case tok::at:
1478 nextToken();
1479 if (FormatTok->Tok.is(tok::l_brace))
1480 parseBracedList();
1481 break;
1482 default:
1483 nextToken();
1484 break;
1485 }
1486 } while (!eof());
1487}
1488
Daniel Jasperf7935112012-12-03 18:12:45 +00001489void UnwrappedLineParser::parseIfThenElse() {
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00001490 assert(FormatTok->Tok.is(tok::kw_if) && "'if' expected");
Daniel Jasperf7935112012-12-03 18:12:45 +00001491 nextToken();
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00001492 if (FormatTok->Tok.is(tok::l_paren))
Manuel Klimekadededf2013-01-11 18:28:36 +00001493 parseParens();
Daniel Jasperf7935112012-12-03 18:12:45 +00001494 bool NeedsUnwrappedLine = false;
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00001495 if (FormatTok->Tok.is(tok::l_brace)) {
Alexander Kornienko3a33f022013-12-12 09:49:52 +00001496 CompoundStatementIndenter Indenter(this, Style, Line->Level);
Nico Weber9096fc02013-06-26 00:30:14 +00001497 parseBlock(/*MustBeDeclaration=*/false);
Daniel Jasperc1bc38e2015-09-29 14:57:55 +00001498 if (Style.BraceWrapping.BeforeElse)
Manuel Klimekd3ed59a2013-08-02 21:31:59 +00001499 addUnwrappedLine();
Daniel Jasperc1bc38e2015-09-29 14:57:55 +00001500 else
Manuel Klimekd3ed59a2013-08-02 21:31:59 +00001501 NeedsUnwrappedLine = true;
Daniel Jasperf7935112012-12-03 18:12:45 +00001502 } else {
1503 addUnwrappedLine();
Manuel Klimek52b15152013-01-09 15:25:02 +00001504 ++Line->Level;
Manuel Klimek6b9eeba2013-01-07 14:56:16 +00001505 parseStructuralElement();
Manuel Klimek52b15152013-01-09 15:25:02 +00001506 --Line->Level;
Daniel Jasperf7935112012-12-03 18:12:45 +00001507 }
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00001508 if (FormatTok->Tok.is(tok::kw_else)) {
Daniel Jasperf7935112012-12-03 18:12:45 +00001509 nextToken();
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00001510 if (FormatTok->Tok.is(tok::l_brace)) {
Alexander Kornienko3a33f022013-12-12 09:49:52 +00001511 CompoundStatementIndenter Indenter(this, Style, Line->Level);
Nico Weber9096fc02013-06-26 00:30:14 +00001512 parseBlock(/*MustBeDeclaration=*/false);
Daniel Jasperf7935112012-12-03 18:12:45 +00001513 addUnwrappedLine();
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00001514 } else if (FormatTok->Tok.is(tok::kw_if)) {
Daniel Jasperf7935112012-12-03 18:12:45 +00001515 parseIfThenElse();
1516 } else {
1517 addUnwrappedLine();
Manuel Klimek52b15152013-01-09 15:25:02 +00001518 ++Line->Level;
Manuel Klimek6b9eeba2013-01-07 14:56:16 +00001519 parseStructuralElement();
Daniel Jasper451544a2016-05-19 06:30:48 +00001520 if (FormatTok->is(tok::eof))
1521 addUnwrappedLine();
Manuel Klimek52b15152013-01-09 15:25:02 +00001522 --Line->Level;
Daniel Jasperf7935112012-12-03 18:12:45 +00001523 }
1524 } else if (NeedsUnwrappedLine) {
1525 addUnwrappedLine();
1526 }
1527}
1528
Daniel Jasper04a71a42014-05-08 11:58:24 +00001529void UnwrappedLineParser::parseTryCatch() {
Nico Weberfac23712015-02-04 15:26:27 +00001530 assert(FormatTok->isOneOf(tok::kw_try, tok::kw___try) && "'try' expected");
Daniel Jasper04a71a42014-05-08 11:58:24 +00001531 nextToken();
1532 bool NeedsUnwrappedLine = false;
1533 if (FormatTok->is(tok::colon)) {
1534 // We are in a function try block, what comes is an initializer list.
1535 nextToken();
1536 while (FormatTok->is(tok::identifier)) {
1537 nextToken();
1538 if (FormatTok->is(tok::l_paren))
1539 parseParens();
Daniel Jasper04a71a42014-05-08 11:58:24 +00001540 if (FormatTok->is(tok::comma))
1541 nextToken();
1542 }
1543 }
Daniel Jaspere189d462015-01-14 10:48:41 +00001544 // Parse try with resource.
1545 if (Style.Language == FormatStyle::LK_Java && FormatTok->is(tok::l_paren)) {
1546 parseParens();
1547 }
Daniel Jasper04a71a42014-05-08 11:58:24 +00001548 if (FormatTok->is(tok::l_brace)) {
1549 CompoundStatementIndenter Indenter(this, Style, Line->Level);
1550 parseBlock(/*MustBeDeclaration=*/false);
Daniel Jasperc1bc38e2015-09-29 14:57:55 +00001551 if (Style.BraceWrapping.BeforeCatch) {
Daniel Jasper04a71a42014-05-08 11:58:24 +00001552 addUnwrappedLine();
1553 } else {
1554 NeedsUnwrappedLine = true;
1555 }
1556 } else if (!FormatTok->is(tok::kw_catch)) {
1557 // The C++ standard requires a compound-statement after a try.
1558 // If there's none, we try to assume there's a structuralElement
1559 // and try to continue.
Daniel Jasper04a71a42014-05-08 11:58:24 +00001560 addUnwrappedLine();
1561 ++Line->Level;
1562 parseStructuralElement();
1563 --Line->Level;
1564 }
Nico Weber33381f52015-02-07 01:57:32 +00001565 while (1) {
1566 if (FormatTok->is(tok::at))
1567 nextToken();
1568 if (!(FormatTok->isOneOf(tok::kw_catch, Keywords.kw___except,
1569 tok::kw___finally) ||
1570 ((Style.Language == FormatStyle::LK_Java ||
1571 Style.Language == FormatStyle::LK_JavaScript) &&
1572 FormatTok->is(Keywords.kw_finally)) ||
1573 (FormatTok->Tok.isObjCAtKeyword(tok::objc_catch) ||
1574 FormatTok->Tok.isObjCAtKeyword(tok::objc_finally))))
1575 break;
Daniel Jasper04a71a42014-05-08 11:58:24 +00001576 nextToken();
1577 while (FormatTok->isNot(tok::l_brace)) {
1578 if (FormatTok->is(tok::l_paren)) {
1579 parseParens();
1580 continue;
1581 }
Daniel Jasper2bd7a642015-01-19 10:50:51 +00001582 if (FormatTok->isOneOf(tok::semi, tok::r_brace, tok::eof))
Daniel Jasper04a71a42014-05-08 11:58:24 +00001583 return;
1584 nextToken();
1585 }
1586 NeedsUnwrappedLine = false;
1587 CompoundStatementIndenter Indenter(this, Style, Line->Level);
1588 parseBlock(/*MustBeDeclaration=*/false);
Daniel Jasperc1bc38e2015-09-29 14:57:55 +00001589 if (Style.BraceWrapping.BeforeCatch)
Daniel Jasper04a71a42014-05-08 11:58:24 +00001590 addUnwrappedLine();
Daniel Jasperc1bc38e2015-09-29 14:57:55 +00001591 else
Daniel Jasper04a71a42014-05-08 11:58:24 +00001592 NeedsUnwrappedLine = true;
Daniel Jasper04a71a42014-05-08 11:58:24 +00001593 }
Daniel Jasperc1bc38e2015-09-29 14:57:55 +00001594 if (NeedsUnwrappedLine)
Daniel Jasper04a71a42014-05-08 11:58:24 +00001595 addUnwrappedLine();
Daniel Jasper04a71a42014-05-08 11:58:24 +00001596}
1597
Alexander Kornienko578fdd82012-12-06 18:03:27 +00001598void UnwrappedLineParser::parseNamespace() {
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00001599 assert(FormatTok->Tok.is(tok::kw_namespace) && "'namespace' expected");
Roman Kashitsyna043ced2014-08-11 12:18:01 +00001600
1601 const FormatToken &InitialToken = *FormatTok;
Alexander Kornienko578fdd82012-12-06 18:03:27 +00001602 nextToken();
Saleem Abdulrasool328085f2015-10-30 05:07:56 +00001603 while (FormatTok->isOneOf(tok::identifier, tok::coloncolon))
Alexander Kornienko578fdd82012-12-06 18:03:27 +00001604 nextToken();
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00001605 if (FormatTok->Tok.is(tok::l_brace)) {
Roman Kashitsyna043ced2014-08-11 12:18:01 +00001606 if (ShouldBreakBeforeBrace(Style, InitialToken))
Manuel Klimeka8eb9142013-05-13 12:51:40 +00001607 addUnwrappedLine();
1608
Daniel Jasper65ee3472013-07-31 23:16:02 +00001609 bool AddLevel = Style.NamespaceIndentation == FormatStyle::NI_All ||
1610 (Style.NamespaceIndentation == FormatStyle::NI_Inner &&
1611 DeclarationScopeStack.size() > 1);
1612 parseBlock(/*MustBeDeclaration=*/true, AddLevel);
Manuel Klimek046b9302013-02-06 16:08:09 +00001613 // Munch the semicolon after a namespace. This is more common than one would
1614 // think. Puttin the semicolon into its own line is very ugly.
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00001615 if (FormatTok->Tok.is(tok::semi))
Manuel Klimek046b9302013-02-06 16:08:09 +00001616 nextToken();
Alexander Kornienko578fdd82012-12-06 18:03:27 +00001617 addUnwrappedLine();
1618 }
1619 // FIXME: Add error handling.
1620}
1621
Daniel Jasper6acf5132015-03-12 14:44:29 +00001622void UnwrappedLineParser::parseNew() {
1623 assert(FormatTok->is(tok::kw_new) && "'new' expected");
1624 nextToken();
1625 if (Style.Language != FormatStyle::LK_Java)
1626 return;
1627
1628 // In Java, we can parse everything up to the parens, which aren't optional.
1629 do {
1630 // There should not be a ;, { or } before the new's open paren.
1631 if (FormatTok->isOneOf(tok::semi, tok::l_brace, tok::r_brace))
1632 return;
1633
1634 // Consume the parens.
1635 if (FormatTok->is(tok::l_paren)) {
1636 parseParens();
1637
1638 // If there is a class body of an anonymous class, consume that as child.
1639 if (FormatTok->is(tok::l_brace))
1640 parseChildBlock();
1641 return;
1642 }
1643 nextToken();
1644 } while (!eof());
1645}
1646
Alexander Kornienko37d6c942012-12-05 15:06:06 +00001647void UnwrappedLineParser::parseForOrWhileLoop() {
Daniel Jasper66cb8c52015-05-04 09:22:29 +00001648 assert(FormatTok->isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) &&
Daniel Jaspere1e43192014-04-01 12:55:11 +00001649 "'for', 'while' or foreach macro expected");
Alexander Kornienko37d6c942012-12-05 15:06:06 +00001650 nextToken();
Martin Probsta050f412017-05-18 21:19:29 +00001651 // JS' for await ( ...
Martin Probstbd49e322017-05-15 19:33:20 +00001652 if (Style.Language == FormatStyle::LK_JavaScript &&
Martin Probsta050f412017-05-18 21:19:29 +00001653 FormatTok->is(Keywords.kw_await))
Martin Probstbd49e322017-05-15 19:33:20 +00001654 nextToken();
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00001655 if (FormatTok->Tok.is(tok::l_paren))
Manuel Klimek9fa8d552013-01-11 19:23:05 +00001656 parseParens();
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00001657 if (FormatTok->Tok.is(tok::l_brace)) {
Alexander Kornienko3a33f022013-12-12 09:49:52 +00001658 CompoundStatementIndenter Indenter(this, Style, Line->Level);
Nico Weber9096fc02013-06-26 00:30:14 +00001659 parseBlock(/*MustBeDeclaration=*/false);
Alexander Kornienko37d6c942012-12-05 15:06:06 +00001660 addUnwrappedLine();
1661 } else {
1662 addUnwrappedLine();
Manuel Klimek52b15152013-01-09 15:25:02 +00001663 ++Line->Level;
Manuel Klimek6b9eeba2013-01-07 14:56:16 +00001664 parseStructuralElement();
Manuel Klimek52b15152013-01-09 15:25:02 +00001665 --Line->Level;
Alexander Kornienko37d6c942012-12-05 15:06:06 +00001666 }
1667}
1668
Daniel Jasperf7935112012-12-03 18:12:45 +00001669void UnwrappedLineParser::parseDoWhile() {
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00001670 assert(FormatTok->Tok.is(tok::kw_do) && "'do' expected");
Daniel Jasperf7935112012-12-03 18:12:45 +00001671 nextToken();
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00001672 if (FormatTok->Tok.is(tok::l_brace)) {
Alexander Kornienko3a33f022013-12-12 09:49:52 +00001673 CompoundStatementIndenter Indenter(this, Style, Line->Level);
Nico Weber9096fc02013-06-26 00:30:14 +00001674 parseBlock(/*MustBeDeclaration=*/false);
Daniel Jasperc1bc38e2015-09-29 14:57:55 +00001675 if (Style.BraceWrapping.IndentBraces)
Alexander Kornienko3a33f022013-12-12 09:49:52 +00001676 addUnwrappedLine();
Daniel Jasperf7935112012-12-03 18:12:45 +00001677 } else {
1678 addUnwrappedLine();
Manuel Klimek52b15152013-01-09 15:25:02 +00001679 ++Line->Level;
Manuel Klimek6b9eeba2013-01-07 14:56:16 +00001680 parseStructuralElement();
Manuel Klimek52b15152013-01-09 15:25:02 +00001681 --Line->Level;
Daniel Jasperf7935112012-12-03 18:12:45 +00001682 }
1683
Alexander Kornienko0ea8e102012-12-04 15:40:36 +00001684 // FIXME: Add error handling.
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00001685 if (!FormatTok->Tok.is(tok::kw_while)) {
Alexander Kornienko0ea8e102012-12-04 15:40:36 +00001686 addUnwrappedLine();
1687 return;
1688 }
1689
Daniel Jasperf7935112012-12-03 18:12:45 +00001690 nextToken();
Manuel Klimek6b9eeba2013-01-07 14:56:16 +00001691 parseStructuralElement();
Daniel Jasperf7935112012-12-03 18:12:45 +00001692}
1693
1694void UnwrappedLineParser::parseLabel() {
Daniel Jasperf7935112012-12-03 18:12:45 +00001695 nextToken();
Manuel Klimek52b15152013-01-09 15:25:02 +00001696 unsigned OldLineLevel = Line->Level;
Daniel Jaspera1275122013-03-20 10:23:53 +00001697 if (Line->Level > 1 || (!Line->InPPDirective && Line->Level > 0))
Manuel Klimek52b15152013-01-09 15:25:02 +00001698 --Line->Level;
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00001699 if (CommentsBeforeNextToken.empty() && FormatTok->Tok.is(tok::l_brace)) {
Alexander Kornienko3a33f022013-12-12 09:49:52 +00001700 CompoundStatementIndenter Indenter(this, Style, Line->Level);
Nico Weber9096fc02013-06-26 00:30:14 +00001701 parseBlock(/*MustBeDeclaration=*/false);
Manuel Klimekd3ed59a2013-08-02 21:31:59 +00001702 if (FormatTok->Tok.is(tok::kw_break)) {
Daniel Jasperc1bc38e2015-09-29 14:57:55 +00001703 if (Style.BraceWrapping.AfterControlStatement)
Manuel Klimekd3ed59a2013-08-02 21:31:59 +00001704 addUnwrappedLine();
1705 parseStructuralElement();
1706 }
Alexander Kornienko3a33f022013-12-12 09:49:52 +00001707 addUnwrappedLine();
1708 } else {
Daniel Jasper1fe0d5c2015-05-06 15:19:47 +00001709 if (FormatTok->is(tok::semi))
1710 nextToken();
Alexander Kornienko3a33f022013-12-12 09:49:52 +00001711 addUnwrappedLine();
Daniel Jasperf7935112012-12-03 18:12:45 +00001712 }
Manuel Klimek52b15152013-01-09 15:25:02 +00001713 Line->Level = OldLineLevel;
Daniel Jasper2cce7b72016-04-06 16:41:39 +00001714 if (FormatTok->isNot(tok::l_brace)) {
Daniel Jasper40609472016-04-06 15:02:46 +00001715 parseStructuralElement();
Daniel Jasper2cce7b72016-04-06 16:41:39 +00001716 addUnwrappedLine();
1717 }
Daniel Jasperf7935112012-12-03 18:12:45 +00001718}
1719
1720void UnwrappedLineParser::parseCaseLabel() {
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00001721 assert(FormatTok->Tok.is(tok::kw_case) && "'case' expected");
Daniel Jasperf7935112012-12-03 18:12:45 +00001722 // FIXME: fix handling of complex expressions here.
1723 do {
1724 nextToken();
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00001725 } while (!eof() && !FormatTok->Tok.is(tok::colon));
Daniel Jasperf7935112012-12-03 18:12:45 +00001726 parseLabel();
1727}
1728
1729void UnwrappedLineParser::parseSwitch() {
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00001730 assert(FormatTok->Tok.is(tok::kw_switch) && "'switch' expected");
Daniel Jasperf7935112012-12-03 18:12:45 +00001731 nextToken();
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00001732 if (FormatTok->Tok.is(tok::l_paren))
Manuel Klimek9fa8d552013-01-11 19:23:05 +00001733 parseParens();
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00001734 if (FormatTok->Tok.is(tok::l_brace)) {
Alexander Kornienko3a33f022013-12-12 09:49:52 +00001735 CompoundStatementIndenter Indenter(this, Style, Line->Level);
Daniel Jasper65ee3472013-07-31 23:16:02 +00001736 parseBlock(/*MustBeDeclaration=*/false);
Daniel Jasperf7935112012-12-03 18:12:45 +00001737 addUnwrappedLine();
1738 } else {
1739 addUnwrappedLine();
Daniel Jasper516d7972013-07-25 11:31:57 +00001740 ++Line->Level;
Manuel Klimek6b9eeba2013-01-07 14:56:16 +00001741 parseStructuralElement();
Daniel Jasper516d7972013-07-25 11:31:57 +00001742 --Line->Level;
Daniel Jasperf7935112012-12-03 18:12:45 +00001743 }
1744}
1745
1746void UnwrappedLineParser::parseAccessSpecifier() {
1747 nextToken();
Daniel Jasper84c47a12013-11-23 17:53:41 +00001748 // Understand Qt's slots.
Daniel Jasper53395402015-04-07 15:04:40 +00001749 if (FormatTok->isOneOf(Keywords.kw_slots, Keywords.kw_qslots))
Daniel Jasper84c47a12013-11-23 17:53:41 +00001750 nextToken();
Alexander Kornienko2ca766f2012-12-10 16:34:48 +00001751 // Otherwise, we don't know what it is, and we'd better keep the next token.
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00001752 if (FormatTok->Tok.is(tok::colon))
Alexander Kornienko2ca766f2012-12-10 16:34:48 +00001753 nextToken();
Daniel Jasperf7935112012-12-03 18:12:45 +00001754 addUnwrappedLine();
1755}
1756
Daniel Jasper6f5a1932015-12-29 08:54:23 +00001757bool UnwrappedLineParser::parseEnum() {
Daniel Jasper6be0f552014-11-13 15:56:28 +00001758 // Won't be 'enum' for NS_ENUMs.
1759 if (FormatTok->Tok.is(tok::kw_enum))
Daniel Jasperccb68b42014-11-19 22:38:18 +00001760 nextToken();
Daniel Jasper6be0f552014-11-13 15:56:28 +00001761
Daniel Jasper6f5a1932015-12-29 08:54:23 +00001762 // In TypeScript, "enum" can also be used as property name, e.g. in interface
1763 // declarations. An "enum" keyword followed by a colon would be a syntax
1764 // error and thus assume it is just an identifier.
Daniel Jasper87379302016-02-03 05:33:44 +00001765 if (Style.Language == FormatStyle::LK_JavaScript &&
1766 FormatTok->isOneOf(tok::colon, tok::question))
Daniel Jasper6f5a1932015-12-29 08:54:23 +00001767 return false;
1768
Daniel Jasper2b41a822013-08-20 12:42:50 +00001769 // Eat up enum class ...
Daniel Jasperb05a81d2014-05-09 13:11:16 +00001770 if (FormatTok->Tok.is(tok::kw_class) || FormatTok->Tok.is(tok::kw_struct))
1771 nextToken();
Daniel Jasperb5a0b852015-06-19 08:17:32 +00001772
Daniel Jasper786a5502013-09-06 21:32:35 +00001773 while (FormatTok->Tok.getIdentifierInfo() ||
Daniel Jasperccb68b42014-11-19 22:38:18 +00001774 FormatTok->isOneOf(tok::colon, tok::coloncolon, tok::less,
1775 tok::greater, tok::comma, tok::question)) {
Manuel Klimek2cec0192013-01-21 19:17:52 +00001776 nextToken();
1777 // We can have macros or attributes in between 'enum' and the enum name.
Daniel Jasperccb68b42014-11-19 22:38:18 +00001778 if (FormatTok->is(tok::l_paren))
Alexander Kornienkob7076a22012-12-04 14:46:19 +00001779 parseParens();
Daniel Jasperb5a0b852015-06-19 08:17:32 +00001780 if (FormatTok->is(tok::identifier)) {
Manuel Klimek2cec0192013-01-21 19:17:52 +00001781 nextToken();
Daniel Jasperb5a0b852015-06-19 08:17:32 +00001782 // If there are two identifiers in a row, this is likely an elaborate
1783 // return type. In Java, this can be "implements", etc.
Daniel Jasper1dbc2102017-03-31 13:30:24 +00001784 if (Style.isCpp() && FormatTok->is(tok::identifier))
Daniel Jasper6f5a1932015-12-29 08:54:23 +00001785 return false;
Daniel Jasperb5a0b852015-06-19 08:17:32 +00001786 }
Manuel Klimek2cec0192013-01-21 19:17:52 +00001787 }
Daniel Jasper6be0f552014-11-13 15:56:28 +00001788
1789 // Just a declaration or something is wrong.
Daniel Jasperccb68b42014-11-19 22:38:18 +00001790 if (FormatTok->isNot(tok::l_brace))
Daniel Jasper6f5a1932015-12-29 08:54:23 +00001791 return true;
Daniel Jasper6be0f552014-11-13 15:56:28 +00001792 FormatTok->BlockKind = BK_Block;
1793
1794 if (Style.Language == FormatStyle::LK_Java) {
1795 // Java enums are different.
1796 parseJavaEnumBody();
Daniel Jasper6f5a1932015-12-29 08:54:23 +00001797 return true;
1798 }
1799 if (Style.Language == FormatStyle::LK_Proto) {
Daniel Jasperc6dd2732015-07-16 14:25:43 +00001800 parseBlock(/*MustBeDeclaration=*/true);
Daniel Jasper6f5a1932015-12-29 08:54:23 +00001801 return true;
Manuel Klimek2cec0192013-01-21 19:17:52 +00001802 }
Daniel Jasper6be0f552014-11-13 15:56:28 +00001803
1804 // Parse enum body.
1805 bool HasError = !parseBracedList(/*ContinueOnSemicolons=*/true);
1806 if (HasError) {
1807 if (FormatTok->is(tok::semi))
1808 nextToken();
1809 addUnwrappedLine();
1810 }
Daniel Jasper6f5a1932015-12-29 08:54:23 +00001811 return true;
Daniel Jasper6be0f552014-11-13 15:56:28 +00001812
Daniel Jasper90cf3802015-06-17 09:44:02 +00001813 // There is no addUnwrappedLine() here so that we fall through to parsing a
1814 // structural element afterwards. Thus, in "enum A {} n, m;",
Manuel Klimek2cec0192013-01-21 19:17:52 +00001815 // "} n, m;" will end up in one unwrapped line.
Daniel Jasper6be0f552014-11-13 15:56:28 +00001816}
1817
1818void UnwrappedLineParser::parseJavaEnumBody() {
1819 // Determine whether the enum is simple, i.e. does not have a semicolon or
1820 // constants with class bodies. Simple enums can be formatted like braced
1821 // lists, contracted to a single line, etc.
1822 unsigned StoredPosition = Tokens->getPosition();
1823 bool IsSimple = true;
1824 FormatToken *Tok = Tokens->getNextToken();
1825 while (Tok) {
1826 if (Tok->is(tok::r_brace))
1827 break;
1828 if (Tok->isOneOf(tok::l_brace, tok::semi)) {
1829 IsSimple = false;
1830 break;
1831 }
1832 // FIXME: This will also mark enums with braces in the arguments to enum
1833 // constants as "not simple". This is probably fine in practice, though.
1834 Tok = Tokens->getNextToken();
1835 }
1836 FormatTok = Tokens->setPosition(StoredPosition);
1837
1838 if (IsSimple) {
1839 parseBracedList();
Daniel Jasperdf2ff002014-11-02 22:31:39 +00001840 addUnwrappedLine();
Daniel Jasper6be0f552014-11-13 15:56:28 +00001841 return;
1842 }
1843
1844 // Parse the body of a more complex enum.
1845 // First add a line for everything up to the "{".
1846 nextToken();
1847 addUnwrappedLine();
1848 ++Line->Level;
1849
1850 // Parse the enum constants.
1851 while (FormatTok) {
1852 if (FormatTok->is(tok::l_brace)) {
1853 // Parse the constant's class body.
1854 parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/true,
1855 /*MunchSemi=*/false);
1856 } else if (FormatTok->is(tok::l_paren)) {
1857 parseParens();
1858 } else if (FormatTok->is(tok::comma)) {
1859 nextToken();
1860 addUnwrappedLine();
1861 } else if (FormatTok->is(tok::semi)) {
1862 nextToken();
1863 addUnwrappedLine();
1864 break;
1865 } else if (FormatTok->is(tok::r_brace)) {
1866 addUnwrappedLine();
1867 break;
1868 } else {
1869 nextToken();
1870 }
1871 }
1872
1873 // Parse the class body after the enum's ";" if any.
1874 parseLevel(/*HasOpeningBrace=*/true);
1875 nextToken();
1876 --Line->Level;
1877 addUnwrappedLine();
Daniel Jasperf7935112012-12-03 18:12:45 +00001878}
1879
Martin Probst1027fb82017-02-07 14:05:30 +00001880void UnwrappedLineParser::parseRecord(bool ParseAsExpr) {
Roman Kashitsyna043ced2014-08-11 12:18:01 +00001881 const FormatToken &InitialToken = *FormatTok;
Manuel Klimek28cacc72013-01-07 18:10:23 +00001882 nextToken();
Daniel Jasper04785d02015-05-06 14:03:02 +00001883
Daniel Jasper04785d02015-05-06 14:03:02 +00001884 // The actual identifier can be a nested name specifier, and in macros
1885 // it is often token-pasted.
1886 while (FormatTok->isOneOf(tok::identifier, tok::coloncolon, tok::hashhash,
1887 tok::kw___attribute, tok::kw___declspec,
1888 tok::kw_alignas) ||
1889 ((Style.Language == FormatStyle::LK_Java ||
1890 Style.Language == FormatStyle::LK_JavaScript) &&
1891 FormatTok->isOneOf(tok::period, tok::comma))) {
1892 bool IsNonMacroIdentifier =
1893 FormatTok->is(tok::identifier) &&
1894 FormatTok->TokenText != FormatTok->TokenText.upper();
Manuel Klimeke01bab52013-01-15 13:38:33 +00001895 nextToken();
1896 // We can have macros or attributes in between 'class' and the class name.
Daniel Jasper04785d02015-05-06 14:03:02 +00001897 if (!IsNonMacroIdentifier && FormatTok->Tok.is(tok::l_paren))
Manuel Klimeke01bab52013-01-15 13:38:33 +00001898 parseParens();
Daniel Jasper04785d02015-05-06 14:03:02 +00001899 }
Manuel Klimeke01bab52013-01-15 13:38:33 +00001900
Daniel Jasper04785d02015-05-06 14:03:02 +00001901 // Note that parsing away template declarations here leads to incorrectly
1902 // accepting function declarations as record declarations.
1903 // In general, we cannot solve this problem. Consider:
1904 // class A<int> B() {}
1905 // which can be a function definition or a class definition when B() is a
1906 // macro. If we find enough real-world cases where this is a problem, we
1907 // can parse for the 'template' keyword in the beginning of the statement,
1908 // and thus rule out the record production in case there is no template
1909 // (this would still leave us with an ambiguity between template function
1910 // and class declarations).
Daniel Jasperadba2aa2015-05-18 12:52:00 +00001911 if (FormatTok->isOneOf(tok::colon, tok::less)) {
1912 while (!eof()) {
Daniel Jasper3c883d12015-05-18 14:49:19 +00001913 if (FormatTok->is(tok::l_brace)) {
1914 calculateBraceTypes(/*ExpectClassBody=*/true);
1915 if (!tryToParseBracedList())
1916 break;
1917 }
Daniel Jasper04785d02015-05-06 14:03:02 +00001918 if (FormatTok->Tok.is(tok::semi))
1919 return;
1920 nextToken();
Manuel Klimeke01bab52013-01-15 13:38:33 +00001921 }
1922 }
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00001923 if (FormatTok->Tok.is(tok::l_brace)) {
Martin Probst1027fb82017-02-07 14:05:30 +00001924 if (ParseAsExpr) {
1925 parseChildBlock();
1926 } else {
1927 if (ShouldBreakBeforeBrace(Style, InitialToken))
1928 addUnwrappedLine();
Manuel Klimeka8eb9142013-05-13 12:51:40 +00001929
Martin Probst1027fb82017-02-07 14:05:30 +00001930 parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/true,
1931 /*MunchSemi=*/false);
1932 }
Manuel Klimeka8eb9142013-05-13 12:51:40 +00001933 }
Daniel Jasper90cf3802015-06-17 09:44:02 +00001934 // There is no addUnwrappedLine() here so that we fall through to parsing a
1935 // structural element afterwards. Thus, in "class A {} n, m;",
1936 // "} n, m;" will end up in one unwrapped line.
Manuel Klimek28cacc72013-01-07 18:10:23 +00001937}
1938
Nico Weber8696a8d2013-01-09 21:15:03 +00001939void UnwrappedLineParser::parseObjCProtocolList() {
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00001940 assert(FormatTok->Tok.is(tok::less) && "'<' expected.");
Nico Weber8696a8d2013-01-09 21:15:03 +00001941 do
1942 nextToken();
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00001943 while (!eof() && FormatTok->Tok.isNot(tok::greater));
Nico Weber8696a8d2013-01-09 21:15:03 +00001944 nextToken(); // Skip '>'.
1945}
1946
1947void UnwrappedLineParser::parseObjCUntilAtEnd() {
1948 do {
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00001949 if (FormatTok->Tok.isObjCAtKeyword(tok::objc_end)) {
Nico Weber8696a8d2013-01-09 21:15:03 +00001950 nextToken();
1951 addUnwrappedLine();
1952 break;
1953 }
Daniel Jaspera15da302013-08-28 08:04:23 +00001954 if (FormatTok->is(tok::l_brace)) {
1955 parseBlock(/*MustBeDeclaration=*/false);
1956 // In ObjC interfaces, nothing should be following the "}".
1957 addUnwrappedLine();
Benjamin Kramere21cb742014-01-08 15:59:42 +00001958 } else if (FormatTok->is(tok::r_brace)) {
1959 // Ignore stray "}". parseStructuralElement doesn't consume them.
1960 nextToken();
1961 addUnwrappedLine();
Daniel Jaspera15da302013-08-28 08:04:23 +00001962 } else {
1963 parseStructuralElement();
1964 }
Nico Weber8696a8d2013-01-09 21:15:03 +00001965 } while (!eof());
1966}
1967
Nico Weber2ce0ac52013-01-09 23:25:37 +00001968void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
Nico Weber7eecf4b2013-01-09 20:25:35 +00001969 nextToken();
Daniel Jasperd1ae3582013-03-20 12:37:50 +00001970 nextToken(); // interface name
Nico Weber7eecf4b2013-01-09 20:25:35 +00001971
1972 // @interface can be followed by either a base class, or a category.
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00001973 if (FormatTok->Tok.is(tok::colon)) {
Nico Weber7eecf4b2013-01-09 20:25:35 +00001974 nextToken();
Daniel Jasperd1ae3582013-03-20 12:37:50 +00001975 nextToken(); // base class name
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00001976 } else if (FormatTok->Tok.is(tok::l_paren))
Nico Weber7eecf4b2013-01-09 20:25:35 +00001977 // Skip category, if present.
1978 parseParens();
1979
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00001980 if (FormatTok->Tok.is(tok::less))
Nico Weber8696a8d2013-01-09 21:15:03 +00001981 parseObjCProtocolList();
Nico Weber7eecf4b2013-01-09 20:25:35 +00001982
Dinesh Dwivediea3aca82014-05-02 17:01:46 +00001983 if (FormatTok->Tok.is(tok::l_brace)) {
Daniel Jasperc1bc38e2015-09-29 14:57:55 +00001984 if (Style.BraceWrapping.AfterObjCDeclaration)
Dinesh Dwivediea3aca82014-05-02 17:01:46 +00001985 addUnwrappedLine();
Nico Weber9096fc02013-06-26 00:30:14 +00001986 parseBlock(/*MustBeDeclaration=*/true);
Dinesh Dwivediea3aca82014-05-02 17:01:46 +00001987 }
Nico Weber7eecf4b2013-01-09 20:25:35 +00001988
1989 // With instance variables, this puts '}' on its own line. Without instance
1990 // variables, this ends the @interface line.
1991 addUnwrappedLine();
1992
Nico Weber8696a8d2013-01-09 21:15:03 +00001993 parseObjCUntilAtEnd();
1994}
Nico Weber7eecf4b2013-01-09 20:25:35 +00001995
Nico Weber8696a8d2013-01-09 21:15:03 +00001996void UnwrappedLineParser::parseObjCProtocol() {
1997 nextToken();
Daniel Jasperd1ae3582013-03-20 12:37:50 +00001998 nextToken(); // protocol name
Nico Weber8696a8d2013-01-09 21:15:03 +00001999
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00002000 if (FormatTok->Tok.is(tok::less))
Nico Weber8696a8d2013-01-09 21:15:03 +00002001 parseObjCProtocolList();
2002
2003 // Check for protocol declaration.
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00002004 if (FormatTok->Tok.is(tok::semi)) {
Nico Weber8696a8d2013-01-09 21:15:03 +00002005 nextToken();
2006 return addUnwrappedLine();
2007 }
2008
2009 addUnwrappedLine();
2010 parseObjCUntilAtEnd();
Nico Weber7eecf4b2013-01-09 20:25:35 +00002011}
2012
Daniel Jasperfca735c2015-02-19 16:14:18 +00002013void UnwrappedLineParser::parseJavaScriptEs6ImportExport() {
Martin Probst053f1aa2016-04-19 14:55:37 +00002014 bool IsImport = FormatTok->is(Keywords.kw_import);
2015 assert(IsImport || FormatTok->is(tok::kw_export));
Daniel Jasper354aa512015-02-19 16:07:32 +00002016 nextToken();
Daniel Jasperfca735c2015-02-19 16:14:18 +00002017
Daniel Jasperec05fc72015-05-11 09:14:50 +00002018 // Consume the "default" in "export default class/function".
Daniel Jasper668c7bb2015-05-11 09:03:10 +00002019 if (FormatTok->is(tok::kw_default))
2020 nextToken();
Daniel Jasperec05fc72015-05-11 09:14:50 +00002021
Martin Probst5f8445b2016-04-24 22:05:09 +00002022 // Consume "async function", "function" and "default function", so that these
2023 // get parsed as free-standing JS functions, i.e. do not require a trailing
2024 // semicolon.
2025 if (FormatTok->is(Keywords.kw_async))
2026 nextToken();
Daniel Jasper668c7bb2015-05-11 09:03:10 +00002027 if (FormatTok->is(Keywords.kw_function)) {
2028 nextToken();
2029 return;
2030 }
2031
Martin Probst053f1aa2016-04-19 14:55:37 +00002032 // For imports, `export *`, `export {...}`, consume the rest of the line up
2033 // to the terminating `;`. For everything else, just return and continue
2034 // parsing the structural element, i.e. the declaration or expression for
2035 // `export default`.
2036 if (!IsImport && !FormatTok->isOneOf(tok::l_brace, tok::star) &&
2037 !FormatTok->isStringLiteral())
2038 return;
Daniel Jasperfca735c2015-02-19 16:14:18 +00002039
Martin Probstd40bca42017-01-09 08:56:36 +00002040 while (!eof()) {
2041 if (FormatTok->is(tok::semi))
2042 return;
2043 if (Line->Tokens.size() == 0) {
2044 // Common issue: Automatic Semicolon Insertion wrapped the line, so the
2045 // import statement should terminate.
2046 return;
2047 }
Daniel Jasperefc1a832016-01-07 08:53:35 +00002048 if (FormatTok->is(tok::l_brace)) {
2049 FormatTok->BlockKind = BK_Block;
2050 parseBracedList();
2051 } else {
2052 nextToken();
2053 }
Daniel Jasper354aa512015-02-19 16:07:32 +00002054 }
2055}
2056
Daniel Jasper3b203a62013-09-05 16:05:56 +00002057LLVM_ATTRIBUTE_UNUSED static void printDebugInfo(const UnwrappedLine &Line,
2058 StringRef Prefix = "") {
Daniel Jasper9fe0e8d2013-09-05 09:29:45 +00002059 llvm::dbgs() << Prefix << "Line(" << Line.Level << ")"
2060 << (Line.InPPDirective ? " MACRO" : "") << ": ";
2061 for (std::list<UnwrappedLineNode>::const_iterator I = Line.Tokens.begin(),
2062 E = Line.Tokens.end();
2063 I != E; ++I) {
Krasimir Georgiev91834222017-01-25 13:58:58 +00002064 llvm::dbgs() << I->Tok->Tok.getName() << "["
2065 << "T=" << I->Tok->Type
2066 << ", OC=" << I->Tok->OriginalColumn << "] ";
Daniel Jasper9fe0e8d2013-09-05 09:29:45 +00002067 }
2068 for (std::list<UnwrappedLineNode>::const_iterator I = Line.Tokens.begin(),
2069 E = Line.Tokens.end();
2070 I != E; ++I) {
2071 const UnwrappedLineNode &Node = *I;
2072 for (SmallVectorImpl<UnwrappedLine>::const_iterator
2073 I = Node.Children.begin(),
2074 E = Node.Children.end();
2075 I != E; ++I) {
2076 printDebugInfo(*I, "\nChild: ");
2077 }
2078 }
2079 llvm::dbgs() << "\n";
2080}
2081
Daniel Jasperf7935112012-12-03 18:12:45 +00002082void UnwrappedLineParser::addUnwrappedLine() {
Daniel Jasperdaffc0d2013-01-16 09:10:19 +00002083 if (Line->Tokens.empty())
Daniel Jasper7c85fde2013-01-08 14:56:18 +00002084 return;
Manuel Klimekab3dc002013-01-16 12:31:12 +00002085 DEBUG({
Daniel Jasper9fe0e8d2013-09-05 09:29:45 +00002086 if (CurrentLines == &Lines)
2087 printDebugInfo(*Line);
Manuel Klimekab3dc002013-01-16 12:31:12 +00002088 });
Benjamin Kramerc7551a42015-05-31 11:18:05 +00002089 CurrentLines->push_back(std::move(*Line));
Daniel Jasperdaffc0d2013-01-16 09:10:19 +00002090 Line->Tokens.clear();
Krasimir Georgiev85c37042017-03-01 16:38:08 +00002091 Line->MatchingOpeningBlockLineIndex = UnwrappedLine::kInvalidIndex;
Manuel Klimekd3b92fa2013-01-18 14:04:34 +00002092 if (CurrentLines == &Lines && !PreprocessorDirectives.empty()) {
Benjamin Kramerc7551a42015-05-31 11:18:05 +00002093 CurrentLines->append(
2094 std::make_move_iterator(PreprocessorDirectives.begin()),
2095 std::make_move_iterator(PreprocessorDirectives.end()));
Manuel Klimekd3b92fa2013-01-18 14:04:34 +00002096 PreprocessorDirectives.clear();
2097 }
Daniel Jasperf7935112012-12-03 18:12:45 +00002098}
2099
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00002100bool UnwrappedLineParser::eof() const { return FormatTok->Tok.is(tok::eof); }
Daniel Jasperf7935112012-12-03 18:12:45 +00002101
Daniel Jasperb05a81d2014-05-09 13:11:16 +00002102bool UnwrappedLineParser::isOnNewLine(const FormatToken &FormatTok) {
Manuel Klimek1fcbe672014-04-11 12:27:47 +00002103 return (Line->InPPDirective || FormatTok.HasUnescapedNewline) &&
2104 FormatTok.NewlinesBefore > 0;
2105}
2106
Krasimir Georgiev91834222017-01-25 13:58:58 +00002107// Checks if \p FormatTok is a line comment that continues the line comment
2108// section on \p Line.
2109static bool continuesLineComment(const FormatToken &FormatTok,
Krasimir Georgiev00c5c722017-02-02 15:32:19 +00002110 const UnwrappedLine &Line,
2111 llvm::Regex &CommentPragmasRegex) {
Krasimir Georgiev91834222017-01-25 13:58:58 +00002112 if (Line.Tokens.empty())
2113 return false;
Krasimir Georgiev84321612017-01-30 19:18:55 +00002114
Krasimir Georgiev00c5c722017-02-02 15:32:19 +00002115 StringRef IndentContent = FormatTok.TokenText;
2116 if (FormatTok.TokenText.startswith("//") ||
2117 FormatTok.TokenText.startswith("/*"))
2118 IndentContent = FormatTok.TokenText.substr(2);
2119 if (CommentPragmasRegex.match(IndentContent))
2120 return false;
2121
Krasimir Georgiev91834222017-01-25 13:58:58 +00002122 // If Line starts with a line comment, then FormatTok continues the comment
Krasimir Georgiev84321612017-01-30 19:18:55 +00002123 // section if its original column is greater or equal to the original start
Krasimir Georgiev91834222017-01-25 13:58:58 +00002124 // column of the line.
2125 //
Krasimir Georgiev84321612017-01-30 19:18:55 +00002126 // Define the min column token of a line as follows: if a line ends in '{' or
2127 // contains a '{' followed by a line comment, then the min column token is
2128 // that '{'. Otherwise, the min column token of the line is the first token of
2129 // the line.
2130 //
2131 // If Line starts with a token other than a line comment, then FormatTok
2132 // continues the comment section if its original column is greater than the
2133 // original start column of the min column token of the line.
Krasimir Georgiev91834222017-01-25 13:58:58 +00002134 //
2135 // For example, the second line comment continues the first in these cases:
Krasimir Georgievb6ccd382017-02-02 14:36:50 +00002136 //
Krasimir Georgiev91834222017-01-25 13:58:58 +00002137 // // first line
2138 // // second line
Krasimir Georgievb6ccd382017-02-02 14:36:50 +00002139 //
Krasimir Georgiev91834222017-01-25 13:58:58 +00002140 // and:
Krasimir Georgievb6ccd382017-02-02 14:36:50 +00002141 //
Krasimir Georgiev91834222017-01-25 13:58:58 +00002142 // // first line
2143 // // second line
Krasimir Georgievb6ccd382017-02-02 14:36:50 +00002144 //
Krasimir Georgiev91834222017-01-25 13:58:58 +00002145 // and:
Krasimir Georgievb6ccd382017-02-02 14:36:50 +00002146 //
Krasimir Georgiev91834222017-01-25 13:58:58 +00002147 // int i; // first line
2148 // // second line
Krasimir Georgievb6ccd382017-02-02 14:36:50 +00002149 //
Krasimir Georgiev84321612017-01-30 19:18:55 +00002150 // and:
Krasimir Georgievb6ccd382017-02-02 14:36:50 +00002151 //
Krasimir Georgiev84321612017-01-30 19:18:55 +00002152 // do { // first line
2153 // // second line
2154 // int i;
2155 // } while (true);
Krasimir Georgiev91834222017-01-25 13:58:58 +00002156 //
Krasimir Georgievb6ccd382017-02-02 14:36:50 +00002157 // and:
2158 //
2159 // enum {
2160 // a, // first line
2161 // // second line
2162 // b
2163 // };
2164 //
Krasimir Georgiev91834222017-01-25 13:58:58 +00002165 // The second line comment doesn't continue the first in these cases:
Krasimir Georgievb6ccd382017-02-02 14:36:50 +00002166 //
Krasimir Georgiev91834222017-01-25 13:58:58 +00002167 // // first line
2168 // // second line
Krasimir Georgievb6ccd382017-02-02 14:36:50 +00002169 //
Krasimir Georgiev91834222017-01-25 13:58:58 +00002170 // and:
Krasimir Georgievb6ccd382017-02-02 14:36:50 +00002171 //
Krasimir Georgiev91834222017-01-25 13:58:58 +00002172 // int i; // first line
2173 // // second line
Krasimir Georgievb6ccd382017-02-02 14:36:50 +00002174 //
Krasimir Georgiev84321612017-01-30 19:18:55 +00002175 // and:
Krasimir Georgievb6ccd382017-02-02 14:36:50 +00002176 //
Krasimir Georgiev84321612017-01-30 19:18:55 +00002177 // do { // first line
2178 // // second line
2179 // int i;
2180 // } while (true);
Krasimir Georgievb6ccd382017-02-02 14:36:50 +00002181 //
2182 // and:
2183 //
2184 // enum {
2185 // a, // first line
2186 // // second line
2187 // };
Krasimir Georgiev84321612017-01-30 19:18:55 +00002188 const FormatToken *MinColumnToken = Line.Tokens.front().Tok;
2189
2190 // Scan for '{//'. If found, use the column of '{' as a min column for line
2191 // comment section continuation.
2192 const FormatToken *PreviousToken = nullptr;
Krasimir Georgievd86c25d2017-03-10 13:09:29 +00002193 for (const UnwrappedLineNode &Node : Line.Tokens) {
Krasimir Georgiev84321612017-01-30 19:18:55 +00002194 if (PreviousToken && PreviousToken->is(tok::l_brace) &&
2195 isLineComment(*Node.Tok)) {
2196 MinColumnToken = PreviousToken;
2197 break;
2198 }
2199 PreviousToken = Node.Tok;
Krasimir Georgievb6ccd382017-02-02 14:36:50 +00002200
2201 // Grab the last newline preceding a token in this unwrapped line.
2202 if (Node.Tok->NewlinesBefore > 0) {
2203 MinColumnToken = Node.Tok;
2204 }
Krasimir Georgiev84321612017-01-30 19:18:55 +00002205 }
2206 if (PreviousToken && PreviousToken->is(tok::l_brace)) {
2207 MinColumnToken = PreviousToken;
2208 }
2209
Krasimir Georgiev91834222017-01-25 13:58:58 +00002210 unsigned MinContinueColumn =
Krasimir Georgiev84321612017-01-30 19:18:55 +00002211 MinColumnToken->OriginalColumn +
2212 (isLineComment(*MinColumnToken) ? 0 : 1);
Krasimir Georgiev91834222017-01-25 13:58:58 +00002213 return isLineComment(FormatTok) && FormatTok.NewlinesBefore == 1 &&
2214 isLineComment(*(Line.Tokens.back().Tok)) &&
2215 FormatTok.OriginalColumn >= MinContinueColumn;
2216}
2217
Manuel Klimekf92f7bc2013-01-22 16:31:55 +00002218void UnwrappedLineParser::flushComments(bool NewlineBeforeNext) {
2219 bool JustComments = Line->Tokens.empty();
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00002220 for (SmallVectorImpl<FormatToken *>::const_iterator
Manuel Klimekf92f7bc2013-01-22 16:31:55 +00002221 I = CommentsBeforeNextToken.begin(),
2222 E = CommentsBeforeNextToken.end();
2223 I != E; ++I) {
Krasimir Georgiev91834222017-01-25 13:58:58 +00002224 // Line comments that belong to the same line comment section are put on the
2225 // same line since later we might want to reflow content between them.
Krasimir Georgiev753625b2017-01-31 13:32:38 +00002226 // Additional fine-grained breaking of line comment sections is controlled
2227 // by the class BreakableLineCommentSection in case it is desirable to keep
2228 // several line comment sections in the same unwrapped line.
2229 //
2230 // FIXME: Consider putting separate line comment sections as children to the
2231 // unwrapped line instead.
Krasimir Georgiev00c5c722017-02-02 15:32:19 +00002232 (*I)->ContinuesLineCommentSection =
2233 continuesLineComment(**I, *Line, CommentPragmasRegex);
Krasimir Georgievb6ccd382017-02-02 14:36:50 +00002234 if (isOnNewLine(**I) && JustComments && !(*I)->ContinuesLineCommentSection)
Manuel Klimekf92f7bc2013-01-22 16:31:55 +00002235 addUnwrappedLine();
Manuel Klimekf92f7bc2013-01-22 16:31:55 +00002236 pushToken(*I);
2237 }
Daniel Jaspere60cba12015-05-13 11:35:53 +00002238 if (NewlineBeforeNext && JustComments)
Manuel Klimekf92f7bc2013-01-22 16:31:55 +00002239 addUnwrappedLine();
Manuel Klimekf92f7bc2013-01-22 16:31:55 +00002240 CommentsBeforeNextToken.clear();
2241}
2242
Daniel Jasperf7935112012-12-03 18:12:45 +00002243void UnwrappedLineParser::nextToken() {
2244 if (eof())
2245 return;
Manuel Klimek1fcbe672014-04-11 12:27:47 +00002246 flushComments(isOnNewLine(*FormatTok));
Manuel Klimekf92f7bc2013-01-22 16:31:55 +00002247 pushToken(FormatTok);
Daniel Jasper1dcbbcfc2016-03-14 19:21:36 +00002248 if (Style.Language != FormatStyle::LK_JavaScript)
2249 readToken();
2250 else
2251 readTokenWithJavaScriptASI();
Manuel Klimek1abf7892013-01-04 23:34:14 +00002252}
2253
Daniel Jasperb9a49902016-01-09 15:56:28 +00002254const FormatToken *UnwrappedLineParser::getPreviousToken() {
2255 // FIXME: This is a dirty way to access the previous token. Find a better
2256 // solution.
2257 if (!Line || Line->Tokens.empty())
2258 return nullptr;
2259 return Line->Tokens.back().Tok;
2260}
2261
Krasimir Georgievf62f9582017-02-08 10:30:44 +00002262void UnwrappedLineParser::distributeComments(
2263 const SmallVectorImpl<FormatToken *> &Comments,
2264 const FormatToken *NextTok) {
2265 // Whether or not a line comment token continues a line is controlled by
2266 // the method continuesLineComment, with the following caveat:
2267 //
2268 // Define a trail of Comments to be a nonempty proper postfix of Comments such
2269 // that each comment line from the trail is aligned with the next token, if
2270 // the next token exists. If a trail exists, the beginning of the maximal
2271 // trail is marked as a start of a new comment section.
2272 //
2273 // For example in this code:
2274 //
2275 // int a; // line about a
2276 // // line 1 about b
2277 // // line 2 about b
2278 // int b;
2279 //
2280 // the two lines about b form a maximal trail, so there are two sections, the
2281 // first one consisting of the single comment "// line about a" and the
2282 // second one consisting of the next two comments.
2283 if (Comments.empty())
2284 return;
2285 bool ShouldPushCommentsInCurrentLine = true;
2286 bool HasTrailAlignedWithNextToken = false;
2287 unsigned StartOfTrailAlignedWithNextToken = 0;
2288 if (NextTok) {
2289 // We are skipping the first element intentionally.
2290 for (unsigned i = Comments.size() - 1; i > 0; --i) {
2291 if (Comments[i]->OriginalColumn == NextTok->OriginalColumn) {
2292 HasTrailAlignedWithNextToken = true;
2293 StartOfTrailAlignedWithNextToken = i;
2294 }
2295 }
2296 }
2297 for (unsigned i = 0, e = Comments.size(); i < e; ++i) {
2298 FormatToken *FormatTok = Comments[i];
2299 if (HasTrailAlignedWithNextToken &&
2300 i == StartOfTrailAlignedWithNextToken) {
2301 FormatTok->ContinuesLineCommentSection = false;
2302 } else {
2303 FormatTok->ContinuesLineCommentSection =
2304 continuesLineComment(*FormatTok, *Line, CommentPragmasRegex);
2305 }
2306 if (!FormatTok->ContinuesLineCommentSection &&
2307 (isOnNewLine(*FormatTok) || FormatTok->IsFirst)) {
2308 ShouldPushCommentsInCurrentLine = false;
2309 }
2310 if (ShouldPushCommentsInCurrentLine) {
2311 pushToken(FormatTok);
2312 } else {
2313 CommentsBeforeNextToken.push_back(FormatTok);
2314 }
2315 }
2316}
2317
Manuel Klimek1abf7892013-01-04 23:34:14 +00002318void UnwrappedLineParser::readToken() {
Krasimir Georgievf62f9582017-02-08 10:30:44 +00002319 SmallVector<FormatToken *, 1> Comments;
Manuel Klimekf92f7bc2013-01-22 16:31:55 +00002320 do {
2321 FormatTok = Tokens->getNextToken();
Alexander Kornienkoc2ee9cf2014-03-13 13:59:48 +00002322 assert(FormatTok);
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00002323 while (!Line->InPPDirective && FormatTok->Tok.is(tok::hash) &&
2324 (FormatTok->HasUnescapedNewline || FormatTok->IsFirst)) {
Krasimir Georgievf62f9582017-02-08 10:30:44 +00002325 distributeComments(Comments, FormatTok);
2326 Comments.clear();
Manuel Klimekf92f7bc2013-01-22 16:31:55 +00002327 // If there is an unfinished unwrapped line, we flush the preprocessor
2328 // directives only after that unwrapped line was finished later.
Daniel Jasper29d39d52015-02-08 09:34:49 +00002329 bool SwitchToPreprocessorLines = !Line->Tokens.empty();
Manuel Klimekf92f7bc2013-01-22 16:31:55 +00002330 ScopedLineState BlockState(*this, SwitchToPreprocessorLines);
Alexander Kornienkob1be9d62013-04-03 12:38:53 +00002331 // Comments stored before the preprocessor directive need to be output
2332 // before the preprocessor directive, at the same level as the
2333 // preprocessor directive, as we consider them to apply to the directive.
Manuel Klimek1fcbe672014-04-11 12:27:47 +00002334 flushComments(isOnNewLine(*FormatTok));
Manuel Klimekf92f7bc2013-01-22 16:31:55 +00002335 parsePPDirective();
2336 }
Manuel Klimek68b03042014-04-14 09:14:11 +00002337 while (FormatTok->Type == TT_ConflictStart ||
2338 FormatTok->Type == TT_ConflictEnd ||
2339 FormatTok->Type == TT_ConflictAlternative) {
2340 if (FormatTok->Type == TT_ConflictStart) {
2341 conditionalCompilationStart(/*Unreachable=*/false);
2342 } else if (FormatTok->Type == TT_ConflictAlternative) {
2343 conditionalCompilationAlternative();
Daniel Jasperb05a81d2014-05-09 13:11:16 +00002344 } else if (FormatTok->Type == TT_ConflictEnd) {
Manuel Klimek68b03042014-04-14 09:14:11 +00002345 conditionalCompilationEnd();
2346 }
2347 FormatTok = Tokens->getNextToken();
2348 FormatTok->MustBreakBefore = true;
2349 }
Alexander Kornienkof2e02122013-05-24 18:24:24 +00002350
2351 if (!PPStack.empty() && (PPStack.back() == PP_Unreachable) &&
2352 !Line->InPPDirective) {
2353 continue;
2354 }
2355
Krasimir Georgievf62f9582017-02-08 10:30:44 +00002356 if (!FormatTok->Tok.is(tok::comment)) {
2357 distributeComments(Comments, FormatTok);
2358 Comments.clear();
Manuel Klimekf92f7bc2013-01-22 16:31:55 +00002359 return;
Manuel Klimekf92f7bc2013-01-22 16:31:55 +00002360 }
Krasimir Georgievf62f9582017-02-08 10:30:44 +00002361
2362 Comments.push_back(FormatTok);
Manuel Klimekf92f7bc2013-01-22 16:31:55 +00002363 } while (!eof());
Krasimir Georgievf62f9582017-02-08 10:30:44 +00002364
2365 distributeComments(Comments, nullptr);
2366 Comments.clear();
Manuel Klimekf92f7bc2013-01-22 16:31:55 +00002367}
2368
Manuel Klimek15dfe7a2013-05-28 11:55:06 +00002369void UnwrappedLineParser::pushToken(FormatToken *Tok) {
Daniel Jasper9fe0e8d2013-09-05 09:29:45 +00002370 Line->Tokens.push_back(UnwrappedLineNode(Tok));
Manuel Klimekf92f7bc2013-01-22 16:31:55 +00002371 if (MustBreakBeforeNextToken) {
Daniel Jasper9fe0e8d2013-09-05 09:29:45 +00002372 Line->Tokens.back().Tok->MustBreakBefore = true;
Manuel Klimekf92f7bc2013-01-22 16:31:55 +00002373 MustBreakBeforeNextToken = false;
Manuel Klimek1abf7892013-01-04 23:34:14 +00002374 }
Daniel Jasperf7935112012-12-03 18:12:45 +00002375}
2376
Daniel Jasper8d1832e2013-01-07 13:26:07 +00002377} // end namespace format
2378} // end namespace clang