blob: 2ca44620c33c8d4e8e2578dd179744371c1eab59 [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:
Daniel Jasperf9955d32013-03-20 12:37:50 +000074 bool eof() { return Token.NewlinesBefore > 0 && Token.HasUnescapedNewline; }
Manuel Klimekd4397b92013-01-04 23:34:14 +000075
76 FormatToken createEOF() {
77 FormatToken FormatTok;
78 FormatTok.Tok.startToken();
79 FormatTok.Tok.setKind(tok::eof);
80 return FormatTok;
81 }
82
83 UnwrappedLine &Line;
84 FormatTokenSource *&TokenSource;
85 FormatToken &ResetToken;
Manuel Klimekc37b4d62013-01-05 22:14:16 +000086 unsigned PreviousLineLevel;
Manuel Klimekd4397b92013-01-04 23:34:14 +000087 FormatTokenSource *PreviousTokenSource;
88
89 FormatToken Token;
90};
91
Manuel Klimekbb42bf12013-01-10 11:52:21 +000092class ScopedLineState {
93public:
Manuel Klimek525fe162013-01-18 14:04:34 +000094 ScopedLineState(UnwrappedLineParser &Parser,
95 bool SwitchToPreprocessorLines = false)
96 : Parser(Parser), SwitchToPreprocessorLines(SwitchToPreprocessorLines) {
97 if (SwitchToPreprocessorLines)
98 Parser.CurrentLines = &Parser.PreprocessorDirectives;
Manuel Klimekbb42bf12013-01-10 11:52:21 +000099 PreBlockLine = Parser.Line.take();
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000100 Parser.Line.reset(new UnwrappedLine());
101 Parser.Line->Level = PreBlockLine->Level;
102 Parser.Line->InPPDirective = PreBlockLine->InPPDirective;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000103 }
104
105 ~ScopedLineState() {
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000106 if (!Parser.Line->Tokens.empty()) {
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000107 Parser.addUnwrappedLine();
108 }
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000109 assert(Parser.Line->Tokens.empty());
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000110 Parser.Line.reset(PreBlockLine);
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000111 Parser.MustBreakBeforeNextToken = true;
Manuel Klimek525fe162013-01-18 14:04:34 +0000112 if (SwitchToPreprocessorLines)
113 Parser.CurrentLines = &Parser.Lines;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000114 }
115
116private:
117 UnwrappedLineParser &Parser;
Manuel Klimek525fe162013-01-18 14:04:34 +0000118 const bool SwitchToPreprocessorLines;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000119
120 UnwrappedLine *PreBlockLine;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000121};
122
Alexander Kornienko3048aea2013-01-10 15:05:09 +0000123UnwrappedLineParser::UnwrappedLineParser(
124 clang::DiagnosticsEngine &Diag, const FormatStyle &Style,
125 FormatTokenSource &Tokens, UnwrappedLineConsumer &Callback)
Manuel Klimek525fe162013-01-18 14:04:34 +0000126 : Line(new UnwrappedLine), MustBreakBeforeNextToken(false),
127 CurrentLines(&Lines), Diag(Diag), Style(Style), Tokens(&Tokens),
128 Callback(Callback) {}
Daniel Jasperbac016b2012-12-03 18:12:45 +0000129
Alexander Kornienkocff563c2012-12-04 17:27:50 +0000130bool UnwrappedLineParser::parse() {
Manuel Klimek8fa37992013-01-16 12:31:12 +0000131 DEBUG(llvm::dbgs() << "----\n");
Manuel Klimekd4397b92013-01-04 23:34:14 +0000132 readToken();
Manuel Klimek525fe162013-01-18 14:04:34 +0000133 bool Error = parseFile();
Daniel Jasperf9955d32013-03-20 12:37:50 +0000134 for (std::vector<UnwrappedLine>::iterator I = Lines.begin(), E = Lines.end();
Manuel Klimek525fe162013-01-18 14:04:34 +0000135 I != E; ++I) {
136 Callback.consumeUnwrappedLine(*I);
137 }
Daniel Jasper516fb312013-03-01 18:11:39 +0000138
139 // Create line with eof token.
140 pushToken(FormatTok);
141 Callback.consumeUnwrappedLine(*Line);
142
Manuel Klimek525fe162013-01-18 14:04:34 +0000143 return Error;
Manuel Klimekd4397b92013-01-04 23:34:14 +0000144}
145
146bool UnwrappedLineParser::parseFile() {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000147 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
148 /*MustBeDeclaration=*/ true);
Daniel Jasperf9955d32013-03-20 12:37:50 +0000149 bool Error = parseLevel(/*HasOpeningBrace=*/ false);
Manuel Klimekd4397b92013-01-04 23:34:14 +0000150 // Make sure to format the remaining tokens.
Manuel Klimek86721d22013-01-22 16:31:55 +0000151 flushComments(true);
Manuel Klimekd4397b92013-01-04 23:34:14 +0000152 addUnwrappedLine();
153 return Error;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000154}
155
Manuel Klimeka5342db2013-01-06 20:07:31 +0000156bool UnwrappedLineParser::parseLevel(bool HasOpeningBrace) {
Alexander Kornienkocff563c2012-12-04 17:27:50 +0000157 bool Error = false;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000158 do {
159 switch (FormatTok.Tok.getKind()) {
Daniel Jasperbac016b2012-12-03 18:12:45 +0000160 case tok::comment:
Daniel Jasper05b1ac82012-12-17 11:29:41 +0000161 nextToken();
162 addUnwrappedLine();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000163 break;
164 case tok::l_brace:
Manuel Klimek70b03f42013-01-23 09:32:48 +0000165 // FIXME: Add parameter whether this can happen - if this happens, we must
166 // be in a non-declaration context.
167 Error |= parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000168 addUnwrappedLine();
169 break;
170 case tok::r_brace:
Manuel Klimeka5342db2013-01-06 20:07:31 +0000171 if (HasOpeningBrace) {
172 return false;
173 } else {
Alexander Kornienko3048aea2013-01-10 15:05:09 +0000174 Diag.Report(FormatTok.Tok.getLocation(),
175 Diag.getCustomDiagID(clang::DiagnosticsEngine::Error,
Alexander Kornienko276a2092013-01-11 16:03:45 +0000176 "unexpected '}'"));
Manuel Klimeka5342db2013-01-06 20:07:31 +0000177 Error = true;
178 nextToken();
179 addUnwrappedLine();
180 }
181 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000182 default:
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000183 parseStructuralElement();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000184 break;
185 }
186 } while (!eof());
Alexander Kornienkocff563c2012-12-04 17:27:50 +0000187 return Error;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000188}
189
Nico Weberd74fcdb2013-02-10 20:35:35 +0000190bool UnwrappedLineParser::parseBlock(bool MustBeDeclaration,
191 unsigned AddLevels) {
Alexander Kornienkoa3a2b3a2012-12-06 17:49:17 +0000192 assert(FormatTok.Tok.is(tok::l_brace) && "'{' expected");
Daniel Jasperbac016b2012-12-03 18:12:45 +0000193 nextToken();
194
Manuel Klimek2f1ac412013-01-21 16:42:44 +0000195 addUnwrappedLine();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000196
Manuel Klimek70b03f42013-01-23 09:32:48 +0000197 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
198 MustBeDeclaration);
Manuel Klimek2f1ac412013-01-21 16:42:44 +0000199 Line->Level += AddLevels;
Daniel Jasperf9955d32013-03-20 12:37:50 +0000200 parseLevel(/*HasOpeningBrace=*/ true);
Alexander Kornienko15757312012-12-06 18:03:27 +0000201
Manuel Klimek86721d22013-01-22 16:31:55 +0000202 if (!FormatTok.Tok.is(tok::r_brace)) {
203 Line->Level -= AddLevels;
Manuel Klimek2f1ac412013-01-21 16:42:44 +0000204 return true;
Manuel Klimek86721d22013-01-22 16:31:55 +0000205 }
Alexander Kornienko393b0082012-12-04 15:40:36 +0000206
Daniel Jasperf9955d32013-03-20 12:37:50 +0000207 nextToken(); // Munch the closing brace.
Manuel Klimek86721d22013-01-22 16:31:55 +0000208 Line->Level -= AddLevels;
Alexander Kornienkocff563c2012-12-04 17:27:50 +0000209 return false;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000210}
211
212void UnwrappedLineParser::parsePPDirective() {
Manuel Klimeka080a182013-01-02 16:30:12 +0000213 assert(FormatTok.Tok.is(tok::hash) && "'#' expected");
Manuel Klimek526ed112013-01-09 15:25:02 +0000214 ScopedMacroState MacroState(*Line, Tokens, FormatTok);
Manuel Klimeka080a182013-01-02 16:30:12 +0000215 nextToken();
216
Manuel Klimeka080a182013-01-02 16:30:12 +0000217 if (FormatTok.Tok.getIdentifierInfo() == NULL) {
Manuel Klimekbd04f2a2013-01-31 15:58:48 +0000218 parsePPUnknown();
Manuel Klimeka080a182013-01-02 16:30:12 +0000219 return;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000220 }
Manuel Klimeka080a182013-01-02 16:30:12 +0000221
Manuel Klimekd4397b92013-01-04 23:34:14 +0000222 switch (FormatTok.Tok.getIdentifierInfo()->getPPKeywordID()) {
223 case tok::pp_define:
224 parsePPDefine();
225 break;
226 default:
227 parsePPUnknown();
228 break;
229 }
230}
231
232void UnwrappedLineParser::parsePPDefine() {
233 nextToken();
234
235 if (FormatTok.Tok.getKind() != tok::identifier) {
236 parsePPUnknown();
237 return;
238 }
239 nextToken();
Manuel Klimek7ccbc212013-01-23 14:37:36 +0000240 if (FormatTok.Tok.getKind() == tok::l_paren &&
241 FormatTok.WhiteSpaceLength == 0) {
Manuel Klimekd4397b92013-01-04 23:34:14 +0000242 parseParens();
243 }
244 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000245 Line->Level = 1;
Manuel Klimekc3d0c822013-01-07 09:34:28 +0000246
247 // Errors during a preprocessor directive can only affect the layout of the
248 // preprocessor directive, and thus we ignore them. An alternative approach
249 // would be to use the same approach we use on the file level (no
250 // re-indentation if there was a structural error) within the macro
251 // definition.
Manuel Klimekd4397b92013-01-04 23:34:14 +0000252 parseFile();
253}
254
255void UnwrappedLineParser::parsePPUnknown() {
Manuel Klimeka080a182013-01-02 16:30:12 +0000256 do {
Manuel Klimeka080a182013-01-02 16:30:12 +0000257 nextToken();
258 } while (!eof());
259 addUnwrappedLine();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000260}
261
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000262void UnwrappedLineParser::parseStructuralElement() {
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000263 assert(!FormatTok.Tok.is(tok::l_brace));
Dmitri Gribenko1f94f2b2012-12-30 21:27:25 +0000264 int TokenNumber = 0;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000265 switch (FormatTok.Tok.getKind()) {
Nico Weber6092d4e2013-01-07 19:05:19 +0000266 case tok::at:
267 nextToken();
Nico Weberd74fcdb2013-02-10 20:35:35 +0000268 if (FormatTok.Tok.is(tok::l_brace)) {
269 parseBracedList();
270 break;
271 }
Nico Weber6092d4e2013-01-07 19:05:19 +0000272 switch (FormatTok.Tok.getObjCKeywordID()) {
273 case tok::objc_public:
274 case tok::objc_protected:
275 case tok::objc_package:
276 case tok::objc_private:
277 return parseAccessSpecifier();
Nico Weber27d13672013-01-09 20:25:35 +0000278 case tok::objc_interface:
Nico Weber50767d82013-01-09 23:25:37 +0000279 case tok::objc_implementation:
280 return parseObjCInterfaceOrImplementation();
Nico Weber1abe6ea2013-01-09 21:15:03 +0000281 case tok::objc_protocol:
282 return parseObjCProtocol();
Nico Weber049c4472013-01-09 21:42:32 +0000283 case tok::objc_end:
284 return; // Handled by the caller.
Nico Weberb530fa32013-01-10 00:25:19 +0000285 case tok::objc_optional:
286 case tok::objc_required:
287 nextToken();
288 addUnwrappedLine();
289 return;
Nico Weber6092d4e2013-01-07 19:05:19 +0000290 default:
291 break;
292 }
293 break;
Alexander Kornienko15757312012-12-06 18:03:27 +0000294 case tok::kw_namespace:
295 parseNamespace();
296 return;
Dmitri Gribenko1f94f2b2012-12-30 21:27:25 +0000297 case tok::kw_inline:
298 nextToken();
299 TokenNumber++;
300 if (FormatTok.Tok.is(tok::kw_namespace)) {
301 parseNamespace();
302 return;
303 }
304 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000305 case tok::kw_public:
306 case tok::kw_protected:
307 case tok::kw_private:
Daniel Jasperbac016b2012-12-03 18:12:45 +0000308 parseAccessSpecifier();
309 return;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000310 case tok::kw_if:
311 parseIfThenElse();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000312 return;
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000313 case tok::kw_for:
314 case tok::kw_while:
315 parseForOrWhileLoop();
316 return;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000317 case tok::kw_do:
318 parseDoWhile();
319 return;
320 case tok::kw_switch:
321 parseSwitch();
322 return;
323 case tok::kw_default:
324 nextToken();
325 parseLabel();
326 return;
327 case tok::kw_case:
328 parseCaseLabel();
329 return;
Manuel Klimekc44ee892013-01-21 10:07:49 +0000330 case tok::kw_return:
331 parseReturn();
332 return;
Manuel Klimekd19dc2d2013-01-21 14:32:05 +0000333 case tok::kw_extern:
334 nextToken();
335 if (FormatTok.Tok.is(tok::string_literal)) {
336 nextToken();
337 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000338 parseBlock(/*MustBeDeclaration=*/ true, 0);
Manuel Klimekd19dc2d2013-01-21 14:32:05 +0000339 addUnwrappedLine();
340 return;
341 }
342 }
343 // In all other cases, parse the declaration.
344 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000345 default:
346 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000347 }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000348 do {
349 ++TokenNumber;
350 switch (FormatTok.Tok.getKind()) {
Nico Weberd74fcdb2013-02-10 20:35:35 +0000351 case tok::at:
352 nextToken();
353 if (FormatTok.Tok.is(tok::l_brace))
354 parseBracedList();
355 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000356 case tok::kw_enum:
357 parseEnum();
Manuel Klimek308232c2013-01-21 19:17:52 +0000358 break;
Alexander Kornienkod8818752013-01-16 11:43:46 +0000359 case tok::kw_struct:
360 case tok::kw_union:
Manuel Klimekde768542013-01-07 18:10:23 +0000361 case tok::kw_class:
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000362 parseRecord();
363 // A record declaration or definition is always the start of a structural
364 // element.
365 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000366 case tok::semi:
367 nextToken();
368 addUnwrappedLine();
369 return;
Alexander Kornienkod8818752013-01-16 11:43:46 +0000370 case tok::r_brace:
371 addUnwrappedLine();
372 return;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000373 case tok::l_paren:
374 parseParens();
375 break;
376 case tok::l_brace:
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000377 // A block outside of parentheses must be the last part of a
378 // structural element.
379 // FIXME: Figure out cases where this is not true, and add projections for
380 // them (the one we know is missing are lambdas).
Manuel Klimek70b03f42013-01-23 09:32:48 +0000381 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000382 addUnwrappedLine();
383 return;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000384 case tok::identifier:
Daniel Jasperbac016b2012-12-03 18:12:45 +0000385 nextToken();
386 if (TokenNumber == 1 && FormatTok.Tok.is(tok::colon)) {
387 parseLabel();
388 return;
389 }
390 break;
Daniel Jasper05b1ac82012-12-17 11:29:41 +0000391 case tok::equal:
392 nextToken();
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000393 if (FormatTok.Tok.is(tok::l_brace)) {
394 parseBracedList();
395 }
Daniel Jasper05b1ac82012-12-17 11:29:41 +0000396 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000397 default:
398 nextToken();
399 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000400 }
401 } while (!eof());
402}
403
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000404void UnwrappedLineParser::parseBracedList() {
405 nextToken();
406
407 do {
408 switch (FormatTok.Tok.getKind()) {
409 case tok::l_brace:
410 parseBracedList();
411 break;
412 case tok::r_brace:
413 nextToken();
414 return;
415 default:
416 nextToken();
417 break;
418 }
419 } while (!eof());
420}
421
Manuel Klimekc44ee892013-01-21 10:07:49 +0000422void UnwrappedLineParser::parseReturn() {
423 nextToken();
424
425 do {
426 switch (FormatTok.Tok.getKind()) {
427 case tok::l_brace:
428 parseBracedList();
429 break;
430 case tok::l_paren:
431 parseParens();
432 break;
433 case tok::r_brace:
434 // Assume missing ';'.
435 addUnwrappedLine();
436 return;
437 case tok::semi:
438 nextToken();
439 addUnwrappedLine();
440 return;
441 default:
442 nextToken();
443 break;
444 }
445 } while (!eof());
446}
447
Daniel Jasperbac016b2012-12-03 18:12:45 +0000448void UnwrappedLineParser::parseParens() {
449 assert(FormatTok.Tok.is(tok::l_paren) && "'(' expected.");
450 nextToken();
451 do {
452 switch (FormatTok.Tok.getKind()) {
453 case tok::l_paren:
454 parseParens();
455 break;
456 case tok::r_paren:
457 nextToken();
458 return;
Nico Weber2afbe522013-02-10 04:38:23 +0000459 case tok::l_brace: {
460 nextToken();
461 ScopedLineState LineState(*this);
462 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
463 /*MustBeDeclaration=*/ false);
464 Line->Level += 1;
465 parseLevel(/*HasOpeningBrace=*/ true);
466 Line->Level -= 1;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000467 break;
Nico Weber2afbe522013-02-10 04:38:23 +0000468 }
Nico Weberd74fcdb2013-02-10 20:35:35 +0000469 case tok::at:
470 nextToken();
471 if (FormatTok.Tok.is(tok::l_brace))
472 parseBracedList();
473 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000474 default:
475 nextToken();
476 break;
477 }
478 } while (!eof());
479}
480
481void UnwrappedLineParser::parseIfThenElse() {
482 assert(FormatTok.Tok.is(tok::kw_if) && "'if' expected");
483 nextToken();
Manuel Klimekd4658432013-01-11 18:28:36 +0000484 if (FormatTok.Tok.is(tok::l_paren))
485 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000486 bool NeedsUnwrappedLine = false;
487 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000488 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000489 NeedsUnwrappedLine = true;
490 } else {
491 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000492 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000493 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000494 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000495 }
496 if (FormatTok.Tok.is(tok::kw_else)) {
497 nextToken();
498 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000499 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000500 addUnwrappedLine();
501 } else if (FormatTok.Tok.is(tok::kw_if)) {
502 parseIfThenElse();
503 } else {
504 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000505 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000506 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000507 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000508 }
509 } else if (NeedsUnwrappedLine) {
510 addUnwrappedLine();
511 }
512}
513
Alexander Kornienko15757312012-12-06 18:03:27 +0000514void UnwrappedLineParser::parseNamespace() {
515 assert(FormatTok.Tok.is(tok::kw_namespace) && "'namespace' expected");
516 nextToken();
517 if (FormatTok.Tok.is(tok::identifier))
518 nextToken();
519 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000520 parseBlock(/*MustBeDeclaration=*/ true, 0);
Manuel Klimek7fc2db02013-02-06 16:08:09 +0000521 // Munch the semicolon after a namespace. This is more common than one would
522 // think. Puttin the semicolon into its own line is very ugly.
523 if (FormatTok.Tok.is(tok::semi))
524 nextToken();
Alexander Kornienko15757312012-12-06 18:03:27 +0000525 addUnwrappedLine();
526 }
527 // FIXME: Add error handling.
528}
529
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000530void UnwrappedLineParser::parseForOrWhileLoop() {
531 assert((FormatTok.Tok.is(tok::kw_for) || FormatTok.Tok.is(tok::kw_while)) &&
532 "'for' or 'while' expected");
533 nextToken();
Manuel Klimek6eca03f2013-01-11 19:23:05 +0000534 if (FormatTok.Tok.is(tok::l_paren))
535 parseParens();
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000536 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000537 parseBlock(/*MustBeDeclaration=*/ false);
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000538 addUnwrappedLine();
539 } else {
540 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000541 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000542 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000543 --Line->Level;
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000544 }
545}
546
Daniel Jasperbac016b2012-12-03 18:12:45 +0000547void UnwrappedLineParser::parseDoWhile() {
548 assert(FormatTok.Tok.is(tok::kw_do) && "'do' expected");
549 nextToken();
550 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000551 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000552 } else {
553 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000554 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000555 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000556 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000557 }
558
Alexander Kornienko393b0082012-12-04 15:40:36 +0000559 // FIXME: Add error handling.
560 if (!FormatTok.Tok.is(tok::kw_while)) {
561 addUnwrappedLine();
562 return;
563 }
564
Daniel Jasperbac016b2012-12-03 18:12:45 +0000565 nextToken();
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000566 parseStructuralElement();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000567}
568
569void UnwrappedLineParser::parseLabel() {
Daniel Jasper89a0daa2013-02-12 20:17:17 +0000570 if (FormatTok.Tok.isNot(tok::colon))
571 return;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000572 nextToken();
Manuel Klimek526ed112013-01-09 15:25:02 +0000573 unsigned OldLineLevel = Line->Level;
Daniel Jasperbcca7e42013-03-20 10:23:53 +0000574 if (Line->Level > 1 || (!Line->InPPDirective && Line->Level > 0))
Manuel Klimek526ed112013-01-09 15:25:02 +0000575 --Line->Level;
Daniel Jasperc30eb512013-03-19 18:33:58 +0000576 if (CommentsBeforeNextToken.empty() && FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000577 parseBlock(/*MustBeDeclaration=*/ false);
Nico Weber94fb7292013-01-18 05:50:57 +0000578 if (FormatTok.Tok.is(tok::kw_break))
579 parseStructuralElement(); // "break;" after "}" goes on the same line.
Daniel Jasperbac016b2012-12-03 18:12:45 +0000580 }
581 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000582 Line->Level = OldLineLevel;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000583}
584
585void UnwrappedLineParser::parseCaseLabel() {
586 assert(FormatTok.Tok.is(tok::kw_case) && "'case' expected");
587 // FIXME: fix handling of complex expressions here.
588 do {
589 nextToken();
590 } while (!eof() && !FormatTok.Tok.is(tok::colon));
591 parseLabel();
592}
593
594void UnwrappedLineParser::parseSwitch() {
595 assert(FormatTok.Tok.is(tok::kw_switch) && "'switch' expected");
596 nextToken();
Manuel Klimek6eca03f2013-01-11 19:23:05 +0000597 if (FormatTok.Tok.is(tok::l_paren))
598 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000599 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000600 parseBlock(/*MustBeDeclaration=*/ false, Style.IndentCaseLabels ? 2 : 1);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000601 addUnwrappedLine();
602 } else {
603 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000604 Line->Level += (Style.IndentCaseLabels ? 2 : 1);
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000605 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000606 Line->Level -= (Style.IndentCaseLabels ? 2 : 1);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000607 }
608}
609
610void UnwrappedLineParser::parseAccessSpecifier() {
611 nextToken();
Alexander Kornienko56e49c52012-12-10 16:34:48 +0000612 // Otherwise, we don't know what it is, and we'd better keep the next token.
613 if (FormatTok.Tok.is(tok::colon))
614 nextToken();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000615 addUnwrappedLine();
616}
617
618void UnwrappedLineParser::parseEnum() {
Manuel Klimek308232c2013-01-21 19:17:52 +0000619 nextToken();
620 if (FormatTok.Tok.is(tok::identifier) ||
621 FormatTok.Tok.is(tok::kw___attribute) ||
622 FormatTok.Tok.is(tok::kw___declspec)) {
623 nextToken();
624 // We can have macros or attributes in between 'enum' and the enum name.
625 if (FormatTok.Tok.is(tok::l_paren)) {
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000626 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000627 }
Manuel Klimek308232c2013-01-21 19:17:52 +0000628 if (FormatTok.Tok.is(tok::identifier))
629 nextToken();
630 }
631 if (FormatTok.Tok.is(tok::l_brace)) {
632 nextToken();
633 addUnwrappedLine();
634 ++Line->Level;
635 do {
636 switch (FormatTok.Tok.getKind()) {
Manuel Klimek308232c2013-01-21 19:17:52 +0000637 case tok::l_paren:
638 parseParens();
639 break;
640 case tok::r_brace:
641 addUnwrappedLine();
642 nextToken();
643 --Line->Level;
644 return;
645 case tok::comma:
646 nextToken();
647 addUnwrappedLine();
648 break;
649 default:
650 nextToken();
651 break;
652 }
653 } while (!eof());
654 }
655 // We fall through to parsing a structural element afterwards, so that in
656 // enum A {} n, m;
657 // "} n, m;" will end up in one unwrapped line.
Daniel Jasperbac016b2012-12-03 18:12:45 +0000658}
659
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000660void UnwrappedLineParser::parseRecord() {
Manuel Klimekde768542013-01-07 18:10:23 +0000661 nextToken();
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000662 if (FormatTok.Tok.is(tok::identifier) ||
663 FormatTok.Tok.is(tok::kw___attribute) ||
664 FormatTok.Tok.is(tok::kw___declspec)) {
665 nextToken();
666 // We can have macros or attributes in between 'class' and the class name.
667 if (FormatTok.Tok.is(tok::l_paren)) {
668 parseParens();
Manuel Klimekde768542013-01-07 18:10:23 +0000669 }
Manuel Klimekb8b1ce12013-02-06 15:57:54 +0000670 // The actual identifier can be a nested name specifier, and in macros
671 // it is often token-pasted.
Manuel Klimek7f5b0252013-01-21 10:17:14 +0000672 while (FormatTok.Tok.is(tok::identifier) ||
Daniel Jasperf9955d32013-03-20 12:37:50 +0000673 FormatTok.Tok.is(tok::coloncolon) || FormatTok.Tok.is(tok::hashhash))
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000674 nextToken();
675
Manuel Klimek3a3408c2013-01-21 13:58:54 +0000676 // Note that parsing away template declarations here leads to incorrectly
677 // accepting function declarations as record declarations.
678 // In general, we cannot solve this problem. Consider:
679 // class A<int> B() {}
680 // which can be a function definition or a class definition when B() is a
681 // macro. If we find enough real-world cases where this is a problem, we
682 // can parse for the 'template' keyword in the beginning of the statement,
683 // and thus rule out the record production in case there is no template
684 // (this would still leave us with an ambiguity between template function
685 // and class declarations).
686 if (FormatTok.Tok.is(tok::colon) || FormatTok.Tok.is(tok::less)) {
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000687 while (FormatTok.Tok.isNot(tok::l_brace)) {
688 if (FormatTok.Tok.is(tok::semi))
689 return;
690 nextToken();
691 }
692 }
693 }
694 if (FormatTok.Tok.is(tok::l_brace))
Manuel Klimek70b03f42013-01-23 09:32:48 +0000695 parseBlock(/*MustBeDeclaration=*/ true);
Manuel Klimek3a3408c2013-01-21 13:58:54 +0000696 // We fall through to parsing a structural element afterwards, so
697 // class A {} n, m;
698 // will end up in one unwrapped line.
Manuel Klimekde768542013-01-07 18:10:23 +0000699}
700
Nico Weber1abe6ea2013-01-09 21:15:03 +0000701void UnwrappedLineParser::parseObjCProtocolList() {
702 assert(FormatTok.Tok.is(tok::less) && "'<' expected.");
703 do
704 nextToken();
705 while (!eof() && FormatTok.Tok.isNot(tok::greater));
706 nextToken(); // Skip '>'.
707}
708
709void UnwrappedLineParser::parseObjCUntilAtEnd() {
710 do {
711 if (FormatTok.Tok.isObjCAtKeyword(tok::objc_end)) {
712 nextToken();
713 addUnwrappedLine();
714 break;
715 }
716 parseStructuralElement();
717 } while (!eof());
718}
719
Nico Weber50767d82013-01-09 23:25:37 +0000720void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
Nico Weber27d13672013-01-09 20:25:35 +0000721 nextToken();
Daniel Jasperf9955d32013-03-20 12:37:50 +0000722 nextToken(); // interface name
Nico Weber27d13672013-01-09 20:25:35 +0000723
724 // @interface can be followed by either a base class, or a category.
725 if (FormatTok.Tok.is(tok::colon)) {
726 nextToken();
Daniel Jasperf9955d32013-03-20 12:37:50 +0000727 nextToken(); // base class name
Nico Weber27d13672013-01-09 20:25:35 +0000728 } else if (FormatTok.Tok.is(tok::l_paren))
729 // Skip category, if present.
730 parseParens();
731
Nico Weber1abe6ea2013-01-09 21:15:03 +0000732 if (FormatTok.Tok.is(tok::less))
733 parseObjCProtocolList();
Nico Weber27d13672013-01-09 20:25:35 +0000734
735 // If instance variables are present, keep the '{' on the first line too.
736 if (FormatTok.Tok.is(tok::l_brace))
Manuel Klimek70b03f42013-01-23 09:32:48 +0000737 parseBlock(/*MustBeDeclaration=*/ true);
Nico Weber27d13672013-01-09 20:25:35 +0000738
739 // With instance variables, this puts '}' on its own line. Without instance
740 // variables, this ends the @interface line.
741 addUnwrappedLine();
742
Nico Weber1abe6ea2013-01-09 21:15:03 +0000743 parseObjCUntilAtEnd();
744}
Nico Weber27d13672013-01-09 20:25:35 +0000745
Nico Weber1abe6ea2013-01-09 21:15:03 +0000746void UnwrappedLineParser::parseObjCProtocol() {
747 nextToken();
Daniel Jasperf9955d32013-03-20 12:37:50 +0000748 nextToken(); // protocol name
Nico Weber1abe6ea2013-01-09 21:15:03 +0000749
750 if (FormatTok.Tok.is(tok::less))
751 parseObjCProtocolList();
752
753 // Check for protocol declaration.
754 if (FormatTok.Tok.is(tok::semi)) {
755 nextToken();
756 return addUnwrappedLine();
757 }
758
759 addUnwrappedLine();
760 parseObjCUntilAtEnd();
Nico Weber27d13672013-01-09 20:25:35 +0000761}
762
Daniel Jasperbac016b2012-12-03 18:12:45 +0000763void UnwrappedLineParser::addUnwrappedLine() {
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000764 if (Line->Tokens.empty())
Daniel Jasper26f7e782013-01-08 14:56:18 +0000765 return;
Manuel Klimek8fa37992013-01-16 12:31:12 +0000766 DEBUG({
Manuel Klimeka28fc062013-02-11 12:33:24 +0000767 llvm::dbgs() << "Line(" << Line->Level << ")"
768 << (Line->InPPDirective ? " MACRO" : "") << ": ";
Manuel Klimek8fa37992013-01-16 12:31:12 +0000769 for (std::list<FormatToken>::iterator I = Line->Tokens.begin(),
770 E = Line->Tokens.end();
771 I != E; ++I) {
772 llvm::dbgs() << I->Tok.getName() << " ";
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000773
Manuel Klimek8fa37992013-01-16 12:31:12 +0000774 }
775 llvm::dbgs() << "\n";
776 });
Manuel Klimek525fe162013-01-18 14:04:34 +0000777 CurrentLines->push_back(*Line);
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000778 Line->Tokens.clear();
Manuel Klimek525fe162013-01-18 14:04:34 +0000779 if (CurrentLines == &Lines && !PreprocessorDirectives.empty()) {
Daniel Jasper516fb312013-03-01 18:11:39 +0000780 for (std::vector<UnwrappedLine>::iterator
781 I = PreprocessorDirectives.begin(),
782 E = PreprocessorDirectives.end();
Manuel Klimek525fe162013-01-18 14:04:34 +0000783 I != E; ++I) {
784 CurrentLines->push_back(*I);
785 }
786 PreprocessorDirectives.clear();
787 }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000788}
789
Daniel Jasperf9955d32013-03-20 12:37:50 +0000790bool UnwrappedLineParser::eof() const { return FormatTok.Tok.is(tok::eof); }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000791
Manuel Klimek86721d22013-01-22 16:31:55 +0000792void UnwrappedLineParser::flushComments(bool NewlineBeforeNext) {
793 bool JustComments = Line->Tokens.empty();
794 for (SmallVectorImpl<FormatToken>::const_iterator
795 I = CommentsBeforeNextToken.begin(),
796 E = CommentsBeforeNextToken.end();
797 I != E; ++I) {
Manuel Klimekb3507cd2013-02-06 16:40:56 +0000798 if (I->NewlinesBefore && JustComments) {
Manuel Klimek86721d22013-01-22 16:31:55 +0000799 addUnwrappedLine();
800 }
801 pushToken(*I);
802 }
803 if (NewlineBeforeNext && JustComments) {
804 addUnwrappedLine();
805 }
806 CommentsBeforeNextToken.clear();
807}
808
Daniel Jasperbac016b2012-12-03 18:12:45 +0000809void UnwrappedLineParser::nextToken() {
810 if (eof())
811 return;
Manuel Klimekb3507cd2013-02-06 16:40:56 +0000812 flushComments(FormatTok.NewlinesBefore > 0);
Manuel Klimek86721d22013-01-22 16:31:55 +0000813 pushToken(FormatTok);
Manuel Klimekd4397b92013-01-04 23:34:14 +0000814 readToken();
815}
816
817void UnwrappedLineParser::readToken() {
Manuel Klimek86721d22013-01-22 16:31:55 +0000818 bool CommentsInCurrentLine = true;
819 do {
820 FormatTok = Tokens->getNextToken();
821 while (!Line->InPPDirective && FormatTok.Tok.is(tok::hash) &&
822 ((FormatTok.NewlinesBefore > 0 && FormatTok.HasUnescapedNewline) ||
823 FormatTok.IsFirst)) {
824 // If there is an unfinished unwrapped line, we flush the preprocessor
825 // directives only after that unwrapped line was finished later.
Daniel Jasperf9955d32013-03-20 12:37:50 +0000826 bool SwitchToPreprocessorLines =
827 !Line->Tokens.empty() && CurrentLines == &Lines;
Manuel Klimek86721d22013-01-22 16:31:55 +0000828 ScopedLineState BlockState(*this, SwitchToPreprocessorLines);
829 parsePPDirective();
830 }
831 if (!FormatTok.Tok.is(tok::comment))
832 return;
Manuel Klimekb3507cd2013-02-06 16:40:56 +0000833 if (FormatTok.NewlinesBefore > 0 || FormatTok.IsFirst) {
Manuel Klimek86721d22013-01-22 16:31:55 +0000834 CommentsInCurrentLine = false;
835 }
836 if (CommentsInCurrentLine) {
837 pushToken(FormatTok);
838 } else {
839 CommentsBeforeNextToken.push_back(FormatTok);
840 }
841 } while (!eof());
842}
843
844void UnwrappedLineParser::pushToken(const FormatToken &Tok) {
845 Line->Tokens.push_back(Tok);
846 if (MustBreakBeforeNextToken) {
847 Line->Tokens.back().MustBreakBefore = true;
848 MustBreakBeforeNextToken = false;
Manuel Klimekd4397b92013-01-04 23:34:14 +0000849 }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000850}
851
Daniel Jaspercd162382013-01-07 13:26:07 +0000852} // end namespace format
853} // end namespace clang