blob: 28522a3e32708776bc1d09306112e32f2b6ff330 [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 }
141 return Error;
Manuel Klimekd4397b92013-01-04 23:34:14 +0000142}
143
144bool UnwrappedLineParser::parseFile() {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000145 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
146 /*MustBeDeclaration=*/ true);
Manuel Klimeka5342db2013-01-06 20:07:31 +0000147 bool Error = parseLevel(/*HasOpeningBrace=*/false);
Manuel Klimekd4397b92013-01-04 23:34:14 +0000148 // Make sure to format the remaining tokens.
Manuel Klimek86721d22013-01-22 16:31:55 +0000149 flushComments(true);
Manuel Klimekd4397b92013-01-04 23:34:14 +0000150 addUnwrappedLine();
151 return Error;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000152}
153
Manuel Klimeka5342db2013-01-06 20:07:31 +0000154bool UnwrappedLineParser::parseLevel(bool HasOpeningBrace) {
Alexander Kornienkocff563c2012-12-04 17:27:50 +0000155 bool Error = false;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000156 do {
157 switch (FormatTok.Tok.getKind()) {
Daniel Jasperbac016b2012-12-03 18:12:45 +0000158 case tok::comment:
Daniel Jasper05b1ac82012-12-17 11:29:41 +0000159 nextToken();
160 addUnwrappedLine();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000161 break;
162 case tok::l_brace:
Manuel Klimek70b03f42013-01-23 09:32:48 +0000163 // FIXME: Add parameter whether this can happen - if this happens, we must
164 // be in a non-declaration context.
165 Error |= parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000166 addUnwrappedLine();
167 break;
168 case tok::r_brace:
Manuel Klimeka5342db2013-01-06 20:07:31 +0000169 if (HasOpeningBrace) {
170 return false;
171 } else {
Alexander Kornienko3048aea2013-01-10 15:05:09 +0000172 Diag.Report(FormatTok.Tok.getLocation(),
173 Diag.getCustomDiagID(clang::DiagnosticsEngine::Error,
Alexander Kornienko276a2092013-01-11 16:03:45 +0000174 "unexpected '}'"));
Manuel Klimeka5342db2013-01-06 20:07:31 +0000175 Error = true;
176 nextToken();
177 addUnwrappedLine();
178 }
179 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000180 default:
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000181 parseStructuralElement();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000182 break;
183 }
184 } while (!eof());
Alexander Kornienkocff563c2012-12-04 17:27:50 +0000185 return Error;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000186}
187
Nico Weberd74fcdb2013-02-10 20:35:35 +0000188bool UnwrappedLineParser::parseBlock(bool MustBeDeclaration,
189 unsigned AddLevels) {
Alexander Kornienkoa3a2b3a2012-12-06 17:49:17 +0000190 assert(FormatTok.Tok.is(tok::l_brace) && "'{' expected");
Daniel Jasperbac016b2012-12-03 18:12:45 +0000191 nextToken();
192
Manuel Klimek2f1ac412013-01-21 16:42:44 +0000193 addUnwrappedLine();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000194
Manuel Klimek70b03f42013-01-23 09:32:48 +0000195 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
196 MustBeDeclaration);
Manuel Klimek2f1ac412013-01-21 16:42:44 +0000197 Line->Level += AddLevels;
198 parseLevel(/*HasOpeningBrace=*/true);
Alexander Kornienko15757312012-12-06 18:03:27 +0000199
Manuel Klimek86721d22013-01-22 16:31:55 +0000200 if (!FormatTok.Tok.is(tok::r_brace)) {
201 Line->Level -= AddLevels;
Manuel Klimek2f1ac412013-01-21 16:42:44 +0000202 return true;
Manuel Klimek86721d22013-01-22 16:31:55 +0000203 }
Alexander Kornienko393b0082012-12-04 15:40:36 +0000204
Manuel Klimekde768542013-01-07 18:10:23 +0000205 nextToken(); // Munch the closing brace.
Manuel Klimek86721d22013-01-22 16:31:55 +0000206 Line->Level -= AddLevels;
Alexander Kornienkocff563c2012-12-04 17:27:50 +0000207 return false;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000208}
209
210void UnwrappedLineParser::parsePPDirective() {
Manuel Klimeka080a182013-01-02 16:30:12 +0000211 assert(FormatTok.Tok.is(tok::hash) && "'#' expected");
Manuel Klimek526ed112013-01-09 15:25:02 +0000212 ScopedMacroState MacroState(*Line, Tokens, FormatTok);
Manuel Klimeka080a182013-01-02 16:30:12 +0000213 nextToken();
214
Manuel Klimeka080a182013-01-02 16:30:12 +0000215 if (FormatTok.Tok.getIdentifierInfo() == NULL) {
Manuel Klimekbd04f2a2013-01-31 15:58:48 +0000216 parsePPUnknown();
Manuel Klimeka080a182013-01-02 16:30:12 +0000217 return;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000218 }
Manuel Klimeka080a182013-01-02 16:30:12 +0000219
Manuel Klimekd4397b92013-01-04 23:34:14 +0000220 switch (FormatTok.Tok.getIdentifierInfo()->getPPKeywordID()) {
221 case tok::pp_define:
222 parsePPDefine();
223 break;
224 default:
225 parsePPUnknown();
226 break;
227 }
228}
229
230void UnwrappedLineParser::parsePPDefine() {
231 nextToken();
232
233 if (FormatTok.Tok.getKind() != tok::identifier) {
234 parsePPUnknown();
235 return;
236 }
237 nextToken();
Manuel Klimek7ccbc212013-01-23 14:37:36 +0000238 if (FormatTok.Tok.getKind() == tok::l_paren &&
239 FormatTok.WhiteSpaceLength == 0) {
Manuel Klimekd4397b92013-01-04 23:34:14 +0000240 parseParens();
241 }
242 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000243 Line->Level = 1;
Manuel Klimekc3d0c822013-01-07 09:34:28 +0000244
245 // Errors during a preprocessor directive can only affect the layout of the
246 // preprocessor directive, and thus we ignore them. An alternative approach
247 // would be to use the same approach we use on the file level (no
248 // re-indentation if there was a structural error) within the macro
249 // definition.
Manuel Klimekd4397b92013-01-04 23:34:14 +0000250 parseFile();
251}
252
253void UnwrappedLineParser::parsePPUnknown() {
Manuel Klimeka080a182013-01-02 16:30:12 +0000254 do {
Manuel Klimeka080a182013-01-02 16:30:12 +0000255 nextToken();
256 } while (!eof());
257 addUnwrappedLine();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000258}
259
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000260void UnwrappedLineParser::parseStructuralElement() {
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000261 assert(!FormatTok.Tok.is(tok::l_brace));
Dmitri Gribenko1f94f2b2012-12-30 21:27:25 +0000262 int TokenNumber = 0;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000263 switch (FormatTok.Tok.getKind()) {
Nico Weber6092d4e2013-01-07 19:05:19 +0000264 case tok::at:
265 nextToken();
Nico Weberd74fcdb2013-02-10 20:35:35 +0000266 if (FormatTok.Tok.is(tok::l_brace)) {
267 parseBracedList();
268 break;
269 }
Nico Weber6092d4e2013-01-07 19:05:19 +0000270 switch (FormatTok.Tok.getObjCKeywordID()) {
271 case tok::objc_public:
272 case tok::objc_protected:
273 case tok::objc_package:
274 case tok::objc_private:
275 return parseAccessSpecifier();
Nico Weber27d13672013-01-09 20:25:35 +0000276 case tok::objc_interface:
Nico Weber50767d82013-01-09 23:25:37 +0000277 case tok::objc_implementation:
278 return parseObjCInterfaceOrImplementation();
Nico Weber1abe6ea2013-01-09 21:15:03 +0000279 case tok::objc_protocol:
280 return parseObjCProtocol();
Nico Weber049c4472013-01-09 21:42:32 +0000281 case tok::objc_end:
282 return; // Handled by the caller.
Nico Weberb530fa32013-01-10 00:25:19 +0000283 case tok::objc_optional:
284 case tok::objc_required:
285 nextToken();
286 addUnwrappedLine();
287 return;
Nico Weber6092d4e2013-01-07 19:05:19 +0000288 default:
289 break;
290 }
291 break;
Alexander Kornienko15757312012-12-06 18:03:27 +0000292 case tok::kw_namespace:
293 parseNamespace();
294 return;
Dmitri Gribenko1f94f2b2012-12-30 21:27:25 +0000295 case tok::kw_inline:
296 nextToken();
297 TokenNumber++;
298 if (FormatTok.Tok.is(tok::kw_namespace)) {
299 parseNamespace();
300 return;
301 }
302 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000303 case tok::kw_public:
304 case tok::kw_protected:
305 case tok::kw_private:
Daniel Jasperbac016b2012-12-03 18:12:45 +0000306 parseAccessSpecifier();
307 return;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000308 case tok::kw_if:
309 parseIfThenElse();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000310 return;
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000311 case tok::kw_for:
312 case tok::kw_while:
313 parseForOrWhileLoop();
314 return;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000315 case tok::kw_do:
316 parseDoWhile();
317 return;
318 case tok::kw_switch:
319 parseSwitch();
320 return;
321 case tok::kw_default:
322 nextToken();
323 parseLabel();
324 return;
325 case tok::kw_case:
326 parseCaseLabel();
327 return;
Manuel Klimekc44ee892013-01-21 10:07:49 +0000328 case tok::kw_return:
329 parseReturn();
330 return;
Manuel Klimekd19dc2d2013-01-21 14:32:05 +0000331 case tok::kw_extern:
332 nextToken();
333 if (FormatTok.Tok.is(tok::string_literal)) {
334 nextToken();
335 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000336 parseBlock(/*MustBeDeclaration=*/ true, 0);
Manuel Klimekd19dc2d2013-01-21 14:32:05 +0000337 addUnwrappedLine();
338 return;
339 }
340 }
341 // In all other cases, parse the declaration.
342 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000343 default:
344 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000345 }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000346 do {
347 ++TokenNumber;
348 switch (FormatTok.Tok.getKind()) {
Nico Weberd74fcdb2013-02-10 20:35:35 +0000349 case tok::at:
350 nextToken();
351 if (FormatTok.Tok.is(tok::l_brace))
352 parseBracedList();
353 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000354 case tok::kw_enum:
355 parseEnum();
Manuel Klimek308232c2013-01-21 19:17:52 +0000356 break;
Alexander Kornienkod8818752013-01-16 11:43:46 +0000357 case tok::kw_struct:
358 case tok::kw_union:
Manuel Klimekde768542013-01-07 18:10:23 +0000359 case tok::kw_class:
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000360 parseRecord();
361 // A record declaration or definition is always the start of a structural
362 // element.
363 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000364 case tok::semi:
365 nextToken();
366 addUnwrappedLine();
367 return;
Alexander Kornienkod8818752013-01-16 11:43:46 +0000368 case tok::r_brace:
369 addUnwrappedLine();
370 return;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000371 case tok::l_paren:
372 parseParens();
373 break;
374 case tok::l_brace:
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000375 // A block outside of parentheses must be the last part of a
376 // structural element.
377 // FIXME: Figure out cases where this is not true, and add projections for
378 // them (the one we know is missing are lambdas).
Manuel Klimek70b03f42013-01-23 09:32:48 +0000379 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000380 addUnwrappedLine();
381 return;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000382 case tok::identifier:
Daniel Jasperbac016b2012-12-03 18:12:45 +0000383 nextToken();
384 if (TokenNumber == 1 && FormatTok.Tok.is(tok::colon)) {
385 parseLabel();
386 return;
387 }
388 break;
Daniel Jasper05b1ac82012-12-17 11:29:41 +0000389 case tok::equal:
390 nextToken();
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000391 if (FormatTok.Tok.is(tok::l_brace)) {
392 parseBracedList();
393 }
Daniel Jasper05b1ac82012-12-17 11:29:41 +0000394 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000395 default:
396 nextToken();
397 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000398 }
399 } while (!eof());
400}
401
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000402void UnwrappedLineParser::parseBracedList() {
403 nextToken();
404
405 do {
406 switch (FormatTok.Tok.getKind()) {
407 case tok::l_brace:
408 parseBracedList();
409 break;
410 case tok::r_brace:
411 nextToken();
412 return;
413 default:
414 nextToken();
415 break;
416 }
417 } while (!eof());
418}
419
Manuel Klimekc44ee892013-01-21 10:07:49 +0000420void UnwrappedLineParser::parseReturn() {
421 nextToken();
422
423 do {
424 switch (FormatTok.Tok.getKind()) {
425 case tok::l_brace:
426 parseBracedList();
427 break;
428 case tok::l_paren:
429 parseParens();
430 break;
431 case tok::r_brace:
432 // Assume missing ';'.
433 addUnwrappedLine();
434 return;
435 case tok::semi:
436 nextToken();
437 addUnwrappedLine();
438 return;
439 default:
440 nextToken();
441 break;
442 }
443 } while (!eof());
444}
445
Daniel Jasperbac016b2012-12-03 18:12:45 +0000446void UnwrappedLineParser::parseParens() {
447 assert(FormatTok.Tok.is(tok::l_paren) && "'(' expected.");
448 nextToken();
449 do {
450 switch (FormatTok.Tok.getKind()) {
451 case tok::l_paren:
452 parseParens();
453 break;
454 case tok::r_paren:
455 nextToken();
456 return;
Nico Weber2afbe522013-02-10 04:38:23 +0000457 case tok::l_brace: {
458 nextToken();
459 ScopedLineState LineState(*this);
460 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
461 /*MustBeDeclaration=*/ false);
462 Line->Level += 1;
463 parseLevel(/*HasOpeningBrace=*/ true);
464 Line->Level -= 1;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000465 break;
Nico Weber2afbe522013-02-10 04:38:23 +0000466 }
Nico Weberd74fcdb2013-02-10 20:35:35 +0000467 case tok::at:
468 nextToken();
469 if (FormatTok.Tok.is(tok::l_brace))
470 parseBracedList();
471 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000472 default:
473 nextToken();
474 break;
475 }
476 } while (!eof());
477}
478
479void UnwrappedLineParser::parseIfThenElse() {
480 assert(FormatTok.Tok.is(tok::kw_if) && "'if' expected");
481 nextToken();
Manuel Klimekd4658432013-01-11 18:28:36 +0000482 if (FormatTok.Tok.is(tok::l_paren))
483 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000484 bool NeedsUnwrappedLine = false;
485 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000486 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000487 NeedsUnwrappedLine = true;
488 } else {
489 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000490 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000491 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000492 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000493 }
494 if (FormatTok.Tok.is(tok::kw_else)) {
495 nextToken();
496 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000497 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000498 addUnwrappedLine();
499 } else if (FormatTok.Tok.is(tok::kw_if)) {
500 parseIfThenElse();
501 } else {
502 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000503 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000504 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000505 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000506 }
507 } else if (NeedsUnwrappedLine) {
508 addUnwrappedLine();
509 }
510}
511
Alexander Kornienko15757312012-12-06 18:03:27 +0000512void UnwrappedLineParser::parseNamespace() {
513 assert(FormatTok.Tok.is(tok::kw_namespace) && "'namespace' expected");
514 nextToken();
515 if (FormatTok.Tok.is(tok::identifier))
516 nextToken();
517 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000518 parseBlock(/*MustBeDeclaration=*/ true, 0);
Manuel Klimek7fc2db02013-02-06 16:08:09 +0000519 // Munch the semicolon after a namespace. This is more common than one would
520 // think. Puttin the semicolon into its own line is very ugly.
521 if (FormatTok.Tok.is(tok::semi))
522 nextToken();
Alexander Kornienko15757312012-12-06 18:03:27 +0000523 addUnwrappedLine();
524 }
525 // FIXME: Add error handling.
526}
527
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000528void UnwrappedLineParser::parseForOrWhileLoop() {
529 assert((FormatTok.Tok.is(tok::kw_for) || FormatTok.Tok.is(tok::kw_while)) &&
530 "'for' or 'while' expected");
531 nextToken();
Manuel Klimek6eca03f2013-01-11 19:23:05 +0000532 if (FormatTok.Tok.is(tok::l_paren))
533 parseParens();
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000534 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000535 parseBlock(/*MustBeDeclaration=*/ false);
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000536 addUnwrappedLine();
537 } else {
538 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000539 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000540 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000541 --Line->Level;
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000542 }
543}
544
Daniel Jasperbac016b2012-12-03 18:12:45 +0000545void UnwrappedLineParser::parseDoWhile() {
546 assert(FormatTok.Tok.is(tok::kw_do) && "'do' expected");
547 nextToken();
548 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000549 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000550 } else {
551 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000552 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000553 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000554 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000555 }
556
Alexander Kornienko393b0082012-12-04 15:40:36 +0000557 // FIXME: Add error handling.
558 if (!FormatTok.Tok.is(tok::kw_while)) {
559 addUnwrappedLine();
560 return;
561 }
562
Daniel Jasperbac016b2012-12-03 18:12:45 +0000563 nextToken();
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000564 parseStructuralElement();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000565}
566
567void UnwrappedLineParser::parseLabel() {
Daniel Jasper89a0daa2013-02-12 20:17:17 +0000568 if (FormatTok.Tok.isNot(tok::colon))
569 return;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000570 nextToken();
Manuel Klimek526ed112013-01-09 15:25:02 +0000571 unsigned OldLineLevel = Line->Level;
572 if (Line->Level > 0)
573 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000574 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000575 parseBlock(/*MustBeDeclaration=*/ false);
Nico Weber94fb7292013-01-18 05:50:57 +0000576 if (FormatTok.Tok.is(tok::kw_break))
577 parseStructuralElement(); // "break;" after "}" goes on the same line.
Daniel Jasperbac016b2012-12-03 18:12:45 +0000578 }
579 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000580 Line->Level = OldLineLevel;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000581}
582
583void UnwrappedLineParser::parseCaseLabel() {
584 assert(FormatTok.Tok.is(tok::kw_case) && "'case' expected");
585 // FIXME: fix handling of complex expressions here.
586 do {
587 nextToken();
588 } while (!eof() && !FormatTok.Tok.is(tok::colon));
589 parseLabel();
590}
591
592void UnwrappedLineParser::parseSwitch() {
593 assert(FormatTok.Tok.is(tok::kw_switch) && "'switch' expected");
594 nextToken();
Manuel Klimek6eca03f2013-01-11 19:23:05 +0000595 if (FormatTok.Tok.is(tok::l_paren))
596 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000597 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000598 parseBlock(/*MustBeDeclaration=*/ false, Style.IndentCaseLabels ? 2 : 1);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000599 addUnwrappedLine();
600 } else {
601 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000602 Line->Level += (Style.IndentCaseLabels ? 2 : 1);
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000603 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000604 Line->Level -= (Style.IndentCaseLabels ? 2 : 1);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000605 }
606}
607
608void UnwrappedLineParser::parseAccessSpecifier() {
609 nextToken();
Alexander Kornienko56e49c52012-12-10 16:34:48 +0000610 // Otherwise, we don't know what it is, and we'd better keep the next token.
611 if (FormatTok.Tok.is(tok::colon))
612 nextToken();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000613 addUnwrappedLine();
614}
615
616void UnwrappedLineParser::parseEnum() {
Manuel Klimek308232c2013-01-21 19:17:52 +0000617 nextToken();
618 if (FormatTok.Tok.is(tok::identifier) ||
619 FormatTok.Tok.is(tok::kw___attribute) ||
620 FormatTok.Tok.is(tok::kw___declspec)) {
621 nextToken();
622 // We can have macros or attributes in between 'enum' and the enum name.
623 if (FormatTok.Tok.is(tok::l_paren)) {
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000624 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000625 }
Manuel Klimek308232c2013-01-21 19:17:52 +0000626 if (FormatTok.Tok.is(tok::identifier))
627 nextToken();
628 }
629 if (FormatTok.Tok.is(tok::l_brace)) {
630 nextToken();
631 addUnwrappedLine();
632 ++Line->Level;
633 do {
634 switch (FormatTok.Tok.getKind()) {
Manuel Klimek308232c2013-01-21 19:17:52 +0000635 case tok::l_paren:
636 parseParens();
637 break;
638 case tok::r_brace:
639 addUnwrappedLine();
640 nextToken();
641 --Line->Level;
642 return;
643 case tok::comma:
644 nextToken();
645 addUnwrappedLine();
646 break;
647 default:
648 nextToken();
649 break;
650 }
651 } while (!eof());
652 }
653 // We fall through to parsing a structural element afterwards, so that in
654 // enum A {} n, m;
655 // "} n, m;" will end up in one unwrapped line.
Daniel Jasperbac016b2012-12-03 18:12:45 +0000656}
657
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000658void UnwrappedLineParser::parseRecord() {
Manuel Klimekde768542013-01-07 18:10:23 +0000659 nextToken();
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000660 if (FormatTok.Tok.is(tok::identifier) ||
661 FormatTok.Tok.is(tok::kw___attribute) ||
662 FormatTok.Tok.is(tok::kw___declspec)) {
663 nextToken();
664 // We can have macros or attributes in between 'class' and the class name.
665 if (FormatTok.Tok.is(tok::l_paren)) {
666 parseParens();
Manuel Klimekde768542013-01-07 18:10:23 +0000667 }
Manuel Klimekb8b1ce12013-02-06 15:57:54 +0000668 // The actual identifier can be a nested name specifier, and in macros
669 // it is often token-pasted.
Manuel Klimek7f5b0252013-01-21 10:17:14 +0000670 while (FormatTok.Tok.is(tok::identifier) ||
Manuel Klimekb8b1ce12013-02-06 15:57:54 +0000671 FormatTok.Tok.is(tok::coloncolon) ||
672 FormatTok.Tok.is(tok::hashhash))
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000673 nextToken();
674
Manuel Klimek3a3408c2013-01-21 13:58:54 +0000675 // Note that parsing away template declarations here leads to incorrectly
676 // accepting function declarations as record declarations.
677 // In general, we cannot solve this problem. Consider:
678 // class A<int> B() {}
679 // which can be a function definition or a class definition when B() is a
680 // macro. If we find enough real-world cases where this is a problem, we
681 // can parse for the 'template' keyword in the beginning of the statement,
682 // and thus rule out the record production in case there is no template
683 // (this would still leave us with an ambiguity between template function
684 // and class declarations).
685 if (FormatTok.Tok.is(tok::colon) || FormatTok.Tok.is(tok::less)) {
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000686 while (FormatTok.Tok.isNot(tok::l_brace)) {
687 if (FormatTok.Tok.is(tok::semi))
688 return;
689 nextToken();
690 }
691 }
692 }
693 if (FormatTok.Tok.is(tok::l_brace))
Manuel Klimek70b03f42013-01-23 09:32:48 +0000694 parseBlock(/*MustBeDeclaration=*/ true);
Manuel Klimek3a3408c2013-01-21 13:58:54 +0000695 // We fall through to parsing a structural element afterwards, so
696 // class A {} n, m;
697 // will end up in one unwrapped line.
Manuel Klimekde768542013-01-07 18:10:23 +0000698}
699
Nico Weber1abe6ea2013-01-09 21:15:03 +0000700void UnwrappedLineParser::parseObjCProtocolList() {
701 assert(FormatTok.Tok.is(tok::less) && "'<' expected.");
702 do
703 nextToken();
704 while (!eof() && FormatTok.Tok.isNot(tok::greater));
705 nextToken(); // Skip '>'.
706}
707
708void UnwrappedLineParser::parseObjCUntilAtEnd() {
709 do {
710 if (FormatTok.Tok.isObjCAtKeyword(tok::objc_end)) {
711 nextToken();
712 addUnwrappedLine();
713 break;
714 }
715 parseStructuralElement();
716 } while (!eof());
717}
718
Nico Weber50767d82013-01-09 23:25:37 +0000719void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
Nico Weber27d13672013-01-09 20:25:35 +0000720 nextToken();
721 nextToken(); // interface name
722
723 // @interface can be followed by either a base class, or a category.
724 if (FormatTok.Tok.is(tok::colon)) {
725 nextToken();
726 nextToken(); // base class name
727 } else if (FormatTok.Tok.is(tok::l_paren))
728 // Skip category, if present.
729 parseParens();
730
Nico Weber1abe6ea2013-01-09 21:15:03 +0000731 if (FormatTok.Tok.is(tok::less))
732 parseObjCProtocolList();
Nico Weber27d13672013-01-09 20:25:35 +0000733
734 // If instance variables are present, keep the '{' on the first line too.
735 if (FormatTok.Tok.is(tok::l_brace))
Manuel Klimek70b03f42013-01-23 09:32:48 +0000736 parseBlock(/*MustBeDeclaration=*/ true);
Nico Weber27d13672013-01-09 20:25:35 +0000737
738 // With instance variables, this puts '}' on its own line. Without instance
739 // variables, this ends the @interface line.
740 addUnwrappedLine();
741
Nico Weber1abe6ea2013-01-09 21:15:03 +0000742 parseObjCUntilAtEnd();
743}
Nico Weber27d13672013-01-09 20:25:35 +0000744
Nico Weber1abe6ea2013-01-09 21:15:03 +0000745void UnwrappedLineParser::parseObjCProtocol() {
746 nextToken();
747 nextToken(); // protocol name
748
749 if (FormatTok.Tok.is(tok::less))
750 parseObjCProtocolList();
751
752 // Check for protocol declaration.
753 if (FormatTok.Tok.is(tok::semi)) {
754 nextToken();
755 return addUnwrappedLine();
756 }
757
758 addUnwrappedLine();
759 parseObjCUntilAtEnd();
Nico Weber27d13672013-01-09 20:25:35 +0000760}
761
Daniel Jasperbac016b2012-12-03 18:12:45 +0000762void UnwrappedLineParser::addUnwrappedLine() {
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000763 if (Line->Tokens.empty())
Daniel Jasper26f7e782013-01-08 14:56:18 +0000764 return;
Manuel Klimek8fa37992013-01-16 12:31:12 +0000765 DEBUG({
Manuel Klimeka28fc062013-02-11 12:33:24 +0000766 llvm::dbgs() << "Line(" << Line->Level << ")"
767 << (Line->InPPDirective ? " MACRO" : "") << ": ";
Manuel Klimek8fa37992013-01-16 12:31:12 +0000768 for (std::list<FormatToken>::iterator I = Line->Tokens.begin(),
769 E = Line->Tokens.end();
770 I != E; ++I) {
771 llvm::dbgs() << I->Tok.getName() << " ";
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000772
Manuel Klimek8fa37992013-01-16 12:31:12 +0000773 }
774 llvm::dbgs() << "\n";
775 });
Manuel Klimek525fe162013-01-18 14:04:34 +0000776 CurrentLines->push_back(*Line);
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000777 Line->Tokens.clear();
Manuel Klimek525fe162013-01-18 14:04:34 +0000778 if (CurrentLines == &Lines && !PreprocessorDirectives.empty()) {
779 for (std::vector<UnwrappedLine>::iterator I = PreprocessorDirectives
780 .begin(), E = PreprocessorDirectives.end();
781 I != E; ++I) {
782 CurrentLines->push_back(*I);
783 }
784 PreprocessorDirectives.clear();
785 }
786
Daniel Jasperbac016b2012-12-03 18:12:45 +0000787}
788
789bool UnwrappedLineParser::eof() const {
790 return FormatTok.Tok.is(tok::eof);
791}
792
Manuel Klimek86721d22013-01-22 16:31:55 +0000793void UnwrappedLineParser::flushComments(bool NewlineBeforeNext) {
794 bool JustComments = Line->Tokens.empty();
795 for (SmallVectorImpl<FormatToken>::const_iterator
796 I = CommentsBeforeNextToken.begin(),
797 E = CommentsBeforeNextToken.end();
798 I != E; ++I) {
Manuel Klimekb3507cd2013-02-06 16:40:56 +0000799 if (I->NewlinesBefore && JustComments) {
Manuel Klimek86721d22013-01-22 16:31:55 +0000800 addUnwrappedLine();
801 }
802 pushToken(*I);
803 }
804 if (NewlineBeforeNext && JustComments) {
805 addUnwrappedLine();
806 }
807 CommentsBeforeNextToken.clear();
808}
809
Daniel Jasperbac016b2012-12-03 18:12:45 +0000810void UnwrappedLineParser::nextToken() {
811 if (eof())
812 return;
Manuel Klimekb3507cd2013-02-06 16:40:56 +0000813 flushComments(FormatTok.NewlinesBefore > 0);
Manuel Klimek86721d22013-01-22 16:31:55 +0000814 pushToken(FormatTok);
Manuel Klimekd4397b92013-01-04 23:34:14 +0000815 readToken();
816}
817
818void UnwrappedLineParser::readToken() {
Manuel Klimek86721d22013-01-22 16:31:55 +0000819 bool CommentsInCurrentLine = true;
820 do {
821 FormatTok = Tokens->getNextToken();
822 while (!Line->InPPDirective && FormatTok.Tok.is(tok::hash) &&
823 ((FormatTok.NewlinesBefore > 0 && FormatTok.HasUnescapedNewline) ||
824 FormatTok.IsFirst)) {
825 // If there is an unfinished unwrapped line, we flush the preprocessor
826 // directives only after that unwrapped line was finished later.
827 bool SwitchToPreprocessorLines = !Line->Tokens.empty() &&
828 CurrentLines == &Lines;
829 ScopedLineState BlockState(*this, SwitchToPreprocessorLines);
830 parsePPDirective();
831 }
832 if (!FormatTok.Tok.is(tok::comment))
833 return;
Manuel Klimekb3507cd2013-02-06 16:40:56 +0000834 if (FormatTok.NewlinesBefore > 0 || FormatTok.IsFirst) {
Manuel Klimek86721d22013-01-22 16:31:55 +0000835 CommentsInCurrentLine = false;
836 }
837 if (CommentsInCurrentLine) {
838 pushToken(FormatTok);
839 } else {
840 CommentsBeforeNextToken.push_back(FormatTok);
841 }
842 } while (!eof());
843}
844
845void UnwrappedLineParser::pushToken(const FormatToken &Tok) {
846 Line->Tokens.push_back(Tok);
847 if (MustBreakBeforeNextToken) {
848 Line->Tokens.back().MustBreakBefore = true;
849 MustBreakBeforeNextToken = false;
Manuel Klimekd4397b92013-01-04 23:34:14 +0000850 }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000851}
852
Daniel Jaspercd162382013-01-07 13:26:07 +0000853} // end namespace format
854} // end namespace clang