blob: ad641a29b1427e6474da1777efb345decd8760e6 [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///
14/// This is EXPERIMENTAL code under heavy development. It is not in a state yet,
15/// where it can be used to format real code.
16///
17//===----------------------------------------------------------------------===//
18
Manuel Klimek8fa37992013-01-16 12:31:12 +000019#define DEBUG_TYPE "format-parser"
Daniel Jasperbac016b2012-12-03 18:12:45 +000020
Chandler Carruthb1ba0ef2013-01-19 08:09:44 +000021#include "UnwrappedLineParser.h"
Manuel Klimek8fa37992013-01-16 12:31:12 +000022#include "clang/Basic/Diagnostic.h"
23#include "llvm/Support/Debug.h"
Manuel Klimek8fa37992013-01-16 12:31:12 +000024
25// Uncomment to get debug output from tests:
26// #define DEBUG_WITH_TYPE(T, X) do { X; } while(0)
Manuel Klimek4c60fc62013-01-10 10:05:08 +000027
Daniel Jasperbac016b2012-12-03 18:12:45 +000028namespace clang {
29namespace format {
30
Manuel Klimek70b03f42013-01-23 09:32:48 +000031class ScopedDeclarationState {
32public:
33 ScopedDeclarationState(UnwrappedLine &Line, std::vector<bool> &Stack,
34 bool MustBeDeclaration)
35 : Line(Line), Stack(Stack) {
Manuel Klimek70b03f42013-01-23 09:32:48 +000036 Line.MustBeDeclaration = MustBeDeclaration;
Manuel Klimek836b58f2013-01-23 11:03:04 +000037 Stack.push_back(MustBeDeclaration);
Manuel Klimek70b03f42013-01-23 09:32:48 +000038 }
39 ~ScopedDeclarationState() {
Manuel Klimek70b03f42013-01-23 09:32:48 +000040 Stack.pop_back();
Manuel Klimeka32a7fd2013-01-23 14:08:21 +000041 if (!Stack.empty())
42 Line.MustBeDeclaration = Stack.back();
43 else
44 Line.MustBeDeclaration = true;
Manuel Klimek70b03f42013-01-23 09:32:48 +000045 }
46private:
47 UnwrappedLine &Line;
48 std::vector<bool> &Stack;
49};
50
Manuel Klimekd4397b92013-01-04 23:34:14 +000051class ScopedMacroState : public FormatTokenSource {
52public:
53 ScopedMacroState(UnwrappedLine &Line, FormatTokenSource *&TokenSource,
54 FormatToken &ResetToken)
55 : Line(Line), TokenSource(TokenSource), ResetToken(ResetToken),
Manuel Klimekc37b4d62013-01-05 22:14:16 +000056 PreviousLineLevel(Line.Level), PreviousTokenSource(TokenSource) {
Manuel Klimekd4397b92013-01-04 23:34:14 +000057 TokenSource = this;
Manuel Klimekc37b4d62013-01-05 22:14:16 +000058 Line.Level = 0;
Manuel Klimekd4397b92013-01-04 23:34:14 +000059 Line.InPPDirective = true;
60 }
61
62 ~ScopedMacroState() {
63 TokenSource = PreviousTokenSource;
64 ResetToken = Token;
65 Line.InPPDirective = false;
Manuel Klimekc37b4d62013-01-05 22:14:16 +000066 Line.Level = PreviousLineLevel;
Manuel Klimekd4397b92013-01-04 23:34:14 +000067 }
68
69 virtual FormatToken getNextToken() {
Manuel Klimekdd5b1012013-01-07 10:03:37 +000070 // The \c UnwrappedLineParser guards against this by never calling
71 // \c getNextToken() after it has encountered the first eof token.
72 assert(!eof());
Manuel Klimekd4397b92013-01-04 23:34:14 +000073 Token = PreviousTokenSource->getNextToken();
74 if (eof())
75 return createEOF();
76 return Token;
77 }
78
79private:
80 bool eof() {
81 return Token.NewlinesBefore > 0 && Token.HasUnescapedNewline;
82 }
83
84 FormatToken createEOF() {
85 FormatToken FormatTok;
86 FormatTok.Tok.startToken();
87 FormatTok.Tok.setKind(tok::eof);
88 return FormatTok;
89 }
90
91 UnwrappedLine &Line;
92 FormatTokenSource *&TokenSource;
93 FormatToken &ResetToken;
Manuel Klimekc37b4d62013-01-05 22:14:16 +000094 unsigned PreviousLineLevel;
Manuel Klimekd4397b92013-01-04 23:34:14 +000095 FormatTokenSource *PreviousTokenSource;
96
97 FormatToken Token;
98};
99
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000100class ScopedLineState {
101public:
Manuel Klimek525fe162013-01-18 14:04:34 +0000102 ScopedLineState(UnwrappedLineParser &Parser,
103 bool SwitchToPreprocessorLines = false)
104 : Parser(Parser), SwitchToPreprocessorLines(SwitchToPreprocessorLines) {
105 if (SwitchToPreprocessorLines)
106 Parser.CurrentLines = &Parser.PreprocessorDirectives;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000107 PreBlockLine = Parser.Line.take();
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000108 Parser.Line.reset(new UnwrappedLine());
109 Parser.Line->Level = PreBlockLine->Level;
110 Parser.Line->InPPDirective = PreBlockLine->InPPDirective;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000111 }
112
113 ~ScopedLineState() {
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000114 if (!Parser.Line->Tokens.empty()) {
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000115 Parser.addUnwrappedLine();
116 }
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000117 assert(Parser.Line->Tokens.empty());
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000118 Parser.Line.reset(PreBlockLine);
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000119 Parser.MustBreakBeforeNextToken = true;
Manuel Klimek525fe162013-01-18 14:04:34 +0000120 if (SwitchToPreprocessorLines)
121 Parser.CurrentLines = &Parser.Lines;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000122 }
123
124private:
125 UnwrappedLineParser &Parser;
Manuel Klimek525fe162013-01-18 14:04:34 +0000126 const bool SwitchToPreprocessorLines;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000127
128 UnwrappedLine *PreBlockLine;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000129};
130
Alexander Kornienko3048aea2013-01-10 15:05:09 +0000131UnwrappedLineParser::UnwrappedLineParser(
132 clang::DiagnosticsEngine &Diag, const FormatStyle &Style,
133 FormatTokenSource &Tokens, UnwrappedLineConsumer &Callback)
Manuel Klimek525fe162013-01-18 14:04:34 +0000134 : Line(new UnwrappedLine), MustBreakBeforeNextToken(false),
135 CurrentLines(&Lines), Diag(Diag), Style(Style), Tokens(&Tokens),
136 Callback(Callback) {}
Daniel Jasperbac016b2012-12-03 18:12:45 +0000137
Alexander Kornienkocff563c2012-12-04 17:27:50 +0000138bool UnwrappedLineParser::parse() {
Manuel Klimek8fa37992013-01-16 12:31:12 +0000139 DEBUG(llvm::dbgs() << "----\n");
Manuel Klimekd4397b92013-01-04 23:34:14 +0000140 readToken();
Manuel Klimek525fe162013-01-18 14:04:34 +0000141 bool Error = parseFile();
142 for (std::vector<UnwrappedLine>::iterator I = Lines.begin(),
143 E = Lines.end();
144 I != E; ++I) {
145 Callback.consumeUnwrappedLine(*I);
146 }
147 return Error;
Manuel Klimekd4397b92013-01-04 23:34:14 +0000148}
149
150bool UnwrappedLineParser::parseFile() {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000151 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
152 /*MustBeDeclaration=*/ true);
Manuel Klimeka5342db2013-01-06 20:07:31 +0000153 bool Error = parseLevel(/*HasOpeningBrace=*/false);
Manuel Klimekd4397b92013-01-04 23:34:14 +0000154 // Make sure to format the remaining tokens.
Manuel Klimek86721d22013-01-22 16:31:55 +0000155 flushComments(true);
Manuel Klimekd4397b92013-01-04 23:34:14 +0000156 addUnwrappedLine();
157 return Error;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000158}
159
Manuel Klimeka5342db2013-01-06 20:07:31 +0000160bool UnwrappedLineParser::parseLevel(bool HasOpeningBrace) {
Alexander Kornienkocff563c2012-12-04 17:27:50 +0000161 bool Error = false;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000162 do {
163 switch (FormatTok.Tok.getKind()) {
Daniel Jasperbac016b2012-12-03 18:12:45 +0000164 case tok::comment:
Daniel Jasper05b1ac82012-12-17 11:29:41 +0000165 nextToken();
166 addUnwrappedLine();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000167 break;
168 case tok::l_brace:
Manuel Klimek70b03f42013-01-23 09:32:48 +0000169 // FIXME: Add parameter whether this can happen - if this happens, we must
170 // be in a non-declaration context.
171 Error |= parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000172 addUnwrappedLine();
173 break;
174 case tok::r_brace:
Manuel Klimeka5342db2013-01-06 20:07:31 +0000175 if (HasOpeningBrace) {
176 return false;
177 } else {
Alexander Kornienko3048aea2013-01-10 15:05:09 +0000178 Diag.Report(FormatTok.Tok.getLocation(),
179 Diag.getCustomDiagID(clang::DiagnosticsEngine::Error,
Alexander Kornienko276a2092013-01-11 16:03:45 +0000180 "unexpected '}'"));
Manuel Klimeka5342db2013-01-06 20:07:31 +0000181 Error = true;
182 nextToken();
183 addUnwrappedLine();
184 }
185 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000186 default:
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000187 parseStructuralElement();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000188 break;
189 }
190 } while (!eof());
Alexander Kornienkocff563c2012-12-04 17:27:50 +0000191 return Error;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000192}
193
Manuel Klimek70b03f42013-01-23 09:32:48 +0000194bool UnwrappedLineParser::parseBlock(bool MustBeDeclaration, 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) {
221 addUnwrappedLine();
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();
271 switch (FormatTok.Tok.getObjCKeywordID()) {
272 case tok::objc_public:
273 case tok::objc_protected:
274 case tok::objc_package:
275 case tok::objc_private:
276 return parseAccessSpecifier();
Nico Weber27d13672013-01-09 20:25:35 +0000277 case tok::objc_interface:
Nico Weber50767d82013-01-09 23:25:37 +0000278 case tok::objc_implementation:
279 return parseObjCInterfaceOrImplementation();
Nico Weber1abe6ea2013-01-09 21:15:03 +0000280 case tok::objc_protocol:
281 return parseObjCProtocol();
Nico Weber049c4472013-01-09 21:42:32 +0000282 case tok::objc_end:
283 return; // Handled by the caller.
Nico Weberb530fa32013-01-10 00:25:19 +0000284 case tok::objc_optional:
285 case tok::objc_required:
286 nextToken();
287 addUnwrappedLine();
288 return;
Nico Weber6092d4e2013-01-07 19:05:19 +0000289 default:
290 break;
291 }
292 break;
Alexander Kornienko15757312012-12-06 18:03:27 +0000293 case tok::kw_namespace:
294 parseNamespace();
295 return;
Dmitri Gribenko1f94f2b2012-12-30 21:27:25 +0000296 case tok::kw_inline:
297 nextToken();
298 TokenNumber++;
299 if (FormatTok.Tok.is(tok::kw_namespace)) {
300 parseNamespace();
301 return;
302 }
303 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000304 case tok::kw_public:
305 case tok::kw_protected:
306 case tok::kw_private:
Daniel Jasperbac016b2012-12-03 18:12:45 +0000307 parseAccessSpecifier();
308 return;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000309 case tok::kw_if:
310 parseIfThenElse();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000311 return;
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000312 case tok::kw_for:
313 case tok::kw_while:
314 parseForOrWhileLoop();
315 return;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000316 case tok::kw_do:
317 parseDoWhile();
318 return;
319 case tok::kw_switch:
320 parseSwitch();
321 return;
322 case tok::kw_default:
323 nextToken();
324 parseLabel();
325 return;
326 case tok::kw_case:
327 parseCaseLabel();
328 return;
Manuel Klimekc44ee892013-01-21 10:07:49 +0000329 case tok::kw_return:
330 parseReturn();
331 return;
Manuel Klimekd19dc2d2013-01-21 14:32:05 +0000332 case tok::kw_extern:
333 nextToken();
334 if (FormatTok.Tok.is(tok::string_literal)) {
335 nextToken();
336 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000337 parseBlock(/*MustBeDeclaration=*/ true, 0);
Manuel Klimekd19dc2d2013-01-21 14:32:05 +0000338 addUnwrappedLine();
339 return;
340 }
341 }
342 // In all other cases, parse the declaration.
343 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000344 default:
345 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000346 }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000347 do {
348 ++TokenNumber;
349 switch (FormatTok.Tok.getKind()) {
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000350 case tok::kw_enum:
351 parseEnum();
Manuel Klimek308232c2013-01-21 19:17:52 +0000352 break;
Alexander Kornienkod8818752013-01-16 11:43:46 +0000353 case tok::kw_struct:
354 case tok::kw_union:
Manuel Klimekde768542013-01-07 18:10:23 +0000355 case tok::kw_class:
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000356 parseRecord();
357 // A record declaration or definition is always the start of a structural
358 // element.
359 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000360 case tok::semi:
361 nextToken();
362 addUnwrappedLine();
363 return;
Alexander Kornienkod8818752013-01-16 11:43:46 +0000364 case tok::r_brace:
365 addUnwrappedLine();
366 return;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000367 case tok::l_paren:
368 parseParens();
369 break;
370 case tok::l_brace:
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000371 // A block outside of parentheses must be the last part of a
372 // structural element.
373 // FIXME: Figure out cases where this is not true, and add projections for
374 // them (the one we know is missing are lambdas).
Manuel Klimek70b03f42013-01-23 09:32:48 +0000375 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000376 addUnwrappedLine();
377 return;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000378 case tok::identifier:
Daniel Jasperbac016b2012-12-03 18:12:45 +0000379 nextToken();
380 if (TokenNumber == 1 && FormatTok.Tok.is(tok::colon)) {
381 parseLabel();
382 return;
383 }
384 break;
Daniel Jasper05b1ac82012-12-17 11:29:41 +0000385 case tok::equal:
386 nextToken();
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000387 if (FormatTok.Tok.is(tok::l_brace)) {
388 parseBracedList();
389 }
Daniel Jasper05b1ac82012-12-17 11:29:41 +0000390 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000391 default:
392 nextToken();
393 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000394 }
395 } while (!eof());
396}
397
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000398void UnwrappedLineParser::parseBracedList() {
399 nextToken();
400
401 do {
402 switch (FormatTok.Tok.getKind()) {
403 case tok::l_brace:
404 parseBracedList();
405 break;
406 case tok::r_brace:
407 nextToken();
408 return;
409 default:
410 nextToken();
411 break;
412 }
413 } while (!eof());
414}
415
Manuel Klimekc44ee892013-01-21 10:07:49 +0000416void UnwrappedLineParser::parseReturn() {
417 nextToken();
418
419 do {
420 switch (FormatTok.Tok.getKind()) {
421 case tok::l_brace:
422 parseBracedList();
423 break;
424 case tok::l_paren:
425 parseParens();
426 break;
427 case tok::r_brace:
428 // Assume missing ';'.
429 addUnwrappedLine();
430 return;
431 case tok::semi:
432 nextToken();
433 addUnwrappedLine();
434 return;
435 default:
436 nextToken();
437 break;
438 }
439 } while (!eof());
440}
441
Daniel Jasperbac016b2012-12-03 18:12:45 +0000442void UnwrappedLineParser::parseParens() {
443 assert(FormatTok.Tok.is(tok::l_paren) && "'(' expected.");
444 nextToken();
445 do {
446 switch (FormatTok.Tok.getKind()) {
447 case tok::l_paren:
448 parseParens();
449 break;
450 case tok::r_paren:
451 nextToken();
452 return;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000453 case tok::l_brace:
454 {
455 nextToken();
456 ScopedLineState LineState(*this);
Manuel Klimek70b03f42013-01-23 09:32:48 +0000457 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
458 /*MustBeDeclaration=*/ false);
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000459 Line->Level += 1;
Manuel Klimek70b03f42013-01-23 09:32:48 +0000460 parseLevel(/*HasOpeningBrace=*/ true);
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000461 Line->Level -= 1;
462 }
463 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000464 default:
465 nextToken();
466 break;
467 }
468 } while (!eof());
469}
470
471void UnwrappedLineParser::parseIfThenElse() {
472 assert(FormatTok.Tok.is(tok::kw_if) && "'if' expected");
473 nextToken();
Manuel Klimekd4658432013-01-11 18:28:36 +0000474 if (FormatTok.Tok.is(tok::l_paren))
475 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000476 bool NeedsUnwrappedLine = false;
477 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000478 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000479 NeedsUnwrappedLine = true;
480 } else {
481 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000482 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000483 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000484 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000485 }
486 if (FormatTok.Tok.is(tok::kw_else)) {
487 nextToken();
488 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000489 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000490 addUnwrappedLine();
491 } else if (FormatTok.Tok.is(tok::kw_if)) {
492 parseIfThenElse();
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 } else if (NeedsUnwrappedLine) {
500 addUnwrappedLine();
501 }
502}
503
Alexander Kornienko15757312012-12-06 18:03:27 +0000504void UnwrappedLineParser::parseNamespace() {
505 assert(FormatTok.Tok.is(tok::kw_namespace) && "'namespace' expected");
506 nextToken();
507 if (FormatTok.Tok.is(tok::identifier))
508 nextToken();
509 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000510 parseBlock(/*MustBeDeclaration=*/ true, 0);
Alexander Kornienko15757312012-12-06 18:03:27 +0000511 addUnwrappedLine();
512 }
513 // FIXME: Add error handling.
514}
515
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000516void UnwrappedLineParser::parseForOrWhileLoop() {
517 assert((FormatTok.Tok.is(tok::kw_for) || FormatTok.Tok.is(tok::kw_while)) &&
518 "'for' or 'while' expected");
519 nextToken();
Manuel Klimek6eca03f2013-01-11 19:23:05 +0000520 if (FormatTok.Tok.is(tok::l_paren))
521 parseParens();
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000522 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000523 parseBlock(/*MustBeDeclaration=*/ false);
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000524 addUnwrappedLine();
525 } else {
526 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000527 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000528 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000529 --Line->Level;
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000530 }
531}
532
Daniel Jasperbac016b2012-12-03 18:12:45 +0000533void UnwrappedLineParser::parseDoWhile() {
534 assert(FormatTok.Tok.is(tok::kw_do) && "'do' expected");
535 nextToken();
536 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000537 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000538 } else {
539 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000540 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000541 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000542 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000543 }
544
Alexander Kornienko393b0082012-12-04 15:40:36 +0000545 // FIXME: Add error handling.
546 if (!FormatTok.Tok.is(tok::kw_while)) {
547 addUnwrappedLine();
548 return;
549 }
550
Daniel Jasperbac016b2012-12-03 18:12:45 +0000551 nextToken();
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000552 parseStructuralElement();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000553}
554
555void UnwrappedLineParser::parseLabel() {
556 // FIXME: remove all asserts.
557 assert(FormatTok.Tok.is(tok::colon) && "':' expected");
558 nextToken();
Manuel Klimek526ed112013-01-09 15:25:02 +0000559 unsigned OldLineLevel = Line->Level;
560 if (Line->Level > 0)
561 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000562 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000563 parseBlock(/*MustBeDeclaration=*/ false);
Nico Weber94fb7292013-01-18 05:50:57 +0000564 if (FormatTok.Tok.is(tok::kw_break))
565 parseStructuralElement(); // "break;" after "}" goes on the same line.
Daniel Jasperbac016b2012-12-03 18:12:45 +0000566 }
567 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000568 Line->Level = OldLineLevel;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000569}
570
571void UnwrappedLineParser::parseCaseLabel() {
572 assert(FormatTok.Tok.is(tok::kw_case) && "'case' expected");
573 // FIXME: fix handling of complex expressions here.
574 do {
575 nextToken();
576 } while (!eof() && !FormatTok.Tok.is(tok::colon));
577 parseLabel();
578}
579
580void UnwrappedLineParser::parseSwitch() {
581 assert(FormatTok.Tok.is(tok::kw_switch) && "'switch' expected");
582 nextToken();
Manuel Klimek6eca03f2013-01-11 19:23:05 +0000583 if (FormatTok.Tok.is(tok::l_paren))
584 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000585 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000586 parseBlock(/*MustBeDeclaration=*/ false, Style.IndentCaseLabels ? 2 : 1);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000587 addUnwrappedLine();
588 } else {
589 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000590 Line->Level += (Style.IndentCaseLabels ? 2 : 1);
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000591 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000592 Line->Level -= (Style.IndentCaseLabels ? 2 : 1);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000593 }
594}
595
596void UnwrappedLineParser::parseAccessSpecifier() {
597 nextToken();
Alexander Kornienko56e49c52012-12-10 16:34:48 +0000598 // Otherwise, we don't know what it is, and we'd better keep the next token.
599 if (FormatTok.Tok.is(tok::colon))
600 nextToken();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000601 addUnwrappedLine();
602}
603
604void UnwrappedLineParser::parseEnum() {
Manuel Klimek308232c2013-01-21 19:17:52 +0000605 nextToken();
606 if (FormatTok.Tok.is(tok::identifier) ||
607 FormatTok.Tok.is(tok::kw___attribute) ||
608 FormatTok.Tok.is(tok::kw___declspec)) {
609 nextToken();
610 // We can have macros or attributes in between 'enum' and the enum name.
611 if (FormatTok.Tok.is(tok::l_paren)) {
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000612 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000613 }
Manuel Klimek308232c2013-01-21 19:17:52 +0000614 if (FormatTok.Tok.is(tok::identifier))
615 nextToken();
616 }
617 if (FormatTok.Tok.is(tok::l_brace)) {
618 nextToken();
619 addUnwrappedLine();
620 ++Line->Level;
621 do {
622 switch (FormatTok.Tok.getKind()) {
Manuel Klimek308232c2013-01-21 19:17:52 +0000623 case tok::l_paren:
624 parseParens();
625 break;
626 case tok::r_brace:
627 addUnwrappedLine();
628 nextToken();
629 --Line->Level;
630 return;
631 case tok::comma:
632 nextToken();
633 addUnwrappedLine();
634 break;
635 default:
636 nextToken();
637 break;
638 }
639 } while (!eof());
640 }
641 // We fall through to parsing a structural element afterwards, so that in
642 // enum A {} n, m;
643 // "} n, m;" will end up in one unwrapped line.
Daniel Jasperbac016b2012-12-03 18:12:45 +0000644}
645
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000646void UnwrappedLineParser::parseRecord() {
Manuel Klimekde768542013-01-07 18:10:23 +0000647 nextToken();
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000648 if (FormatTok.Tok.is(tok::identifier) ||
649 FormatTok.Tok.is(tok::kw___attribute) ||
650 FormatTok.Tok.is(tok::kw___declspec)) {
651 nextToken();
652 // We can have macros or attributes in between 'class' and the class name.
653 if (FormatTok.Tok.is(tok::l_paren)) {
654 parseParens();
Manuel Klimekde768542013-01-07 18:10:23 +0000655 }
Manuel Klimek7f5b0252013-01-21 10:17:14 +0000656 // The actual identifier can be a nested name specifier.
657 while (FormatTok.Tok.is(tok::identifier) ||
658 FormatTok.Tok.is(tok::coloncolon))
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000659 nextToken();
660
Manuel Klimek3a3408c2013-01-21 13:58:54 +0000661 // Note that parsing away template declarations here leads to incorrectly
662 // accepting function declarations as record declarations.
663 // In general, we cannot solve this problem. Consider:
664 // class A<int> B() {}
665 // which can be a function definition or a class definition when B() is a
666 // macro. If we find enough real-world cases where this is a problem, we
667 // can parse for the 'template' keyword in the beginning of the statement,
668 // and thus rule out the record production in case there is no template
669 // (this would still leave us with an ambiguity between template function
670 // and class declarations).
671 if (FormatTok.Tok.is(tok::colon) || FormatTok.Tok.is(tok::less)) {
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000672 while (FormatTok.Tok.isNot(tok::l_brace)) {
673 if (FormatTok.Tok.is(tok::semi))
674 return;
675 nextToken();
676 }
677 }
678 }
679 if (FormatTok.Tok.is(tok::l_brace))
Manuel Klimek70b03f42013-01-23 09:32:48 +0000680 parseBlock(/*MustBeDeclaration=*/ true);
Manuel Klimek3a3408c2013-01-21 13:58:54 +0000681 // We fall through to parsing a structural element afterwards, so
682 // class A {} n, m;
683 // will end up in one unwrapped line.
Manuel Klimekde768542013-01-07 18:10:23 +0000684}
685
Nico Weber1abe6ea2013-01-09 21:15:03 +0000686void UnwrappedLineParser::parseObjCProtocolList() {
687 assert(FormatTok.Tok.is(tok::less) && "'<' expected.");
688 do
689 nextToken();
690 while (!eof() && FormatTok.Tok.isNot(tok::greater));
691 nextToken(); // Skip '>'.
692}
693
694void UnwrappedLineParser::parseObjCUntilAtEnd() {
695 do {
696 if (FormatTok.Tok.isObjCAtKeyword(tok::objc_end)) {
697 nextToken();
698 addUnwrappedLine();
699 break;
700 }
701 parseStructuralElement();
702 } while (!eof());
703}
704
Nico Weber50767d82013-01-09 23:25:37 +0000705void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
Nico Weber27d13672013-01-09 20:25:35 +0000706 nextToken();
707 nextToken(); // interface name
708
709 // @interface can be followed by either a base class, or a category.
710 if (FormatTok.Tok.is(tok::colon)) {
711 nextToken();
712 nextToken(); // base class name
713 } else if (FormatTok.Tok.is(tok::l_paren))
714 // Skip category, if present.
715 parseParens();
716
Nico Weber1abe6ea2013-01-09 21:15:03 +0000717 if (FormatTok.Tok.is(tok::less))
718 parseObjCProtocolList();
Nico Weber27d13672013-01-09 20:25:35 +0000719
720 // If instance variables are present, keep the '{' on the first line too.
721 if (FormatTok.Tok.is(tok::l_brace))
Manuel Klimek70b03f42013-01-23 09:32:48 +0000722 parseBlock(/*MustBeDeclaration=*/ true);
Nico Weber27d13672013-01-09 20:25:35 +0000723
724 // With instance variables, this puts '}' on its own line. Without instance
725 // variables, this ends the @interface line.
726 addUnwrappedLine();
727
Nico Weber1abe6ea2013-01-09 21:15:03 +0000728 parseObjCUntilAtEnd();
729}
Nico Weber27d13672013-01-09 20:25:35 +0000730
Nico Weber1abe6ea2013-01-09 21:15:03 +0000731void UnwrappedLineParser::parseObjCProtocol() {
732 nextToken();
733 nextToken(); // protocol name
734
735 if (FormatTok.Tok.is(tok::less))
736 parseObjCProtocolList();
737
738 // Check for protocol declaration.
739 if (FormatTok.Tok.is(tok::semi)) {
740 nextToken();
741 return addUnwrappedLine();
742 }
743
744 addUnwrappedLine();
745 parseObjCUntilAtEnd();
Nico Weber27d13672013-01-09 20:25:35 +0000746}
747
Daniel Jasperbac016b2012-12-03 18:12:45 +0000748void UnwrappedLineParser::addUnwrappedLine() {
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000749 if (Line->Tokens.empty())
Daniel Jasper26f7e782013-01-08 14:56:18 +0000750 return;
Manuel Klimek8fa37992013-01-16 12:31:12 +0000751 DEBUG({
Manuel Klimek86721d22013-01-22 16:31:55 +0000752 llvm::dbgs() << "Line(" << Line->Level << "): ";
Manuel Klimek8fa37992013-01-16 12:31:12 +0000753 for (std::list<FormatToken>::iterator I = Line->Tokens.begin(),
754 E = Line->Tokens.end();
755 I != E; ++I) {
756 llvm::dbgs() << I->Tok.getName() << " ";
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000757
Manuel Klimek8fa37992013-01-16 12:31:12 +0000758 }
759 llvm::dbgs() << "\n";
760 });
Manuel Klimek525fe162013-01-18 14:04:34 +0000761 CurrentLines->push_back(*Line);
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000762 Line->Tokens.clear();
Manuel Klimek525fe162013-01-18 14:04:34 +0000763 if (CurrentLines == &Lines && !PreprocessorDirectives.empty()) {
764 for (std::vector<UnwrappedLine>::iterator I = PreprocessorDirectives
765 .begin(), E = PreprocessorDirectives.end();
766 I != E; ++I) {
767 CurrentLines->push_back(*I);
768 }
769 PreprocessorDirectives.clear();
770 }
771
Daniel Jasperbac016b2012-12-03 18:12:45 +0000772}
773
774bool UnwrappedLineParser::eof() const {
775 return FormatTok.Tok.is(tok::eof);
776}
777
Manuel Klimek86721d22013-01-22 16:31:55 +0000778void UnwrappedLineParser::flushComments(bool NewlineBeforeNext) {
779 bool JustComments = Line->Tokens.empty();
780 for (SmallVectorImpl<FormatToken>::const_iterator
781 I = CommentsBeforeNextToken.begin(),
782 E = CommentsBeforeNextToken.end();
783 I != E; ++I) {
784 if (I->HasUnescapedNewline && JustComments) {
785 addUnwrappedLine();
786 }
787 pushToken(*I);
788 }
789 if (NewlineBeforeNext && JustComments) {
790 addUnwrappedLine();
791 }
792 CommentsBeforeNextToken.clear();
793}
794
Daniel Jasperbac016b2012-12-03 18:12:45 +0000795void UnwrappedLineParser::nextToken() {
796 if (eof())
797 return;
Manuel Klimek86721d22013-01-22 16:31:55 +0000798 flushComments(FormatTok.HasUnescapedNewline);
799 pushToken(FormatTok);
Manuel Klimekd4397b92013-01-04 23:34:14 +0000800 readToken();
801}
802
803void UnwrappedLineParser::readToken() {
Manuel Klimek86721d22013-01-22 16:31:55 +0000804 bool CommentsInCurrentLine = true;
805 do {
806 FormatTok = Tokens->getNextToken();
807 while (!Line->InPPDirective && FormatTok.Tok.is(tok::hash) &&
808 ((FormatTok.NewlinesBefore > 0 && FormatTok.HasUnescapedNewline) ||
809 FormatTok.IsFirst)) {
810 // If there is an unfinished unwrapped line, we flush the preprocessor
811 // directives only after that unwrapped line was finished later.
812 bool SwitchToPreprocessorLines = !Line->Tokens.empty() &&
813 CurrentLines == &Lines;
814 ScopedLineState BlockState(*this, SwitchToPreprocessorLines);
815 parsePPDirective();
816 }
817 if (!FormatTok.Tok.is(tok::comment))
818 return;
819 if (FormatTok.HasUnescapedNewline || FormatTok.IsFirst) {
820 CommentsInCurrentLine = false;
821 }
822 if (CommentsInCurrentLine) {
823 pushToken(FormatTok);
824 } else {
825 CommentsBeforeNextToken.push_back(FormatTok);
826 }
827 } while (!eof());
828}
829
830void UnwrappedLineParser::pushToken(const FormatToken &Tok) {
831 Line->Tokens.push_back(Tok);
832 if (MustBreakBeforeNextToken) {
833 Line->Tokens.back().MustBreakBefore = true;
834 MustBreakBeforeNextToken = false;
Manuel Klimekd4397b92013-01-04 23:34:14 +0000835 }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000836}
837
Daniel Jaspercd162382013-01-07 13:26:07 +0000838} // end namespace format
839} // end namespace clang