blob: cb956084e0e330ae773f924c953f7340d5e4af0d [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
22// Uncomment to get debug output from tests:
23// #define DEBUG_WITH_TYPE(T, X) do { X; } while(0)
Manuel Klimek4c60fc62013-01-10 10:05:08 +000024
Daniel Jasperbac016b2012-12-03 18:12:45 +000025namespace clang {
26namespace format {
27
Manuel Klimek70b03f42013-01-23 09:32:48 +000028class ScopedDeclarationState {
29public:
30 ScopedDeclarationState(UnwrappedLine &Line, std::vector<bool> &Stack,
31 bool MustBeDeclaration)
32 : Line(Line), Stack(Stack) {
Manuel Klimek70b03f42013-01-23 09:32:48 +000033 Line.MustBeDeclaration = MustBeDeclaration;
Manuel Klimek836b58f2013-01-23 11:03:04 +000034 Stack.push_back(MustBeDeclaration);
Manuel Klimek70b03f42013-01-23 09:32:48 +000035 }
36 ~ScopedDeclarationState() {
Manuel Klimek70b03f42013-01-23 09:32:48 +000037 Stack.pop_back();
Manuel Klimeka32a7fd2013-01-23 14:08:21 +000038 if (!Stack.empty())
39 Line.MustBeDeclaration = Stack.back();
40 else
41 Line.MustBeDeclaration = true;
Manuel Klimek70b03f42013-01-23 09:32:48 +000042 }
43private:
44 UnwrappedLine &Line;
45 std::vector<bool> &Stack;
46};
47
Manuel Klimekd4397b92013-01-04 23:34:14 +000048class ScopedMacroState : public FormatTokenSource {
49public:
50 ScopedMacroState(UnwrappedLine &Line, FormatTokenSource *&TokenSource,
51 FormatToken &ResetToken)
52 : Line(Line), TokenSource(TokenSource), ResetToken(ResetToken),
Manuel Klimekc37b4d62013-01-05 22:14:16 +000053 PreviousLineLevel(Line.Level), PreviousTokenSource(TokenSource) {
Manuel Klimekd4397b92013-01-04 23:34:14 +000054 TokenSource = this;
Manuel Klimekc37b4d62013-01-05 22:14:16 +000055 Line.Level = 0;
Manuel Klimekd4397b92013-01-04 23:34:14 +000056 Line.InPPDirective = true;
57 }
58
59 ~ScopedMacroState() {
60 TokenSource = PreviousTokenSource;
61 ResetToken = Token;
62 Line.InPPDirective = false;
Manuel Klimekc37b4d62013-01-05 22:14:16 +000063 Line.Level = PreviousLineLevel;
Manuel Klimekd4397b92013-01-04 23:34:14 +000064 }
65
66 virtual FormatToken getNextToken() {
Manuel Klimekdd5b1012013-01-07 10:03:37 +000067 // The \c UnwrappedLineParser guards against this by never calling
68 // \c getNextToken() after it has encountered the first eof token.
69 assert(!eof());
Manuel Klimekd4397b92013-01-04 23:34:14 +000070 Token = PreviousTokenSource->getNextToken();
71 if (eof())
72 return createEOF();
73 return Token;
74 }
75
76private:
77 bool eof() {
78 return Token.NewlinesBefore > 0 && Token.HasUnescapedNewline;
79 }
80
81 FormatToken createEOF() {
82 FormatToken FormatTok;
83 FormatTok.Tok.startToken();
84 FormatTok.Tok.setKind(tok::eof);
85 return FormatTok;
86 }
87
88 UnwrappedLine &Line;
89 FormatTokenSource *&TokenSource;
90 FormatToken &ResetToken;
Manuel Klimekc37b4d62013-01-05 22:14:16 +000091 unsigned PreviousLineLevel;
Manuel Klimekd4397b92013-01-04 23:34:14 +000092 FormatTokenSource *PreviousTokenSource;
93
94 FormatToken Token;
95};
96
Manuel Klimekbb42bf12013-01-10 11:52:21 +000097class ScopedLineState {
98public:
Manuel Klimek525fe162013-01-18 14:04:34 +000099 ScopedLineState(UnwrappedLineParser &Parser,
100 bool SwitchToPreprocessorLines = false)
101 : Parser(Parser), SwitchToPreprocessorLines(SwitchToPreprocessorLines) {
102 if (SwitchToPreprocessorLines)
103 Parser.CurrentLines = &Parser.PreprocessorDirectives;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000104 PreBlockLine = Parser.Line.take();
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000105 Parser.Line.reset(new UnwrappedLine());
106 Parser.Line->Level = PreBlockLine->Level;
107 Parser.Line->InPPDirective = PreBlockLine->InPPDirective;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000108 }
109
110 ~ScopedLineState() {
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000111 if (!Parser.Line->Tokens.empty()) {
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000112 Parser.addUnwrappedLine();
113 }
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000114 assert(Parser.Line->Tokens.empty());
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000115 Parser.Line.reset(PreBlockLine);
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000116 Parser.MustBreakBeforeNextToken = true;
Manuel Klimek525fe162013-01-18 14:04:34 +0000117 if (SwitchToPreprocessorLines)
118 Parser.CurrentLines = &Parser.Lines;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000119 }
120
121private:
122 UnwrappedLineParser &Parser;
Manuel Klimek525fe162013-01-18 14:04:34 +0000123 const bool SwitchToPreprocessorLines;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000124
125 UnwrappedLine *PreBlockLine;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000126};
127
Alexander Kornienko3048aea2013-01-10 15:05:09 +0000128UnwrappedLineParser::UnwrappedLineParser(
129 clang::DiagnosticsEngine &Diag, const FormatStyle &Style,
130 FormatTokenSource &Tokens, UnwrappedLineConsumer &Callback)
Manuel Klimek525fe162013-01-18 14:04:34 +0000131 : Line(new UnwrappedLine), MustBreakBeforeNextToken(false),
132 CurrentLines(&Lines), Diag(Diag), Style(Style), Tokens(&Tokens),
133 Callback(Callback) {}
Daniel Jasperbac016b2012-12-03 18:12:45 +0000134
Alexander Kornienkocff563c2012-12-04 17:27:50 +0000135bool UnwrappedLineParser::parse() {
Manuel Klimek8fa37992013-01-16 12:31:12 +0000136 DEBUG(llvm::dbgs() << "----\n");
Manuel Klimekd4397b92013-01-04 23:34:14 +0000137 readToken();
Manuel Klimek525fe162013-01-18 14:04:34 +0000138 bool Error = parseFile();
139 for (std::vector<UnwrappedLine>::iterator I = Lines.begin(),
140 E = Lines.end();
141 I != E; ++I) {
142 Callback.consumeUnwrappedLine(*I);
143 }
144 return Error;
Manuel Klimekd4397b92013-01-04 23:34:14 +0000145}
146
147bool UnwrappedLineParser::parseFile() {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000148 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
149 /*MustBeDeclaration=*/ true);
Manuel Klimeka5342db2013-01-06 20:07:31 +0000150 bool Error = parseLevel(/*HasOpeningBrace=*/false);
Manuel Klimekd4397b92013-01-04 23:34:14 +0000151 // Make sure to format the remaining tokens.
Manuel Klimek86721d22013-01-22 16:31:55 +0000152 flushComments(true);
Manuel Klimekd4397b92013-01-04 23:34:14 +0000153 addUnwrappedLine();
154 return Error;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000155}
156
Manuel Klimeka5342db2013-01-06 20:07:31 +0000157bool UnwrappedLineParser::parseLevel(bool HasOpeningBrace) {
Alexander Kornienkocff563c2012-12-04 17:27:50 +0000158 bool Error = false;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000159 do {
160 switch (FormatTok.Tok.getKind()) {
Daniel Jasperbac016b2012-12-03 18:12:45 +0000161 case tok::comment:
Daniel Jasper05b1ac82012-12-17 11:29:41 +0000162 nextToken();
163 addUnwrappedLine();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000164 break;
165 case tok::l_brace:
Manuel Klimek70b03f42013-01-23 09:32:48 +0000166 // FIXME: Add parameter whether this can happen - if this happens, we must
167 // be in a non-declaration context.
168 Error |= parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000169 addUnwrappedLine();
170 break;
171 case tok::r_brace:
Manuel Klimeka5342db2013-01-06 20:07:31 +0000172 if (HasOpeningBrace) {
173 return false;
174 } else {
Alexander Kornienko3048aea2013-01-10 15:05:09 +0000175 Diag.Report(FormatTok.Tok.getLocation(),
176 Diag.getCustomDiagID(clang::DiagnosticsEngine::Error,
Alexander Kornienko276a2092013-01-11 16:03:45 +0000177 "unexpected '}'"));
Manuel Klimeka5342db2013-01-06 20:07:31 +0000178 Error = true;
179 nextToken();
180 addUnwrappedLine();
181 }
182 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000183 default:
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000184 parseStructuralElement();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000185 break;
186 }
187 } while (!eof());
Alexander Kornienkocff563c2012-12-04 17:27:50 +0000188 return Error;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000189}
190
Nico Weberd74fcdb2013-02-10 20:35:35 +0000191bool UnwrappedLineParser::parseBlock(bool MustBeDeclaration,
192 unsigned AddLevels) {
Alexander Kornienkoa3a2b3a2012-12-06 17:49:17 +0000193 assert(FormatTok.Tok.is(tok::l_brace) && "'{' expected");
Daniel Jasperbac016b2012-12-03 18:12:45 +0000194 nextToken();
195
Manuel Klimek2f1ac412013-01-21 16:42:44 +0000196 addUnwrappedLine();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000197
Manuel Klimek70b03f42013-01-23 09:32:48 +0000198 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
199 MustBeDeclaration);
Manuel Klimek2f1ac412013-01-21 16:42:44 +0000200 Line->Level += AddLevels;
201 parseLevel(/*HasOpeningBrace=*/true);
Alexander Kornienko15757312012-12-06 18:03:27 +0000202
Manuel Klimek86721d22013-01-22 16:31:55 +0000203 if (!FormatTok.Tok.is(tok::r_brace)) {
204 Line->Level -= AddLevels;
Manuel Klimek2f1ac412013-01-21 16:42:44 +0000205 return true;
Manuel Klimek86721d22013-01-22 16:31:55 +0000206 }
Alexander Kornienko393b0082012-12-04 15:40:36 +0000207
Manuel Klimekde768542013-01-07 18:10:23 +0000208 nextToken(); // Munch the closing brace.
Manuel Klimek86721d22013-01-22 16:31:55 +0000209 Line->Level -= AddLevels;
Alexander Kornienkocff563c2012-12-04 17:27:50 +0000210 return false;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000211}
212
213void UnwrappedLineParser::parsePPDirective() {
Manuel Klimeka080a182013-01-02 16:30:12 +0000214 assert(FormatTok.Tok.is(tok::hash) && "'#' expected");
Manuel Klimek526ed112013-01-09 15:25:02 +0000215 ScopedMacroState MacroState(*Line, Tokens, FormatTok);
Manuel Klimeka080a182013-01-02 16:30:12 +0000216 nextToken();
217
Manuel Klimeka080a182013-01-02 16:30:12 +0000218 if (FormatTok.Tok.getIdentifierInfo() == NULL) {
Manuel Klimekbd04f2a2013-01-31 15:58:48 +0000219 parsePPUnknown();
Manuel Klimeka080a182013-01-02 16:30:12 +0000220 return;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000221 }
Manuel Klimeka080a182013-01-02 16:30:12 +0000222
Manuel Klimekd4397b92013-01-04 23:34:14 +0000223 switch (FormatTok.Tok.getIdentifierInfo()->getPPKeywordID()) {
224 case tok::pp_define:
225 parsePPDefine();
226 break;
227 default:
228 parsePPUnknown();
229 break;
230 }
231}
232
233void UnwrappedLineParser::parsePPDefine() {
234 nextToken();
235
236 if (FormatTok.Tok.getKind() != tok::identifier) {
237 parsePPUnknown();
238 return;
239 }
240 nextToken();
Manuel Klimek7ccbc212013-01-23 14:37:36 +0000241 if (FormatTok.Tok.getKind() == tok::l_paren &&
242 FormatTok.WhiteSpaceLength == 0) {
Manuel Klimekd4397b92013-01-04 23:34:14 +0000243 parseParens();
244 }
245 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000246 Line->Level = 1;
Manuel Klimekc3d0c822013-01-07 09:34:28 +0000247
248 // Errors during a preprocessor directive can only affect the layout of the
249 // preprocessor directive, and thus we ignore them. An alternative approach
250 // would be to use the same approach we use on the file level (no
251 // re-indentation if there was a structural error) within the macro
252 // definition.
Manuel Klimekd4397b92013-01-04 23:34:14 +0000253 parseFile();
254}
255
256void UnwrappedLineParser::parsePPUnknown() {
Manuel Klimeka080a182013-01-02 16:30:12 +0000257 do {
Manuel Klimeka080a182013-01-02 16:30:12 +0000258 nextToken();
259 } while (!eof());
260 addUnwrappedLine();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000261}
262
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000263void UnwrappedLineParser::parseStructuralElement() {
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000264 assert(!FormatTok.Tok.is(tok::l_brace));
Dmitri Gribenko1f94f2b2012-12-30 21:27:25 +0000265 int TokenNumber = 0;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000266 switch (FormatTok.Tok.getKind()) {
Nico Weber6092d4e2013-01-07 19:05:19 +0000267 case tok::at:
268 nextToken();
Nico Weberd74fcdb2013-02-10 20:35:35 +0000269 if (FormatTok.Tok.is(tok::l_brace)) {
270 parseBracedList();
271 break;
272 }
Nico Weber6092d4e2013-01-07 19:05:19 +0000273 switch (FormatTok.Tok.getObjCKeywordID()) {
274 case tok::objc_public:
275 case tok::objc_protected:
276 case tok::objc_package:
277 case tok::objc_private:
278 return parseAccessSpecifier();
Nico Weber27d13672013-01-09 20:25:35 +0000279 case tok::objc_interface:
Nico Weber50767d82013-01-09 23:25:37 +0000280 case tok::objc_implementation:
281 return parseObjCInterfaceOrImplementation();
Nico Weber1abe6ea2013-01-09 21:15:03 +0000282 case tok::objc_protocol:
283 return parseObjCProtocol();
Nico Weber049c4472013-01-09 21:42:32 +0000284 case tok::objc_end:
285 return; // Handled by the caller.
Nico Weberb530fa32013-01-10 00:25:19 +0000286 case tok::objc_optional:
287 case tok::objc_required:
288 nextToken();
289 addUnwrappedLine();
290 return;
Nico Weber6092d4e2013-01-07 19:05:19 +0000291 default:
292 break;
293 }
294 break;
Alexander Kornienko15757312012-12-06 18:03:27 +0000295 case tok::kw_namespace:
296 parseNamespace();
297 return;
Dmitri Gribenko1f94f2b2012-12-30 21:27:25 +0000298 case tok::kw_inline:
299 nextToken();
300 TokenNumber++;
301 if (FormatTok.Tok.is(tok::kw_namespace)) {
302 parseNamespace();
303 return;
304 }
305 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000306 case tok::kw_public:
307 case tok::kw_protected:
308 case tok::kw_private:
Daniel Jasperbac016b2012-12-03 18:12:45 +0000309 parseAccessSpecifier();
310 return;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000311 case tok::kw_if:
312 parseIfThenElse();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000313 return;
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000314 case tok::kw_for:
315 case tok::kw_while:
316 parseForOrWhileLoop();
317 return;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000318 case tok::kw_do:
319 parseDoWhile();
320 return;
321 case tok::kw_switch:
322 parseSwitch();
323 return;
324 case tok::kw_default:
325 nextToken();
326 parseLabel();
327 return;
328 case tok::kw_case:
329 parseCaseLabel();
330 return;
Manuel Klimekc44ee892013-01-21 10:07:49 +0000331 case tok::kw_return:
332 parseReturn();
333 return;
Manuel Klimekd19dc2d2013-01-21 14:32:05 +0000334 case tok::kw_extern:
335 nextToken();
336 if (FormatTok.Tok.is(tok::string_literal)) {
337 nextToken();
338 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000339 parseBlock(/*MustBeDeclaration=*/ true, 0);
Manuel Klimekd19dc2d2013-01-21 14:32:05 +0000340 addUnwrappedLine();
341 return;
342 }
343 }
344 // In all other cases, parse the declaration.
345 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000346 default:
347 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000348 }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000349 do {
350 ++TokenNumber;
351 switch (FormatTok.Tok.getKind()) {
Nico Weberd74fcdb2013-02-10 20:35:35 +0000352 case tok::at:
353 nextToken();
354 if (FormatTok.Tok.is(tok::l_brace))
355 parseBracedList();
356 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000357 case tok::kw_enum:
358 parseEnum();
Manuel Klimek308232c2013-01-21 19:17:52 +0000359 break;
Alexander Kornienkod8818752013-01-16 11:43:46 +0000360 case tok::kw_struct:
361 case tok::kw_union:
Manuel Klimekde768542013-01-07 18:10:23 +0000362 case tok::kw_class:
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000363 parseRecord();
364 // A record declaration or definition is always the start of a structural
365 // element.
366 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000367 case tok::semi:
368 nextToken();
369 addUnwrappedLine();
370 return;
Alexander Kornienkod8818752013-01-16 11:43:46 +0000371 case tok::r_brace:
372 addUnwrappedLine();
373 return;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000374 case tok::l_paren:
375 parseParens();
376 break;
377 case tok::l_brace:
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000378 // A block outside of parentheses must be the last part of a
379 // structural element.
380 // FIXME: Figure out cases where this is not true, and add projections for
381 // them (the one we know is missing are lambdas).
Manuel Klimek70b03f42013-01-23 09:32:48 +0000382 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000383 addUnwrappedLine();
384 return;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000385 case tok::identifier:
Daniel Jasperbac016b2012-12-03 18:12:45 +0000386 nextToken();
387 if (TokenNumber == 1 && FormatTok.Tok.is(tok::colon)) {
388 parseLabel();
389 return;
390 }
391 break;
Daniel Jasper05b1ac82012-12-17 11:29:41 +0000392 case tok::equal:
393 nextToken();
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000394 if (FormatTok.Tok.is(tok::l_brace)) {
395 parseBracedList();
396 }
Daniel Jasper05b1ac82012-12-17 11:29:41 +0000397 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000398 default:
399 nextToken();
400 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000401 }
402 } while (!eof());
403}
404
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000405void UnwrappedLineParser::parseBracedList() {
406 nextToken();
407
408 do {
409 switch (FormatTok.Tok.getKind()) {
410 case tok::l_brace:
411 parseBracedList();
412 break;
413 case tok::r_brace:
414 nextToken();
415 return;
416 default:
417 nextToken();
418 break;
419 }
420 } while (!eof());
421}
422
Manuel Klimekc44ee892013-01-21 10:07:49 +0000423void UnwrappedLineParser::parseReturn() {
424 nextToken();
425
426 do {
427 switch (FormatTok.Tok.getKind()) {
428 case tok::l_brace:
429 parseBracedList();
430 break;
431 case tok::l_paren:
432 parseParens();
433 break;
434 case tok::r_brace:
435 // Assume missing ';'.
436 addUnwrappedLine();
437 return;
438 case tok::semi:
439 nextToken();
440 addUnwrappedLine();
441 return;
442 default:
443 nextToken();
444 break;
445 }
446 } while (!eof());
447}
448
Daniel Jasperbac016b2012-12-03 18:12:45 +0000449void UnwrappedLineParser::parseParens() {
450 assert(FormatTok.Tok.is(tok::l_paren) && "'(' expected.");
451 nextToken();
452 do {
453 switch (FormatTok.Tok.getKind()) {
454 case tok::l_paren:
455 parseParens();
456 break;
457 case tok::r_paren:
458 nextToken();
459 return;
Nico Weber2afbe522013-02-10 04:38:23 +0000460 case tok::l_brace: {
461 nextToken();
462 ScopedLineState LineState(*this);
463 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
464 /*MustBeDeclaration=*/ false);
465 Line->Level += 1;
466 parseLevel(/*HasOpeningBrace=*/ true);
467 Line->Level -= 1;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000468 break;
Nico Weber2afbe522013-02-10 04:38:23 +0000469 }
Nico Weberd74fcdb2013-02-10 20:35:35 +0000470 case tok::at:
471 nextToken();
472 if (FormatTok.Tok.is(tok::l_brace))
473 parseBracedList();
474 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000475 default:
476 nextToken();
477 break;
478 }
479 } while (!eof());
480}
481
482void UnwrappedLineParser::parseIfThenElse() {
483 assert(FormatTok.Tok.is(tok::kw_if) && "'if' expected");
484 nextToken();
Manuel Klimekd4658432013-01-11 18:28:36 +0000485 if (FormatTok.Tok.is(tok::l_paren))
486 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000487 bool NeedsUnwrappedLine = false;
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 NeedsUnwrappedLine = true;
491 } else {
492 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000493 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000494 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000495 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000496 }
497 if (FormatTok.Tok.is(tok::kw_else)) {
498 nextToken();
499 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000500 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000501 addUnwrappedLine();
502 } else if (FormatTok.Tok.is(tok::kw_if)) {
503 parseIfThenElse();
504 } else {
505 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000506 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000507 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000508 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000509 }
510 } else if (NeedsUnwrappedLine) {
511 addUnwrappedLine();
512 }
513}
514
Alexander Kornienko15757312012-12-06 18:03:27 +0000515void UnwrappedLineParser::parseNamespace() {
516 assert(FormatTok.Tok.is(tok::kw_namespace) && "'namespace' expected");
517 nextToken();
518 if (FormatTok.Tok.is(tok::identifier))
519 nextToken();
520 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000521 parseBlock(/*MustBeDeclaration=*/ true, 0);
Manuel Klimek7fc2db02013-02-06 16:08:09 +0000522 // Munch the semicolon after a namespace. This is more common than one would
523 // think. Puttin the semicolon into its own line is very ugly.
524 if (FormatTok.Tok.is(tok::semi))
525 nextToken();
Alexander Kornienko15757312012-12-06 18:03:27 +0000526 addUnwrappedLine();
527 }
528 // FIXME: Add error handling.
529}
530
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000531void UnwrappedLineParser::parseForOrWhileLoop() {
532 assert((FormatTok.Tok.is(tok::kw_for) || FormatTok.Tok.is(tok::kw_while)) &&
533 "'for' or 'while' expected");
534 nextToken();
Manuel Klimek6eca03f2013-01-11 19:23:05 +0000535 if (FormatTok.Tok.is(tok::l_paren))
536 parseParens();
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000537 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000538 parseBlock(/*MustBeDeclaration=*/ false);
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000539 addUnwrappedLine();
540 } else {
541 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000542 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000543 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000544 --Line->Level;
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000545 }
546}
547
Daniel Jasperbac016b2012-12-03 18:12:45 +0000548void UnwrappedLineParser::parseDoWhile() {
549 assert(FormatTok.Tok.is(tok::kw_do) && "'do' expected");
550 nextToken();
551 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000552 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000553 } else {
554 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000555 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000556 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000557 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000558 }
559
Alexander Kornienko393b0082012-12-04 15:40:36 +0000560 // FIXME: Add error handling.
561 if (!FormatTok.Tok.is(tok::kw_while)) {
562 addUnwrappedLine();
563 return;
564 }
565
Daniel Jasperbac016b2012-12-03 18:12:45 +0000566 nextToken();
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000567 parseStructuralElement();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000568}
569
570void UnwrappedLineParser::parseLabel() {
571 // FIXME: remove all asserts.
572 assert(FormatTok.Tok.is(tok::colon) && "':' expected");
573 nextToken();
Manuel Klimek526ed112013-01-09 15:25:02 +0000574 unsigned OldLineLevel = Line->Level;
575 if (Line->Level > 0)
576 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000577 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000578 parseBlock(/*MustBeDeclaration=*/ false);
Nico Weber94fb7292013-01-18 05:50:57 +0000579 if (FormatTok.Tok.is(tok::kw_break))
580 parseStructuralElement(); // "break;" after "}" goes on the same line.
Daniel Jasperbac016b2012-12-03 18:12:45 +0000581 }
582 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000583 Line->Level = OldLineLevel;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000584}
585
586void UnwrappedLineParser::parseCaseLabel() {
587 assert(FormatTok.Tok.is(tok::kw_case) && "'case' expected");
588 // FIXME: fix handling of complex expressions here.
589 do {
590 nextToken();
591 } while (!eof() && !FormatTok.Tok.is(tok::colon));
592 parseLabel();
593}
594
595void UnwrappedLineParser::parseSwitch() {
596 assert(FormatTok.Tok.is(tok::kw_switch) && "'switch' expected");
597 nextToken();
Manuel Klimek6eca03f2013-01-11 19:23:05 +0000598 if (FormatTok.Tok.is(tok::l_paren))
599 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000600 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000601 parseBlock(/*MustBeDeclaration=*/ false, Style.IndentCaseLabels ? 2 : 1);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000602 addUnwrappedLine();
603 } else {
604 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000605 Line->Level += (Style.IndentCaseLabels ? 2 : 1);
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000606 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000607 Line->Level -= (Style.IndentCaseLabels ? 2 : 1);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000608 }
609}
610
611void UnwrappedLineParser::parseAccessSpecifier() {
612 nextToken();
Alexander Kornienko56e49c52012-12-10 16:34:48 +0000613 // Otherwise, we don't know what it is, and we'd better keep the next token.
614 if (FormatTok.Tok.is(tok::colon))
615 nextToken();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000616 addUnwrappedLine();
617}
618
619void UnwrappedLineParser::parseEnum() {
Manuel Klimek308232c2013-01-21 19:17:52 +0000620 nextToken();
621 if (FormatTok.Tok.is(tok::identifier) ||
622 FormatTok.Tok.is(tok::kw___attribute) ||
623 FormatTok.Tok.is(tok::kw___declspec)) {
624 nextToken();
625 // We can have macros or attributes in between 'enum' and the enum name.
626 if (FormatTok.Tok.is(tok::l_paren)) {
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000627 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000628 }
Manuel Klimek308232c2013-01-21 19:17:52 +0000629 if (FormatTok.Tok.is(tok::identifier))
630 nextToken();
631 }
632 if (FormatTok.Tok.is(tok::l_brace)) {
633 nextToken();
634 addUnwrappedLine();
635 ++Line->Level;
636 do {
637 switch (FormatTok.Tok.getKind()) {
Manuel Klimek308232c2013-01-21 19:17:52 +0000638 case tok::l_paren:
639 parseParens();
640 break;
641 case tok::r_brace:
642 addUnwrappedLine();
643 nextToken();
644 --Line->Level;
645 return;
646 case tok::comma:
647 nextToken();
648 addUnwrappedLine();
649 break;
650 default:
651 nextToken();
652 break;
653 }
654 } while (!eof());
655 }
656 // We fall through to parsing a structural element afterwards, so that in
657 // enum A {} n, m;
658 // "} n, m;" will end up in one unwrapped line.
Daniel Jasperbac016b2012-12-03 18:12:45 +0000659}
660
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000661void UnwrappedLineParser::parseRecord() {
Manuel Klimekde768542013-01-07 18:10:23 +0000662 nextToken();
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000663 if (FormatTok.Tok.is(tok::identifier) ||
664 FormatTok.Tok.is(tok::kw___attribute) ||
665 FormatTok.Tok.is(tok::kw___declspec)) {
666 nextToken();
667 // We can have macros or attributes in between 'class' and the class name.
668 if (FormatTok.Tok.is(tok::l_paren)) {
669 parseParens();
Manuel Klimekde768542013-01-07 18:10:23 +0000670 }
Manuel Klimekb8b1ce12013-02-06 15:57:54 +0000671 // The actual identifier can be a nested name specifier, and in macros
672 // it is often token-pasted.
Manuel Klimek7f5b0252013-01-21 10:17:14 +0000673 while (FormatTok.Tok.is(tok::identifier) ||
Manuel Klimekb8b1ce12013-02-06 15:57:54 +0000674 FormatTok.Tok.is(tok::coloncolon) ||
675 FormatTok.Tok.is(tok::hashhash))
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000676 nextToken();
677
Manuel Klimek3a3408c2013-01-21 13:58:54 +0000678 // Note that parsing away template declarations here leads to incorrectly
679 // accepting function declarations as record declarations.
680 // In general, we cannot solve this problem. Consider:
681 // class A<int> B() {}
682 // which can be a function definition or a class definition when B() is a
683 // macro. If we find enough real-world cases where this is a problem, we
684 // can parse for the 'template' keyword in the beginning of the statement,
685 // and thus rule out the record production in case there is no template
686 // (this would still leave us with an ambiguity between template function
687 // and class declarations).
688 if (FormatTok.Tok.is(tok::colon) || FormatTok.Tok.is(tok::less)) {
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000689 while (FormatTok.Tok.isNot(tok::l_brace)) {
690 if (FormatTok.Tok.is(tok::semi))
691 return;
692 nextToken();
693 }
694 }
695 }
696 if (FormatTok.Tok.is(tok::l_brace))
Manuel Klimek70b03f42013-01-23 09:32:48 +0000697 parseBlock(/*MustBeDeclaration=*/ true);
Manuel Klimek3a3408c2013-01-21 13:58:54 +0000698 // We fall through to parsing a structural element afterwards, so
699 // class A {} n, m;
700 // will end up in one unwrapped line.
Manuel Klimekde768542013-01-07 18:10:23 +0000701}
702
Nico Weber1abe6ea2013-01-09 21:15:03 +0000703void UnwrappedLineParser::parseObjCProtocolList() {
704 assert(FormatTok.Tok.is(tok::less) && "'<' expected.");
705 do
706 nextToken();
707 while (!eof() && FormatTok.Tok.isNot(tok::greater));
708 nextToken(); // Skip '>'.
709}
710
711void UnwrappedLineParser::parseObjCUntilAtEnd() {
712 do {
713 if (FormatTok.Tok.isObjCAtKeyword(tok::objc_end)) {
714 nextToken();
715 addUnwrappedLine();
716 break;
717 }
718 parseStructuralElement();
719 } while (!eof());
720}
721
Nico Weber50767d82013-01-09 23:25:37 +0000722void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
Nico Weber27d13672013-01-09 20:25:35 +0000723 nextToken();
724 nextToken(); // interface name
725
726 // @interface can be followed by either a base class, or a category.
727 if (FormatTok.Tok.is(tok::colon)) {
728 nextToken();
729 nextToken(); // base class name
730 } else if (FormatTok.Tok.is(tok::l_paren))
731 // Skip category, if present.
732 parseParens();
733
Nico Weber1abe6ea2013-01-09 21:15:03 +0000734 if (FormatTok.Tok.is(tok::less))
735 parseObjCProtocolList();
Nico Weber27d13672013-01-09 20:25:35 +0000736
737 // If instance variables are present, keep the '{' on the first line too.
738 if (FormatTok.Tok.is(tok::l_brace))
Manuel Klimek70b03f42013-01-23 09:32:48 +0000739 parseBlock(/*MustBeDeclaration=*/ true);
Nico Weber27d13672013-01-09 20:25:35 +0000740
741 // With instance variables, this puts '}' on its own line. Without instance
742 // variables, this ends the @interface line.
743 addUnwrappedLine();
744
Nico Weber1abe6ea2013-01-09 21:15:03 +0000745 parseObjCUntilAtEnd();
746}
Nico Weber27d13672013-01-09 20:25:35 +0000747
Nico Weber1abe6ea2013-01-09 21:15:03 +0000748void UnwrappedLineParser::parseObjCProtocol() {
749 nextToken();
750 nextToken(); // protocol name
751
752 if (FormatTok.Tok.is(tok::less))
753 parseObjCProtocolList();
754
755 // Check for protocol declaration.
756 if (FormatTok.Tok.is(tok::semi)) {
757 nextToken();
758 return addUnwrappedLine();
759 }
760
761 addUnwrappedLine();
762 parseObjCUntilAtEnd();
Nico Weber27d13672013-01-09 20:25:35 +0000763}
764
Daniel Jasperbac016b2012-12-03 18:12:45 +0000765void UnwrappedLineParser::addUnwrappedLine() {
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000766 if (Line->Tokens.empty())
Daniel Jasper26f7e782013-01-08 14:56:18 +0000767 return;
Manuel Klimek8fa37992013-01-16 12:31:12 +0000768 DEBUG({
Manuel Klimek86721d22013-01-22 16:31:55 +0000769 llvm::dbgs() << "Line(" << Line->Level << "): ";
Manuel Klimek8fa37992013-01-16 12:31:12 +0000770 for (std::list<FormatToken>::iterator I = Line->Tokens.begin(),
771 E = Line->Tokens.end();
772 I != E; ++I) {
773 llvm::dbgs() << I->Tok.getName() << " ";
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000774
Manuel Klimek8fa37992013-01-16 12:31:12 +0000775 }
776 llvm::dbgs() << "\n";
777 });
Manuel Klimek525fe162013-01-18 14:04:34 +0000778 CurrentLines->push_back(*Line);
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000779 Line->Tokens.clear();
Manuel Klimek525fe162013-01-18 14:04:34 +0000780 if (CurrentLines == &Lines && !PreprocessorDirectives.empty()) {
781 for (std::vector<UnwrappedLine>::iterator I = PreprocessorDirectives
782 .begin(), E = PreprocessorDirectives.end();
783 I != E; ++I) {
784 CurrentLines->push_back(*I);
785 }
786 PreprocessorDirectives.clear();
787 }
788
Daniel Jasperbac016b2012-12-03 18:12:45 +0000789}
790
791bool UnwrappedLineParser::eof() const {
792 return FormatTok.Tok.is(tok::eof);
793}
794
Manuel Klimek86721d22013-01-22 16:31:55 +0000795void UnwrappedLineParser::flushComments(bool NewlineBeforeNext) {
796 bool JustComments = Line->Tokens.empty();
797 for (SmallVectorImpl<FormatToken>::const_iterator
798 I = CommentsBeforeNextToken.begin(),
799 E = CommentsBeforeNextToken.end();
800 I != E; ++I) {
Manuel Klimekb3507cd2013-02-06 16:40:56 +0000801 if (I->NewlinesBefore && JustComments) {
Manuel Klimek86721d22013-01-22 16:31:55 +0000802 addUnwrappedLine();
803 }
804 pushToken(*I);
805 }
806 if (NewlineBeforeNext && JustComments) {
807 addUnwrappedLine();
808 }
809 CommentsBeforeNextToken.clear();
810}
811
Daniel Jasperbac016b2012-12-03 18:12:45 +0000812void UnwrappedLineParser::nextToken() {
813 if (eof())
814 return;
Manuel Klimekb3507cd2013-02-06 16:40:56 +0000815 flushComments(FormatTok.NewlinesBefore > 0);
Manuel Klimek86721d22013-01-22 16:31:55 +0000816 pushToken(FormatTok);
Manuel Klimekd4397b92013-01-04 23:34:14 +0000817 readToken();
818}
819
820void UnwrappedLineParser::readToken() {
Manuel Klimek86721d22013-01-22 16:31:55 +0000821 bool CommentsInCurrentLine = true;
822 do {
823 FormatTok = Tokens->getNextToken();
824 while (!Line->InPPDirective && FormatTok.Tok.is(tok::hash) &&
825 ((FormatTok.NewlinesBefore > 0 && FormatTok.HasUnescapedNewline) ||
826 FormatTok.IsFirst)) {
827 // If there is an unfinished unwrapped line, we flush the preprocessor
828 // directives only after that unwrapped line was finished later.
829 bool SwitchToPreprocessorLines = !Line->Tokens.empty() &&
830 CurrentLines == &Lines;
831 ScopedLineState BlockState(*this, SwitchToPreprocessorLines);
832 parsePPDirective();
833 }
834 if (!FormatTok.Tok.is(tok::comment))
835 return;
Manuel Klimekb3507cd2013-02-06 16:40:56 +0000836 if (FormatTok.NewlinesBefore > 0 || FormatTok.IsFirst) {
Manuel Klimek86721d22013-01-22 16:31:55 +0000837 CommentsInCurrentLine = false;
838 }
839 if (CommentsInCurrentLine) {
840 pushToken(FormatTok);
841 } else {
842 CommentsBeforeNextToken.push_back(FormatTok);
843 }
844 } while (!eof());
845}
846
847void UnwrappedLineParser::pushToken(const FormatToken &Tok) {
848 Line->Tokens.push_back(Tok);
849 if (MustBreakBeforeNextToken) {
850 Line->Tokens.back().MustBreakBefore = true;
851 MustBreakBeforeNextToken = false;
Manuel Klimekd4397b92013-01-04 23:34:14 +0000852 }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000853}
854
Daniel Jaspercd162382013-01-07 13:26:07 +0000855} // end namespace format
856} // end namespace clang