blob: a438a53c370f891fe3f89606b8f30886915f2d95 [file] [log] [blame]
Daniel Jasperbac016b2012-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 Jasperbac016b2012-12-03 18:12:45 +000014//===----------------------------------------------------------------------===//
15
Manuel Klimek8fa37992013-01-16 12:31:12 +000016#define DEBUG_TYPE "format-parser"
Daniel Jasperbac016b2012-12-03 18:12:45 +000017
Chandler Carruthb1ba0ef2013-01-19 08:09:44 +000018#include "UnwrappedLineParser.h"
Manuel Klimek8fa37992013-01-16 12:31:12 +000019#include "clang/Basic/Diagnostic.h"
20#include "llvm/Support/Debug.h"
Manuel Klimek8fa37992013-01-16 12:31:12 +000021
Daniel Jasperbac016b2012-12-03 18:12:45 +000022namespace clang {
23namespace format {
24
Manuel Klimek70b03f42013-01-23 09:32:48 +000025class ScopedDeclarationState {
26public:
27 ScopedDeclarationState(UnwrappedLine &Line, std::vector<bool> &Stack,
28 bool MustBeDeclaration)
29 : Line(Line), Stack(Stack) {
Manuel Klimek70b03f42013-01-23 09:32:48 +000030 Line.MustBeDeclaration = MustBeDeclaration;
Manuel Klimek836b58f2013-01-23 11:03:04 +000031 Stack.push_back(MustBeDeclaration);
Manuel Klimek70b03f42013-01-23 09:32:48 +000032 }
33 ~ScopedDeclarationState() {
Manuel Klimek70b03f42013-01-23 09:32:48 +000034 Stack.pop_back();
Manuel Klimeka32a7fd2013-01-23 14:08:21 +000035 if (!Stack.empty())
36 Line.MustBeDeclaration = Stack.back();
37 else
38 Line.MustBeDeclaration = true;
Manuel Klimek70b03f42013-01-23 09:32:48 +000039 }
40private:
41 UnwrappedLine &Line;
42 std::vector<bool> &Stack;
43};
44
Manuel Klimekd4397b92013-01-04 23:34:14 +000045class ScopedMacroState : public FormatTokenSource {
46public:
47 ScopedMacroState(UnwrappedLine &Line, FormatTokenSource *&TokenSource,
48 FormatToken &ResetToken)
49 : Line(Line), TokenSource(TokenSource), ResetToken(ResetToken),
Manuel Klimekc37b4d62013-01-05 22:14:16 +000050 PreviousLineLevel(Line.Level), PreviousTokenSource(TokenSource) {
Manuel Klimekd4397b92013-01-04 23:34:14 +000051 TokenSource = this;
Manuel Klimekc37b4d62013-01-05 22:14:16 +000052 Line.Level = 0;
Manuel Klimekd4397b92013-01-04 23:34:14 +000053 Line.InPPDirective = true;
54 }
55
56 ~ScopedMacroState() {
57 TokenSource = PreviousTokenSource;
58 ResetToken = Token;
59 Line.InPPDirective = false;
Manuel Klimekc37b4d62013-01-05 22:14:16 +000060 Line.Level = PreviousLineLevel;
Manuel Klimekd4397b92013-01-04 23:34:14 +000061 }
62
63 virtual FormatToken getNextToken() {
Manuel Klimekdd5b1012013-01-07 10:03:37 +000064 // The \c UnwrappedLineParser guards against this by never calling
65 // \c getNextToken() after it has encountered the first eof token.
66 assert(!eof());
Manuel Klimekd4397b92013-01-04 23:34:14 +000067 Token = PreviousTokenSource->getNextToken();
68 if (eof())
69 return createEOF();
70 return Token;
71 }
72
73private:
74 bool eof() {
75 return Token.NewlinesBefore > 0 && Token.HasUnescapedNewline;
76 }
77
78 FormatToken createEOF() {
79 FormatToken FormatTok;
80 FormatTok.Tok.startToken();
81 FormatTok.Tok.setKind(tok::eof);
82 return FormatTok;
83 }
84
85 UnwrappedLine &Line;
86 FormatTokenSource *&TokenSource;
87 FormatToken &ResetToken;
Manuel Klimekc37b4d62013-01-05 22:14:16 +000088 unsigned PreviousLineLevel;
Manuel Klimekd4397b92013-01-04 23:34:14 +000089 FormatTokenSource *PreviousTokenSource;
90
91 FormatToken Token;
92};
93
Manuel Klimekbb42bf12013-01-10 11:52:21 +000094class ScopedLineState {
95public:
Manuel Klimek525fe162013-01-18 14:04:34 +000096 ScopedLineState(UnwrappedLineParser &Parser,
97 bool SwitchToPreprocessorLines = false)
98 : Parser(Parser), SwitchToPreprocessorLines(SwitchToPreprocessorLines) {
99 if (SwitchToPreprocessorLines)
100 Parser.CurrentLines = &Parser.PreprocessorDirectives;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000101 PreBlockLine = Parser.Line.take();
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000102 Parser.Line.reset(new UnwrappedLine());
103 Parser.Line->Level = PreBlockLine->Level;
104 Parser.Line->InPPDirective = PreBlockLine->InPPDirective;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000105 }
106
107 ~ScopedLineState() {
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000108 if (!Parser.Line->Tokens.empty()) {
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000109 Parser.addUnwrappedLine();
110 }
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000111 assert(Parser.Line->Tokens.empty());
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000112 Parser.Line.reset(PreBlockLine);
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000113 Parser.MustBreakBeforeNextToken = true;
Manuel Klimek525fe162013-01-18 14:04:34 +0000114 if (SwitchToPreprocessorLines)
115 Parser.CurrentLines = &Parser.Lines;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000116 }
117
118private:
119 UnwrappedLineParser &Parser;
Manuel Klimek525fe162013-01-18 14:04:34 +0000120 const bool SwitchToPreprocessorLines;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000121
122 UnwrappedLine *PreBlockLine;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000123};
124
Alexander Kornienko3048aea2013-01-10 15:05:09 +0000125UnwrappedLineParser::UnwrappedLineParser(
126 clang::DiagnosticsEngine &Diag, const FormatStyle &Style,
127 FormatTokenSource &Tokens, UnwrappedLineConsumer &Callback)
Manuel Klimek525fe162013-01-18 14:04:34 +0000128 : Line(new UnwrappedLine), MustBreakBeforeNextToken(false),
129 CurrentLines(&Lines), Diag(Diag), Style(Style), Tokens(&Tokens),
130 Callback(Callback) {}
Daniel Jasperbac016b2012-12-03 18:12:45 +0000131
Alexander Kornienkocff563c2012-12-04 17:27:50 +0000132bool UnwrappedLineParser::parse() {
Manuel Klimek8fa37992013-01-16 12:31:12 +0000133 DEBUG(llvm::dbgs() << "----\n");
Manuel Klimekd4397b92013-01-04 23:34:14 +0000134 readToken();
Manuel Klimek525fe162013-01-18 14:04:34 +0000135 bool Error = parseFile();
136 for (std::vector<UnwrappedLine>::iterator I = Lines.begin(),
137 E = Lines.end();
138 I != E; ++I) {
139 Callback.consumeUnwrappedLine(*I);
140 }
Daniel Jasper516fb312013-03-01 18:11:39 +0000141
142 // Create line with eof token.
143 pushToken(FormatTok);
144 Callback.consumeUnwrappedLine(*Line);
145
Manuel Klimek525fe162013-01-18 14:04:34 +0000146 return Error;
Manuel Klimekd4397b92013-01-04 23:34:14 +0000147}
148
149bool UnwrappedLineParser::parseFile() {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000150 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
151 /*MustBeDeclaration=*/ true);
Manuel Klimeka5342db2013-01-06 20:07:31 +0000152 bool Error = parseLevel(/*HasOpeningBrace=*/false);
Manuel Klimekd4397b92013-01-04 23:34:14 +0000153 // Make sure to format the remaining tokens.
Manuel Klimek86721d22013-01-22 16:31:55 +0000154 flushComments(true);
Manuel Klimekd4397b92013-01-04 23:34:14 +0000155 addUnwrappedLine();
156 return Error;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000157}
158
Manuel Klimeka5342db2013-01-06 20:07:31 +0000159bool UnwrappedLineParser::parseLevel(bool HasOpeningBrace) {
Alexander Kornienkocff563c2012-12-04 17:27:50 +0000160 bool Error = false;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000161 do {
162 switch (FormatTok.Tok.getKind()) {
Daniel Jasperbac016b2012-12-03 18:12:45 +0000163 case tok::comment:
Daniel Jasper05b1ac82012-12-17 11:29:41 +0000164 nextToken();
165 addUnwrappedLine();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000166 break;
167 case tok::l_brace:
Manuel Klimek70b03f42013-01-23 09:32:48 +0000168 // FIXME: Add parameter whether this can happen - if this happens, we must
169 // be in a non-declaration context.
170 Error |= parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000171 addUnwrappedLine();
172 break;
173 case tok::r_brace:
Manuel Klimeka5342db2013-01-06 20:07:31 +0000174 if (HasOpeningBrace) {
175 return false;
176 } else {
Alexander Kornienko3048aea2013-01-10 15:05:09 +0000177 Diag.Report(FormatTok.Tok.getLocation(),
178 Diag.getCustomDiagID(clang::DiagnosticsEngine::Error,
Alexander Kornienko276a2092013-01-11 16:03:45 +0000179 "unexpected '}'"));
Manuel Klimeka5342db2013-01-06 20:07:31 +0000180 Error = true;
181 nextToken();
182 addUnwrappedLine();
183 }
184 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000185 default:
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000186 parseStructuralElement();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000187 break;
188 }
189 } while (!eof());
Alexander Kornienkocff563c2012-12-04 17:27:50 +0000190 return Error;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000191}
192
Nico Weberd74fcdb2013-02-10 20:35:35 +0000193bool UnwrappedLineParser::parseBlock(bool MustBeDeclaration,
194 unsigned AddLevels) {
Alexander Kornienkoa3a2b3a2012-12-06 17:49:17 +0000195 assert(FormatTok.Tok.is(tok::l_brace) && "'{' expected");
Daniel Jasperbac016b2012-12-03 18:12:45 +0000196 nextToken();
197
Manuel Klimek2f1ac412013-01-21 16:42:44 +0000198 addUnwrappedLine();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000199
Manuel Klimek70b03f42013-01-23 09:32:48 +0000200 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
201 MustBeDeclaration);
Manuel Klimek2f1ac412013-01-21 16:42:44 +0000202 Line->Level += AddLevels;
203 parseLevel(/*HasOpeningBrace=*/true);
Alexander Kornienko15757312012-12-06 18:03:27 +0000204
Manuel Klimek86721d22013-01-22 16:31:55 +0000205 if (!FormatTok.Tok.is(tok::r_brace)) {
206 Line->Level -= AddLevels;
Manuel Klimek2f1ac412013-01-21 16:42:44 +0000207 return true;
Manuel Klimek86721d22013-01-22 16:31:55 +0000208 }
Alexander Kornienko393b0082012-12-04 15:40:36 +0000209
Manuel Klimekde768542013-01-07 18:10:23 +0000210 nextToken(); // Munch the closing brace.
Manuel Klimek86721d22013-01-22 16:31:55 +0000211 Line->Level -= AddLevels;
Alexander Kornienkocff563c2012-12-04 17:27:50 +0000212 return false;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000213}
214
215void UnwrappedLineParser::parsePPDirective() {
Manuel Klimeka080a182013-01-02 16:30:12 +0000216 assert(FormatTok.Tok.is(tok::hash) && "'#' expected");
Manuel Klimek526ed112013-01-09 15:25:02 +0000217 ScopedMacroState MacroState(*Line, Tokens, FormatTok);
Manuel Klimeka080a182013-01-02 16:30:12 +0000218 nextToken();
219
Manuel Klimeka080a182013-01-02 16:30:12 +0000220 if (FormatTok.Tok.getIdentifierInfo() == NULL) {
Manuel Klimekbd04f2a2013-01-31 15:58:48 +0000221 parsePPUnknown();
Manuel Klimeka080a182013-01-02 16:30:12 +0000222 return;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000223 }
Manuel Klimeka080a182013-01-02 16:30:12 +0000224
Manuel Klimekd4397b92013-01-04 23:34:14 +0000225 switch (FormatTok.Tok.getIdentifierInfo()->getPPKeywordID()) {
226 case tok::pp_define:
227 parsePPDefine();
228 break;
229 default:
230 parsePPUnknown();
231 break;
232 }
233}
234
235void UnwrappedLineParser::parsePPDefine() {
236 nextToken();
237
238 if (FormatTok.Tok.getKind() != tok::identifier) {
239 parsePPUnknown();
240 return;
241 }
242 nextToken();
Manuel Klimek7ccbc212013-01-23 14:37:36 +0000243 if (FormatTok.Tok.getKind() == tok::l_paren &&
244 FormatTok.WhiteSpaceLength == 0) {
Manuel Klimekd4397b92013-01-04 23:34:14 +0000245 parseParens();
246 }
247 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000248 Line->Level = 1;
Manuel Klimekc3d0c822013-01-07 09:34:28 +0000249
250 // Errors during a preprocessor directive can only affect the layout of the
251 // preprocessor directive, and thus we ignore them. An alternative approach
252 // would be to use the same approach we use on the file level (no
253 // re-indentation if there was a structural error) within the macro
254 // definition.
Manuel Klimekd4397b92013-01-04 23:34:14 +0000255 parseFile();
256}
257
258void UnwrappedLineParser::parsePPUnknown() {
Manuel Klimeka080a182013-01-02 16:30:12 +0000259 do {
Manuel Klimeka080a182013-01-02 16:30:12 +0000260 nextToken();
261 } while (!eof());
262 addUnwrappedLine();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000263}
264
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000265void UnwrappedLineParser::parseStructuralElement() {
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000266 assert(!FormatTok.Tok.is(tok::l_brace));
Dmitri Gribenko1f94f2b2012-12-30 21:27:25 +0000267 int TokenNumber = 0;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000268 switch (FormatTok.Tok.getKind()) {
Nico Weber6092d4e2013-01-07 19:05:19 +0000269 case tok::at:
270 nextToken();
Nico Weberd74fcdb2013-02-10 20:35:35 +0000271 if (FormatTok.Tok.is(tok::l_brace)) {
272 parseBracedList();
273 break;
274 }
Nico Weber6092d4e2013-01-07 19:05:19 +0000275 switch (FormatTok.Tok.getObjCKeywordID()) {
276 case tok::objc_public:
277 case tok::objc_protected:
278 case tok::objc_package:
279 case tok::objc_private:
280 return parseAccessSpecifier();
Nico Weber27d13672013-01-09 20:25:35 +0000281 case tok::objc_interface:
Nico Weber50767d82013-01-09 23:25:37 +0000282 case tok::objc_implementation:
283 return parseObjCInterfaceOrImplementation();
Nico Weber1abe6ea2013-01-09 21:15:03 +0000284 case tok::objc_protocol:
285 return parseObjCProtocol();
Nico Weber049c4472013-01-09 21:42:32 +0000286 case tok::objc_end:
287 return; // Handled by the caller.
Nico Weberb530fa32013-01-10 00:25:19 +0000288 case tok::objc_optional:
289 case tok::objc_required:
290 nextToken();
291 addUnwrappedLine();
292 return;
Nico Weber6092d4e2013-01-07 19:05:19 +0000293 default:
294 break;
295 }
296 break;
Alexander Kornienko15757312012-12-06 18:03:27 +0000297 case tok::kw_namespace:
298 parseNamespace();
299 return;
Dmitri Gribenko1f94f2b2012-12-30 21:27:25 +0000300 case tok::kw_inline:
301 nextToken();
302 TokenNumber++;
303 if (FormatTok.Tok.is(tok::kw_namespace)) {
304 parseNamespace();
305 return;
306 }
307 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000308 case tok::kw_public:
309 case tok::kw_protected:
310 case tok::kw_private:
Daniel Jasperbac016b2012-12-03 18:12:45 +0000311 parseAccessSpecifier();
312 return;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000313 case tok::kw_if:
314 parseIfThenElse();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000315 return;
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000316 case tok::kw_for:
317 case tok::kw_while:
318 parseForOrWhileLoop();
319 return;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000320 case tok::kw_do:
321 parseDoWhile();
322 return;
323 case tok::kw_switch:
324 parseSwitch();
325 return;
326 case tok::kw_default:
327 nextToken();
328 parseLabel();
329 return;
330 case tok::kw_case:
331 parseCaseLabel();
332 return;
Manuel Klimekc44ee892013-01-21 10:07:49 +0000333 case tok::kw_return:
334 parseReturn();
335 return;
Manuel Klimekd19dc2d2013-01-21 14:32:05 +0000336 case tok::kw_extern:
337 nextToken();
338 if (FormatTok.Tok.is(tok::string_literal)) {
339 nextToken();
340 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000341 parseBlock(/*MustBeDeclaration=*/ true, 0);
Manuel Klimekd19dc2d2013-01-21 14:32:05 +0000342 addUnwrappedLine();
343 return;
344 }
345 }
346 // In all other cases, parse the declaration.
347 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000348 default:
349 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000350 }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000351 do {
352 ++TokenNumber;
353 switch (FormatTok.Tok.getKind()) {
Nico Weberd74fcdb2013-02-10 20:35:35 +0000354 case tok::at:
355 nextToken();
356 if (FormatTok.Tok.is(tok::l_brace))
357 parseBracedList();
358 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000359 case tok::kw_enum:
360 parseEnum();
Manuel Klimek308232c2013-01-21 19:17:52 +0000361 break;
Alexander Kornienkod8818752013-01-16 11:43:46 +0000362 case tok::kw_struct:
363 case tok::kw_union:
Manuel Klimekde768542013-01-07 18:10:23 +0000364 case tok::kw_class:
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000365 parseRecord();
366 // A record declaration or definition is always the start of a structural
367 // element.
368 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000369 case tok::semi:
370 nextToken();
371 addUnwrappedLine();
372 return;
Alexander Kornienkod8818752013-01-16 11:43:46 +0000373 case tok::r_brace:
374 addUnwrappedLine();
375 return;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000376 case tok::l_paren:
377 parseParens();
378 break;
379 case tok::l_brace:
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000380 // A block outside of parentheses must be the last part of a
381 // structural element.
382 // FIXME: Figure out cases where this is not true, and add projections for
383 // them (the one we know is missing are lambdas).
Manuel Klimek70b03f42013-01-23 09:32:48 +0000384 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000385 addUnwrappedLine();
386 return;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000387 case tok::identifier:
Daniel Jasperbac016b2012-12-03 18:12:45 +0000388 nextToken();
389 if (TokenNumber == 1 && FormatTok.Tok.is(tok::colon)) {
390 parseLabel();
391 return;
392 }
393 break;
Daniel Jasper05b1ac82012-12-17 11:29:41 +0000394 case tok::equal:
395 nextToken();
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000396 if (FormatTok.Tok.is(tok::l_brace)) {
397 parseBracedList();
398 }
Daniel Jasper05b1ac82012-12-17 11:29:41 +0000399 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000400 default:
401 nextToken();
402 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000403 }
404 } while (!eof());
405}
406
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000407void UnwrappedLineParser::parseBracedList() {
408 nextToken();
409
410 do {
411 switch (FormatTok.Tok.getKind()) {
412 case tok::l_brace:
413 parseBracedList();
414 break;
415 case tok::r_brace:
416 nextToken();
417 return;
418 default:
419 nextToken();
420 break;
421 }
422 } while (!eof());
423}
424
Manuel Klimekc44ee892013-01-21 10:07:49 +0000425void UnwrappedLineParser::parseReturn() {
426 nextToken();
427
428 do {
429 switch (FormatTok.Tok.getKind()) {
430 case tok::l_brace:
431 parseBracedList();
432 break;
433 case tok::l_paren:
434 parseParens();
435 break;
436 case tok::r_brace:
437 // Assume missing ';'.
438 addUnwrappedLine();
439 return;
440 case tok::semi:
441 nextToken();
442 addUnwrappedLine();
443 return;
444 default:
445 nextToken();
446 break;
447 }
448 } while (!eof());
449}
450
Daniel Jasperbac016b2012-12-03 18:12:45 +0000451void UnwrappedLineParser::parseParens() {
452 assert(FormatTok.Tok.is(tok::l_paren) && "'(' expected.");
453 nextToken();
454 do {
455 switch (FormatTok.Tok.getKind()) {
456 case tok::l_paren:
457 parseParens();
458 break;
459 case tok::r_paren:
460 nextToken();
461 return;
Nico Weber2afbe522013-02-10 04:38:23 +0000462 case tok::l_brace: {
463 nextToken();
464 ScopedLineState LineState(*this);
465 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
466 /*MustBeDeclaration=*/ false);
467 Line->Level += 1;
468 parseLevel(/*HasOpeningBrace=*/ true);
469 Line->Level -= 1;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000470 break;
Nico Weber2afbe522013-02-10 04:38:23 +0000471 }
Nico Weberd74fcdb2013-02-10 20:35:35 +0000472 case tok::at:
473 nextToken();
474 if (FormatTok.Tok.is(tok::l_brace))
475 parseBracedList();
476 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000477 default:
478 nextToken();
479 break;
480 }
481 } while (!eof());
482}
483
484void UnwrappedLineParser::parseIfThenElse() {
485 assert(FormatTok.Tok.is(tok::kw_if) && "'if' expected");
486 nextToken();
Manuel Klimekd4658432013-01-11 18:28:36 +0000487 if (FormatTok.Tok.is(tok::l_paren))
488 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000489 bool NeedsUnwrappedLine = false;
490 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000491 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000492 NeedsUnwrappedLine = true;
493 } else {
494 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000495 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000496 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000497 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000498 }
499 if (FormatTok.Tok.is(tok::kw_else)) {
500 nextToken();
501 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000502 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000503 addUnwrappedLine();
504 } else if (FormatTok.Tok.is(tok::kw_if)) {
505 parseIfThenElse();
506 } else {
507 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000508 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000509 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000510 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000511 }
512 } else if (NeedsUnwrappedLine) {
513 addUnwrappedLine();
514 }
515}
516
Alexander Kornienko15757312012-12-06 18:03:27 +0000517void UnwrappedLineParser::parseNamespace() {
518 assert(FormatTok.Tok.is(tok::kw_namespace) && "'namespace' expected");
519 nextToken();
520 if (FormatTok.Tok.is(tok::identifier))
521 nextToken();
522 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000523 parseBlock(/*MustBeDeclaration=*/ true, 0);
Manuel Klimek7fc2db02013-02-06 16:08:09 +0000524 // Munch the semicolon after a namespace. This is more common than one would
525 // think. Puttin the semicolon into its own line is very ugly.
526 if (FormatTok.Tok.is(tok::semi))
527 nextToken();
Alexander Kornienko15757312012-12-06 18:03:27 +0000528 addUnwrappedLine();
529 }
530 // FIXME: Add error handling.
531}
532
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000533void UnwrappedLineParser::parseForOrWhileLoop() {
534 assert((FormatTok.Tok.is(tok::kw_for) || FormatTok.Tok.is(tok::kw_while)) &&
535 "'for' or 'while' expected");
536 nextToken();
Manuel Klimek6eca03f2013-01-11 19:23:05 +0000537 if (FormatTok.Tok.is(tok::l_paren))
538 parseParens();
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000539 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000540 parseBlock(/*MustBeDeclaration=*/ false);
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000541 addUnwrappedLine();
542 } else {
543 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000544 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000545 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000546 --Line->Level;
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000547 }
548}
549
Daniel Jasperbac016b2012-12-03 18:12:45 +0000550void UnwrappedLineParser::parseDoWhile() {
551 assert(FormatTok.Tok.is(tok::kw_do) && "'do' expected");
552 nextToken();
553 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000554 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000555 } else {
556 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000557 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000558 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000559 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000560 }
561
Alexander Kornienko393b0082012-12-04 15:40:36 +0000562 // FIXME: Add error handling.
563 if (!FormatTok.Tok.is(tok::kw_while)) {
564 addUnwrappedLine();
565 return;
566 }
567
Daniel Jasperbac016b2012-12-03 18:12:45 +0000568 nextToken();
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000569 parseStructuralElement();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000570}
571
572void UnwrappedLineParser::parseLabel() {
Daniel Jasper89a0daa2013-02-12 20:17:17 +0000573 if (FormatTok.Tok.isNot(tok::colon))
574 return;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000575 nextToken();
Manuel Klimek526ed112013-01-09 15:25:02 +0000576 unsigned OldLineLevel = Line->Level;
577 if (Line->Level > 0)
578 --Line->Level;
Daniel Jasperc30eb512013-03-19 18:33:58 +0000579 if (CommentsBeforeNextToken.empty() && FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000580 parseBlock(/*MustBeDeclaration=*/ false);
Nico Weber94fb7292013-01-18 05:50:57 +0000581 if (FormatTok.Tok.is(tok::kw_break))
582 parseStructuralElement(); // "break;" after "}" goes on the same line.
Daniel Jasperbac016b2012-12-03 18:12:45 +0000583 }
584 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000585 Line->Level = OldLineLevel;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000586}
587
588void UnwrappedLineParser::parseCaseLabel() {
589 assert(FormatTok.Tok.is(tok::kw_case) && "'case' expected");
590 // FIXME: fix handling of complex expressions here.
591 do {
592 nextToken();
593 } while (!eof() && !FormatTok.Tok.is(tok::colon));
594 parseLabel();
595}
596
597void UnwrappedLineParser::parseSwitch() {
598 assert(FormatTok.Tok.is(tok::kw_switch) && "'switch' expected");
599 nextToken();
Manuel Klimek6eca03f2013-01-11 19:23:05 +0000600 if (FormatTok.Tok.is(tok::l_paren))
601 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000602 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000603 parseBlock(/*MustBeDeclaration=*/ false, Style.IndentCaseLabels ? 2 : 1);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000604 addUnwrappedLine();
605 } else {
606 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000607 Line->Level += (Style.IndentCaseLabels ? 2 : 1);
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000608 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000609 Line->Level -= (Style.IndentCaseLabels ? 2 : 1);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000610 }
611}
612
613void UnwrappedLineParser::parseAccessSpecifier() {
614 nextToken();
Alexander Kornienko56e49c52012-12-10 16:34:48 +0000615 // Otherwise, we don't know what it is, and we'd better keep the next token.
616 if (FormatTok.Tok.is(tok::colon))
617 nextToken();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000618 addUnwrappedLine();
619}
620
621void UnwrappedLineParser::parseEnum() {
Manuel Klimek308232c2013-01-21 19:17:52 +0000622 nextToken();
623 if (FormatTok.Tok.is(tok::identifier) ||
624 FormatTok.Tok.is(tok::kw___attribute) ||
625 FormatTok.Tok.is(tok::kw___declspec)) {
626 nextToken();
627 // We can have macros or attributes in between 'enum' and the enum name.
628 if (FormatTok.Tok.is(tok::l_paren)) {
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000629 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000630 }
Manuel Klimek308232c2013-01-21 19:17:52 +0000631 if (FormatTok.Tok.is(tok::identifier))
632 nextToken();
633 }
634 if (FormatTok.Tok.is(tok::l_brace)) {
635 nextToken();
636 addUnwrappedLine();
637 ++Line->Level;
638 do {
639 switch (FormatTok.Tok.getKind()) {
Manuel Klimek308232c2013-01-21 19:17:52 +0000640 case tok::l_paren:
641 parseParens();
642 break;
643 case tok::r_brace:
644 addUnwrappedLine();
645 nextToken();
646 --Line->Level;
647 return;
648 case tok::comma:
649 nextToken();
650 addUnwrappedLine();
651 break;
652 default:
653 nextToken();
654 break;
655 }
656 } while (!eof());
657 }
658 // We fall through to parsing a structural element afterwards, so that in
659 // enum A {} n, m;
660 // "} n, m;" will end up in one unwrapped line.
Daniel Jasperbac016b2012-12-03 18:12:45 +0000661}
662
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000663void UnwrappedLineParser::parseRecord() {
Manuel Klimekde768542013-01-07 18:10:23 +0000664 nextToken();
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000665 if (FormatTok.Tok.is(tok::identifier) ||
666 FormatTok.Tok.is(tok::kw___attribute) ||
667 FormatTok.Tok.is(tok::kw___declspec)) {
668 nextToken();
669 // We can have macros or attributes in between 'class' and the class name.
670 if (FormatTok.Tok.is(tok::l_paren)) {
671 parseParens();
Manuel Klimekde768542013-01-07 18:10:23 +0000672 }
Manuel Klimekb8b1ce12013-02-06 15:57:54 +0000673 // The actual identifier can be a nested name specifier, and in macros
674 // it is often token-pasted.
Manuel Klimek7f5b0252013-01-21 10:17:14 +0000675 while (FormatTok.Tok.is(tok::identifier) ||
Manuel Klimekb8b1ce12013-02-06 15:57:54 +0000676 FormatTok.Tok.is(tok::coloncolon) ||
677 FormatTok.Tok.is(tok::hashhash))
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000678 nextToken();
679
Manuel Klimek3a3408c2013-01-21 13:58:54 +0000680 // Note that parsing away template declarations here leads to incorrectly
681 // accepting function declarations as record declarations.
682 // In general, we cannot solve this problem. Consider:
683 // class A<int> B() {}
684 // which can be a function definition or a class definition when B() is a
685 // macro. If we find enough real-world cases where this is a problem, we
686 // can parse for the 'template' keyword in the beginning of the statement,
687 // and thus rule out the record production in case there is no template
688 // (this would still leave us with an ambiguity between template function
689 // and class declarations).
690 if (FormatTok.Tok.is(tok::colon) || FormatTok.Tok.is(tok::less)) {
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000691 while (FormatTok.Tok.isNot(tok::l_brace)) {
692 if (FormatTok.Tok.is(tok::semi))
693 return;
694 nextToken();
695 }
696 }
697 }
698 if (FormatTok.Tok.is(tok::l_brace))
Manuel Klimek70b03f42013-01-23 09:32:48 +0000699 parseBlock(/*MustBeDeclaration=*/ true);
Manuel Klimek3a3408c2013-01-21 13:58:54 +0000700 // We fall through to parsing a structural element afterwards, so
701 // class A {} n, m;
702 // will end up in one unwrapped line.
Manuel Klimekde768542013-01-07 18:10:23 +0000703}
704
Nico Weber1abe6ea2013-01-09 21:15:03 +0000705void UnwrappedLineParser::parseObjCProtocolList() {
706 assert(FormatTok.Tok.is(tok::less) && "'<' expected.");
707 do
708 nextToken();
709 while (!eof() && FormatTok.Tok.isNot(tok::greater));
710 nextToken(); // Skip '>'.
711}
712
713void UnwrappedLineParser::parseObjCUntilAtEnd() {
714 do {
715 if (FormatTok.Tok.isObjCAtKeyword(tok::objc_end)) {
716 nextToken();
717 addUnwrappedLine();
718 break;
719 }
720 parseStructuralElement();
721 } while (!eof());
722}
723
Nico Weber50767d82013-01-09 23:25:37 +0000724void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
Nico Weber27d13672013-01-09 20:25:35 +0000725 nextToken();
726 nextToken(); // interface name
727
728 // @interface can be followed by either a base class, or a category.
729 if (FormatTok.Tok.is(tok::colon)) {
730 nextToken();
731 nextToken(); // base class name
732 } else if (FormatTok.Tok.is(tok::l_paren))
733 // Skip category, if present.
734 parseParens();
735
Nico Weber1abe6ea2013-01-09 21:15:03 +0000736 if (FormatTok.Tok.is(tok::less))
737 parseObjCProtocolList();
Nico Weber27d13672013-01-09 20:25:35 +0000738
739 // If instance variables are present, keep the '{' on the first line too.
740 if (FormatTok.Tok.is(tok::l_brace))
Manuel Klimek70b03f42013-01-23 09:32:48 +0000741 parseBlock(/*MustBeDeclaration=*/ true);
Nico Weber27d13672013-01-09 20:25:35 +0000742
743 // With instance variables, this puts '}' on its own line. Without instance
744 // variables, this ends the @interface line.
745 addUnwrappedLine();
746
Nico Weber1abe6ea2013-01-09 21:15:03 +0000747 parseObjCUntilAtEnd();
748}
Nico Weber27d13672013-01-09 20:25:35 +0000749
Nico Weber1abe6ea2013-01-09 21:15:03 +0000750void UnwrappedLineParser::parseObjCProtocol() {
751 nextToken();
752 nextToken(); // protocol name
753
754 if (FormatTok.Tok.is(tok::less))
755 parseObjCProtocolList();
756
757 // Check for protocol declaration.
758 if (FormatTok.Tok.is(tok::semi)) {
759 nextToken();
760 return addUnwrappedLine();
761 }
762
763 addUnwrappedLine();
764 parseObjCUntilAtEnd();
Nico Weber27d13672013-01-09 20:25:35 +0000765}
766
Daniel Jasperbac016b2012-12-03 18:12:45 +0000767void UnwrappedLineParser::addUnwrappedLine() {
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000768 if (Line->Tokens.empty())
Daniel Jasper26f7e782013-01-08 14:56:18 +0000769 return;
Manuel Klimek8fa37992013-01-16 12:31:12 +0000770 DEBUG({
Manuel Klimeka28fc062013-02-11 12:33:24 +0000771 llvm::dbgs() << "Line(" << Line->Level << ")"
772 << (Line->InPPDirective ? " MACRO" : "") << ": ";
Manuel Klimek8fa37992013-01-16 12:31:12 +0000773 for (std::list<FormatToken>::iterator I = Line->Tokens.begin(),
774 E = Line->Tokens.end();
775 I != E; ++I) {
776 llvm::dbgs() << I->Tok.getName() << " ";
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000777
Manuel Klimek8fa37992013-01-16 12:31:12 +0000778 }
779 llvm::dbgs() << "\n";
780 });
Manuel Klimek525fe162013-01-18 14:04:34 +0000781 CurrentLines->push_back(*Line);
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000782 Line->Tokens.clear();
Manuel Klimek525fe162013-01-18 14:04:34 +0000783 if (CurrentLines == &Lines && !PreprocessorDirectives.empty()) {
Daniel Jasper516fb312013-03-01 18:11:39 +0000784 for (std::vector<UnwrappedLine>::iterator
785 I = PreprocessorDirectives.begin(),
786 E = PreprocessorDirectives.end();
Manuel Klimek525fe162013-01-18 14:04:34 +0000787 I != E; ++I) {
788 CurrentLines->push_back(*I);
789 }
790 PreprocessorDirectives.clear();
791 }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000792}
793
794bool UnwrappedLineParser::eof() const {
795 return FormatTok.Tok.is(tok::eof);
796}
797
Manuel Klimek86721d22013-01-22 16:31:55 +0000798void UnwrappedLineParser::flushComments(bool NewlineBeforeNext) {
799 bool JustComments = Line->Tokens.empty();
800 for (SmallVectorImpl<FormatToken>::const_iterator
801 I = CommentsBeforeNextToken.begin(),
802 E = CommentsBeforeNextToken.end();
803 I != E; ++I) {
Manuel Klimekb3507cd2013-02-06 16:40:56 +0000804 if (I->NewlinesBefore && JustComments) {
Manuel Klimek86721d22013-01-22 16:31:55 +0000805 addUnwrappedLine();
806 }
807 pushToken(*I);
808 }
809 if (NewlineBeforeNext && JustComments) {
810 addUnwrappedLine();
811 }
812 CommentsBeforeNextToken.clear();
813}
814
Daniel Jasperbac016b2012-12-03 18:12:45 +0000815void UnwrappedLineParser::nextToken() {
816 if (eof())
817 return;
Manuel Klimekb3507cd2013-02-06 16:40:56 +0000818 flushComments(FormatTok.NewlinesBefore > 0);
Manuel Klimek86721d22013-01-22 16:31:55 +0000819 pushToken(FormatTok);
Manuel Klimekd4397b92013-01-04 23:34:14 +0000820 readToken();
821}
822
823void UnwrappedLineParser::readToken() {
Manuel Klimek86721d22013-01-22 16:31:55 +0000824 bool CommentsInCurrentLine = true;
825 do {
826 FormatTok = Tokens->getNextToken();
827 while (!Line->InPPDirective && FormatTok.Tok.is(tok::hash) &&
828 ((FormatTok.NewlinesBefore > 0 && FormatTok.HasUnescapedNewline) ||
829 FormatTok.IsFirst)) {
830 // If there is an unfinished unwrapped line, we flush the preprocessor
831 // directives only after that unwrapped line was finished later.
832 bool SwitchToPreprocessorLines = !Line->Tokens.empty() &&
833 CurrentLines == &Lines;
834 ScopedLineState BlockState(*this, SwitchToPreprocessorLines);
835 parsePPDirective();
836 }
837 if (!FormatTok.Tok.is(tok::comment))
838 return;
Manuel Klimekb3507cd2013-02-06 16:40:56 +0000839 if (FormatTok.NewlinesBefore > 0 || FormatTok.IsFirst) {
Manuel Klimek86721d22013-01-22 16:31:55 +0000840 CommentsInCurrentLine = false;
841 }
842 if (CommentsInCurrentLine) {
843 pushToken(FormatTok);
844 } else {
845 CommentsBeforeNextToken.push_back(FormatTok);
846 }
847 } while (!eof());
848}
849
850void UnwrappedLineParser::pushToken(const FormatToken &Tok) {
851 Line->Tokens.push_back(Tok);
852 if (MustBreakBeforeNextToken) {
853 Line->Tokens.back().MustBreakBefore = true;
854 MustBreakBeforeNextToken = false;
Manuel Klimekd4397b92013-01-04 23:34:14 +0000855 }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000856}
857
Daniel Jaspercd162382013-01-07 13:26:07 +0000858} // end namespace format
859} // end namespace clang