blob: c21fa0d74e5c50da3ea92c0ad0964a4bff3780a3 [file] [log] [blame]
Daniel Jasperbac016b2012-12-03 18:12:45 +00001//===--- UnwrappedLineParser.cpp - Format C++ code ------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file
11/// \brief This file contains the implementation of the UnwrappedLineParser,
12/// which turns a stream of tokens into UnwrappedLines.
13///
14/// This is EXPERIMENTAL code under heavy development. It is not in a state yet,
15/// where it can be used to format real code.
16///
17//===----------------------------------------------------------------------===//
18
Manuel Klimek8fa37992013-01-16 12:31:12 +000019#define DEBUG_TYPE "format-parser"
Daniel Jasperbac016b2012-12-03 18:12:45 +000020
Chandler Carruthb1ba0ef2013-01-19 08:09:44 +000021#include "UnwrappedLineParser.h"
Manuel Klimek8fa37992013-01-16 12:31:12 +000022#include "clang/Basic/Diagnostic.h"
23#include "llvm/Support/Debug.h"
Manuel Klimek8fa37992013-01-16 12:31:12 +000024
25// Uncomment to get debug output from tests:
26// #define DEBUG_WITH_TYPE(T, X) do { X; } while(0)
Manuel Klimek4c60fc62013-01-10 10:05:08 +000027
Daniel Jasperbac016b2012-12-03 18:12:45 +000028namespace clang {
29namespace format {
30
Manuel Klimek70b03f42013-01-23 09:32:48 +000031class ScopedDeclarationState {
32public:
33 ScopedDeclarationState(UnwrappedLine &Line, std::vector<bool> &Stack,
34 bool MustBeDeclaration)
35 : Line(Line), Stack(Stack) {
Manuel Klimek70b03f42013-01-23 09:32:48 +000036 Line.MustBeDeclaration = MustBeDeclaration;
Manuel Klimek836b58f2013-01-23 11:03:04 +000037 Stack.push_back(MustBeDeclaration);
Manuel Klimek70b03f42013-01-23 09:32:48 +000038 }
39 ~ScopedDeclarationState() {
Manuel Klimek70b03f42013-01-23 09:32:48 +000040 Stack.pop_back();
Manuel Klimek836b58f2013-01-23 11:03:04 +000041 Line.MustBeDeclaration = Stack.back();
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
Manuel Klimek70b03f42013-01-23 09:32:48 +0000191bool UnwrappedLineParser::parseBlock(bool MustBeDeclaration, 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;
200 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
Manuel Klimekde768542013-01-07 18:10:23 +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) {
218 addUnwrappedLine();
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();
240 if (FormatTok.Tok.getKind() == tok::l_paren) {
241 parseParens();
242 }
243 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000244 Line->Level = 1;
Manuel Klimekc3d0c822013-01-07 09:34:28 +0000245
246 // Errors during a preprocessor directive can only affect the layout of the
247 // preprocessor directive, and thus we ignore them. An alternative approach
248 // would be to use the same approach we use on the file level (no
249 // re-indentation if there was a structural error) within the macro
250 // definition.
Manuel Klimekd4397b92013-01-04 23:34:14 +0000251 parseFile();
252}
253
254void UnwrappedLineParser::parsePPUnknown() {
Manuel Klimeka080a182013-01-02 16:30:12 +0000255 do {
Manuel Klimeka080a182013-01-02 16:30:12 +0000256 nextToken();
257 } while (!eof());
258 addUnwrappedLine();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000259}
260
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000261void UnwrappedLineParser::parseStructuralElement() {
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000262 assert(!FormatTok.Tok.is(tok::l_brace));
Dmitri Gribenko1f94f2b2012-12-30 21:27:25 +0000263 int TokenNumber = 0;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000264 switch (FormatTok.Tok.getKind()) {
Nico Weber6092d4e2013-01-07 19:05:19 +0000265 case tok::at:
266 nextToken();
267 switch (FormatTok.Tok.getObjCKeywordID()) {
268 case tok::objc_public:
269 case tok::objc_protected:
270 case tok::objc_package:
271 case tok::objc_private:
272 return parseAccessSpecifier();
Nico Weber27d13672013-01-09 20:25:35 +0000273 case tok::objc_interface:
Nico Weber50767d82013-01-09 23:25:37 +0000274 case tok::objc_implementation:
275 return parseObjCInterfaceOrImplementation();
Nico Weber1abe6ea2013-01-09 21:15:03 +0000276 case tok::objc_protocol:
277 return parseObjCProtocol();
Nico Weber049c4472013-01-09 21:42:32 +0000278 case tok::objc_end:
279 return; // Handled by the caller.
Nico Weberb530fa32013-01-10 00:25:19 +0000280 case tok::objc_optional:
281 case tok::objc_required:
282 nextToken();
283 addUnwrappedLine();
284 return;
Nico Weber6092d4e2013-01-07 19:05:19 +0000285 default:
286 break;
287 }
288 break;
Alexander Kornienko15757312012-12-06 18:03:27 +0000289 case tok::kw_namespace:
290 parseNamespace();
291 return;
Dmitri Gribenko1f94f2b2012-12-30 21:27:25 +0000292 case tok::kw_inline:
293 nextToken();
294 TokenNumber++;
295 if (FormatTok.Tok.is(tok::kw_namespace)) {
296 parseNamespace();
297 return;
298 }
299 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000300 case tok::kw_public:
301 case tok::kw_protected:
302 case tok::kw_private:
Daniel Jasperbac016b2012-12-03 18:12:45 +0000303 parseAccessSpecifier();
304 return;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000305 case tok::kw_if:
306 parseIfThenElse();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000307 return;
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000308 case tok::kw_for:
309 case tok::kw_while:
310 parseForOrWhileLoop();
311 return;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000312 case tok::kw_do:
313 parseDoWhile();
314 return;
315 case tok::kw_switch:
316 parseSwitch();
317 return;
318 case tok::kw_default:
319 nextToken();
320 parseLabel();
321 return;
322 case tok::kw_case:
323 parseCaseLabel();
324 return;
Manuel Klimekc44ee892013-01-21 10:07:49 +0000325 case tok::kw_return:
326 parseReturn();
327 return;
Manuel Klimekd19dc2d2013-01-21 14:32:05 +0000328 case tok::kw_extern:
329 nextToken();
330 if (FormatTok.Tok.is(tok::string_literal)) {
331 nextToken();
332 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000333 parseBlock(/*MustBeDeclaration=*/ true, 0);
Manuel Klimekd19dc2d2013-01-21 14:32:05 +0000334 addUnwrappedLine();
335 return;
336 }
337 }
338 // In all other cases, parse the declaration.
339 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000340 default:
341 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000342 }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000343 do {
344 ++TokenNumber;
345 switch (FormatTok.Tok.getKind()) {
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000346 case tok::kw_enum:
347 parseEnum();
Manuel Klimek308232c2013-01-21 19:17:52 +0000348 break;
Alexander Kornienkod8818752013-01-16 11:43:46 +0000349 case tok::kw_struct:
350 case tok::kw_union:
Manuel Klimekde768542013-01-07 18:10:23 +0000351 case tok::kw_class:
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000352 parseRecord();
353 // A record declaration or definition is always the start of a structural
354 // element.
355 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000356 case tok::semi:
357 nextToken();
358 addUnwrappedLine();
359 return;
Alexander Kornienkod8818752013-01-16 11:43:46 +0000360 case tok::r_brace:
361 addUnwrappedLine();
362 return;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000363 case tok::l_paren:
364 parseParens();
365 break;
366 case tok::l_brace:
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000367 // A block outside of parentheses must be the last part of a
368 // structural element.
369 // FIXME: Figure out cases where this is not true, and add projections for
370 // them (the one we know is missing are lambdas).
Manuel Klimek70b03f42013-01-23 09:32:48 +0000371 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000372 addUnwrappedLine();
373 return;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000374 case tok::identifier:
Daniel Jasperbac016b2012-12-03 18:12:45 +0000375 nextToken();
376 if (TokenNumber == 1 && FormatTok.Tok.is(tok::colon)) {
377 parseLabel();
378 return;
379 }
380 break;
Daniel Jasper05b1ac82012-12-17 11:29:41 +0000381 case tok::equal:
382 nextToken();
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000383 if (FormatTok.Tok.is(tok::l_brace)) {
384 parseBracedList();
385 }
Daniel Jasper05b1ac82012-12-17 11:29:41 +0000386 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000387 default:
388 nextToken();
389 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000390 }
391 } while (!eof());
392}
393
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000394void UnwrappedLineParser::parseBracedList() {
395 nextToken();
396
397 do {
398 switch (FormatTok.Tok.getKind()) {
399 case tok::l_brace:
400 parseBracedList();
401 break;
402 case tok::r_brace:
403 nextToken();
404 return;
405 default:
406 nextToken();
407 break;
408 }
409 } while (!eof());
410}
411
Manuel Klimekc44ee892013-01-21 10:07:49 +0000412void UnwrappedLineParser::parseReturn() {
413 nextToken();
414
415 do {
416 switch (FormatTok.Tok.getKind()) {
417 case tok::l_brace:
418 parseBracedList();
419 break;
420 case tok::l_paren:
421 parseParens();
422 break;
423 case tok::r_brace:
424 // Assume missing ';'.
425 addUnwrappedLine();
426 return;
427 case tok::semi:
428 nextToken();
429 addUnwrappedLine();
430 return;
431 default:
432 nextToken();
433 break;
434 }
435 } while (!eof());
436}
437
Daniel Jasperbac016b2012-12-03 18:12:45 +0000438void UnwrappedLineParser::parseParens() {
439 assert(FormatTok.Tok.is(tok::l_paren) && "'(' expected.");
440 nextToken();
441 do {
442 switch (FormatTok.Tok.getKind()) {
443 case tok::l_paren:
444 parseParens();
445 break;
446 case tok::r_paren:
447 nextToken();
448 return;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000449 case tok::l_brace:
450 {
451 nextToken();
452 ScopedLineState LineState(*this);
Manuel Klimek70b03f42013-01-23 09:32:48 +0000453 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
454 /*MustBeDeclaration=*/ false);
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000455 Line->Level += 1;
Manuel Klimek70b03f42013-01-23 09:32:48 +0000456 parseLevel(/*HasOpeningBrace=*/ true);
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000457 Line->Level -= 1;
458 }
459 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000460 default:
461 nextToken();
462 break;
463 }
464 } while (!eof());
465}
466
467void UnwrappedLineParser::parseIfThenElse() {
468 assert(FormatTok.Tok.is(tok::kw_if) && "'if' expected");
469 nextToken();
Manuel Klimekd4658432013-01-11 18:28:36 +0000470 if (FormatTok.Tok.is(tok::l_paren))
471 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000472 bool NeedsUnwrappedLine = false;
473 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000474 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000475 NeedsUnwrappedLine = true;
476 } else {
477 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000478 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000479 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000480 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000481 }
482 if (FormatTok.Tok.is(tok::kw_else)) {
483 nextToken();
484 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000485 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000486 addUnwrappedLine();
487 } else if (FormatTok.Tok.is(tok::kw_if)) {
488 parseIfThenElse();
489 } else {
490 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000491 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000492 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000493 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000494 }
495 } else if (NeedsUnwrappedLine) {
496 addUnwrappedLine();
497 }
498}
499
Alexander Kornienko15757312012-12-06 18:03:27 +0000500void UnwrappedLineParser::parseNamespace() {
501 assert(FormatTok.Tok.is(tok::kw_namespace) && "'namespace' expected");
502 nextToken();
503 if (FormatTok.Tok.is(tok::identifier))
504 nextToken();
505 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000506 parseBlock(/*MustBeDeclaration=*/ true, 0);
Alexander Kornienko15757312012-12-06 18:03:27 +0000507 addUnwrappedLine();
508 }
509 // FIXME: Add error handling.
510}
511
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000512void UnwrappedLineParser::parseForOrWhileLoop() {
513 assert((FormatTok.Tok.is(tok::kw_for) || FormatTok.Tok.is(tok::kw_while)) &&
514 "'for' or 'while' expected");
515 nextToken();
Manuel Klimek6eca03f2013-01-11 19:23:05 +0000516 if (FormatTok.Tok.is(tok::l_paren))
517 parseParens();
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000518 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000519 parseBlock(/*MustBeDeclaration=*/ false);
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000520 addUnwrappedLine();
521 } else {
522 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000523 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000524 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000525 --Line->Level;
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000526 }
527}
528
Daniel Jasperbac016b2012-12-03 18:12:45 +0000529void UnwrappedLineParser::parseDoWhile() {
530 assert(FormatTok.Tok.is(tok::kw_do) && "'do' expected");
531 nextToken();
532 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000533 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000534 } else {
535 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000536 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000537 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000538 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000539 }
540
Alexander Kornienko393b0082012-12-04 15:40:36 +0000541 // FIXME: Add error handling.
542 if (!FormatTok.Tok.is(tok::kw_while)) {
543 addUnwrappedLine();
544 return;
545 }
546
Daniel Jasperbac016b2012-12-03 18:12:45 +0000547 nextToken();
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000548 parseStructuralElement();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000549}
550
551void UnwrappedLineParser::parseLabel() {
552 // FIXME: remove all asserts.
553 assert(FormatTok.Tok.is(tok::colon) && "':' expected");
554 nextToken();
Manuel Klimek526ed112013-01-09 15:25:02 +0000555 unsigned OldLineLevel = Line->Level;
556 if (Line->Level > 0)
557 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000558 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000559 parseBlock(/*MustBeDeclaration=*/ false);
Nico Weber94fb7292013-01-18 05:50:57 +0000560 if (FormatTok.Tok.is(tok::kw_break))
561 parseStructuralElement(); // "break;" after "}" goes on the same line.
Daniel Jasperbac016b2012-12-03 18:12:45 +0000562 }
563 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000564 Line->Level = OldLineLevel;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000565}
566
567void UnwrappedLineParser::parseCaseLabel() {
568 assert(FormatTok.Tok.is(tok::kw_case) && "'case' expected");
569 // FIXME: fix handling of complex expressions here.
570 do {
571 nextToken();
572 } while (!eof() && !FormatTok.Tok.is(tok::colon));
573 parseLabel();
574}
575
576void UnwrappedLineParser::parseSwitch() {
577 assert(FormatTok.Tok.is(tok::kw_switch) && "'switch' expected");
578 nextToken();
Manuel Klimek6eca03f2013-01-11 19:23:05 +0000579 if (FormatTok.Tok.is(tok::l_paren))
580 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000581 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000582 parseBlock(/*MustBeDeclaration=*/ false, Style.IndentCaseLabels ? 2 : 1);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000583 addUnwrappedLine();
584 } else {
585 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000586 Line->Level += (Style.IndentCaseLabels ? 2 : 1);
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000587 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000588 Line->Level -= (Style.IndentCaseLabels ? 2 : 1);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000589 }
590}
591
592void UnwrappedLineParser::parseAccessSpecifier() {
593 nextToken();
Alexander Kornienko56e49c52012-12-10 16:34:48 +0000594 // Otherwise, we don't know what it is, and we'd better keep the next token.
595 if (FormatTok.Tok.is(tok::colon))
596 nextToken();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000597 addUnwrappedLine();
598}
599
600void UnwrappedLineParser::parseEnum() {
Manuel Klimek308232c2013-01-21 19:17:52 +0000601 nextToken();
602 if (FormatTok.Tok.is(tok::identifier) ||
603 FormatTok.Tok.is(tok::kw___attribute) ||
604 FormatTok.Tok.is(tok::kw___declspec)) {
605 nextToken();
606 // We can have macros or attributes in between 'enum' and the enum name.
607 if (FormatTok.Tok.is(tok::l_paren)) {
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000608 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000609 }
Manuel Klimek308232c2013-01-21 19:17:52 +0000610 if (FormatTok.Tok.is(tok::identifier))
611 nextToken();
612 }
613 if (FormatTok.Tok.is(tok::l_brace)) {
614 nextToken();
615 addUnwrappedLine();
616 ++Line->Level;
617 do {
618 switch (FormatTok.Tok.getKind()) {
Manuel Klimek308232c2013-01-21 19:17:52 +0000619 case tok::l_paren:
620 parseParens();
621 break;
622 case tok::r_brace:
623 addUnwrappedLine();
624 nextToken();
625 --Line->Level;
626 return;
627 case tok::comma:
628 nextToken();
629 addUnwrappedLine();
630 break;
631 default:
632 nextToken();
633 break;
634 }
635 } while (!eof());
636 }
637 // We fall through to parsing a structural element afterwards, so that in
638 // enum A {} n, m;
639 // "} n, m;" will end up in one unwrapped line.
Daniel Jasperbac016b2012-12-03 18:12:45 +0000640}
641
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000642void UnwrappedLineParser::parseRecord() {
Manuel Klimekde768542013-01-07 18:10:23 +0000643 nextToken();
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000644 if (FormatTok.Tok.is(tok::identifier) ||
645 FormatTok.Tok.is(tok::kw___attribute) ||
646 FormatTok.Tok.is(tok::kw___declspec)) {
647 nextToken();
648 // We can have macros or attributes in between 'class' and the class name.
649 if (FormatTok.Tok.is(tok::l_paren)) {
650 parseParens();
Manuel Klimekde768542013-01-07 18:10:23 +0000651 }
Manuel Klimek7f5b0252013-01-21 10:17:14 +0000652 // The actual identifier can be a nested name specifier.
653 while (FormatTok.Tok.is(tok::identifier) ||
654 FormatTok.Tok.is(tok::coloncolon))
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000655 nextToken();
656
Manuel Klimek3a3408c2013-01-21 13:58:54 +0000657 // Note that parsing away template declarations here leads to incorrectly
658 // accepting function declarations as record declarations.
659 // In general, we cannot solve this problem. Consider:
660 // class A<int> B() {}
661 // which can be a function definition or a class definition when B() is a
662 // macro. If we find enough real-world cases where this is a problem, we
663 // can parse for the 'template' keyword in the beginning of the statement,
664 // and thus rule out the record production in case there is no template
665 // (this would still leave us with an ambiguity between template function
666 // and class declarations).
667 if (FormatTok.Tok.is(tok::colon) || FormatTok.Tok.is(tok::less)) {
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000668 while (FormatTok.Tok.isNot(tok::l_brace)) {
669 if (FormatTok.Tok.is(tok::semi))
670 return;
671 nextToken();
672 }
673 }
674 }
675 if (FormatTok.Tok.is(tok::l_brace))
Manuel Klimek70b03f42013-01-23 09:32:48 +0000676 parseBlock(/*MustBeDeclaration=*/ true);
Manuel Klimek3a3408c2013-01-21 13:58:54 +0000677 // We fall through to parsing a structural element afterwards, so
678 // class A {} n, m;
679 // will end up in one unwrapped line.
Manuel Klimekde768542013-01-07 18:10:23 +0000680}
681
Nico Weber1abe6ea2013-01-09 21:15:03 +0000682void UnwrappedLineParser::parseObjCProtocolList() {
683 assert(FormatTok.Tok.is(tok::less) && "'<' expected.");
684 do
685 nextToken();
686 while (!eof() && FormatTok.Tok.isNot(tok::greater));
687 nextToken(); // Skip '>'.
688}
689
690void UnwrappedLineParser::parseObjCUntilAtEnd() {
691 do {
692 if (FormatTok.Tok.isObjCAtKeyword(tok::objc_end)) {
693 nextToken();
694 addUnwrappedLine();
695 break;
696 }
697 parseStructuralElement();
698 } while (!eof());
699}
700
Nico Weber50767d82013-01-09 23:25:37 +0000701void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
Nico Weber27d13672013-01-09 20:25:35 +0000702 nextToken();
703 nextToken(); // interface name
704
705 // @interface can be followed by either a base class, or a category.
706 if (FormatTok.Tok.is(tok::colon)) {
707 nextToken();
708 nextToken(); // base class name
709 } else if (FormatTok.Tok.is(tok::l_paren))
710 // Skip category, if present.
711 parseParens();
712
Nico Weber1abe6ea2013-01-09 21:15:03 +0000713 if (FormatTok.Tok.is(tok::less))
714 parseObjCProtocolList();
Nico Weber27d13672013-01-09 20:25:35 +0000715
716 // If instance variables are present, keep the '{' on the first line too.
717 if (FormatTok.Tok.is(tok::l_brace))
Manuel Klimek70b03f42013-01-23 09:32:48 +0000718 parseBlock(/*MustBeDeclaration=*/ true);
Nico Weber27d13672013-01-09 20:25:35 +0000719
720 // With instance variables, this puts '}' on its own line. Without instance
721 // variables, this ends the @interface line.
722 addUnwrappedLine();
723
Nico Weber1abe6ea2013-01-09 21:15:03 +0000724 parseObjCUntilAtEnd();
725}
Nico Weber27d13672013-01-09 20:25:35 +0000726
Nico Weber1abe6ea2013-01-09 21:15:03 +0000727void UnwrappedLineParser::parseObjCProtocol() {
728 nextToken();
729 nextToken(); // protocol name
730
731 if (FormatTok.Tok.is(tok::less))
732 parseObjCProtocolList();
733
734 // Check for protocol declaration.
735 if (FormatTok.Tok.is(tok::semi)) {
736 nextToken();
737 return addUnwrappedLine();
738 }
739
740 addUnwrappedLine();
741 parseObjCUntilAtEnd();
Nico Weber27d13672013-01-09 20:25:35 +0000742}
743
Daniel Jasperbac016b2012-12-03 18:12:45 +0000744void UnwrappedLineParser::addUnwrappedLine() {
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000745 if (Line->Tokens.empty())
Daniel Jasper26f7e782013-01-08 14:56:18 +0000746 return;
Manuel Klimek8fa37992013-01-16 12:31:12 +0000747 DEBUG({
Manuel Klimek86721d22013-01-22 16:31:55 +0000748 llvm::dbgs() << "Line(" << Line->Level << "): ";
Manuel Klimek8fa37992013-01-16 12:31:12 +0000749 for (std::list<FormatToken>::iterator I = Line->Tokens.begin(),
750 E = Line->Tokens.end();
751 I != E; ++I) {
752 llvm::dbgs() << I->Tok.getName() << " ";
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000753
Manuel Klimek8fa37992013-01-16 12:31:12 +0000754 }
755 llvm::dbgs() << "\n";
756 });
Manuel Klimek525fe162013-01-18 14:04:34 +0000757 CurrentLines->push_back(*Line);
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000758 Line->Tokens.clear();
Manuel Klimek525fe162013-01-18 14:04:34 +0000759 if (CurrentLines == &Lines && !PreprocessorDirectives.empty()) {
760 for (std::vector<UnwrappedLine>::iterator I = PreprocessorDirectives
761 .begin(), E = PreprocessorDirectives.end();
762 I != E; ++I) {
763 CurrentLines->push_back(*I);
764 }
765 PreprocessorDirectives.clear();
766 }
767
Daniel Jasperbac016b2012-12-03 18:12:45 +0000768}
769
770bool UnwrappedLineParser::eof() const {
771 return FormatTok.Tok.is(tok::eof);
772}
773
Manuel Klimek86721d22013-01-22 16:31:55 +0000774void UnwrappedLineParser::flushComments(bool NewlineBeforeNext) {
775 bool JustComments = Line->Tokens.empty();
776 for (SmallVectorImpl<FormatToken>::const_iterator
777 I = CommentsBeforeNextToken.begin(),
778 E = CommentsBeforeNextToken.end();
779 I != E; ++I) {
780 if (I->HasUnescapedNewline && JustComments) {
781 addUnwrappedLine();
782 }
783 pushToken(*I);
784 }
785 if (NewlineBeforeNext && JustComments) {
786 addUnwrappedLine();
787 }
788 CommentsBeforeNextToken.clear();
789}
790
Daniel Jasperbac016b2012-12-03 18:12:45 +0000791void UnwrappedLineParser::nextToken() {
792 if (eof())
793 return;
Manuel Klimek86721d22013-01-22 16:31:55 +0000794 flushComments(FormatTok.HasUnescapedNewline);
795 pushToken(FormatTok);
Manuel Klimekd4397b92013-01-04 23:34:14 +0000796 readToken();
797}
798
799void UnwrappedLineParser::readToken() {
Manuel Klimek86721d22013-01-22 16:31:55 +0000800 bool CommentsInCurrentLine = true;
801 do {
802 FormatTok = Tokens->getNextToken();
803 while (!Line->InPPDirective && FormatTok.Tok.is(tok::hash) &&
804 ((FormatTok.NewlinesBefore > 0 && FormatTok.HasUnescapedNewline) ||
805 FormatTok.IsFirst)) {
806 // If there is an unfinished unwrapped line, we flush the preprocessor
807 // directives only after that unwrapped line was finished later.
808 bool SwitchToPreprocessorLines = !Line->Tokens.empty() &&
809 CurrentLines == &Lines;
810 ScopedLineState BlockState(*this, SwitchToPreprocessorLines);
811 parsePPDirective();
812 }
813 if (!FormatTok.Tok.is(tok::comment))
814 return;
815 if (FormatTok.HasUnescapedNewline || FormatTok.IsFirst) {
816 CommentsInCurrentLine = false;
817 }
818 if (CommentsInCurrentLine) {
819 pushToken(FormatTok);
820 } else {
821 CommentsBeforeNextToken.push_back(FormatTok);
822 }
823 } while (!eof());
824}
825
826void UnwrappedLineParser::pushToken(const FormatToken &Tok) {
827 Line->Tokens.push_back(Tok);
828 if (MustBreakBeforeNextToken) {
829 Line->Tokens.back().MustBreakBefore = true;
830 MustBreakBeforeNextToken = false;
Manuel Klimekd4397b92013-01-04 23:34:14 +0000831 }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000832}
833
Daniel Jaspercd162382013-01-07 13:26:07 +0000834} // end namespace format
835} // end namespace clang