blob: 36307e04873e58e96d00cad4c3762ae62f30d622 [file] [log] [blame]
Daniel Jasperf7935112012-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 Jasperf7935112012-12-03 18:12:45 +000014//===----------------------------------------------------------------------===//
15
Manuel Klimekab3dc002013-01-16 12:31:12 +000016#define DEBUG_TYPE "format-parser"
Daniel Jasperf7935112012-12-03 18:12:45 +000017
Chandler Carruth4b417452013-01-19 08:09:44 +000018#include "UnwrappedLineParser.h"
Manuel Klimekab3dc002013-01-16 12:31:12 +000019#include "clang/Basic/Diagnostic.h"
20#include "llvm/Support/Debug.h"
Manuel Klimekab3dc002013-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 Klimekfba4bb12013-01-10 10:05:08 +000024
Daniel Jasperf7935112012-12-03 18:12:45 +000025namespace clang {
26namespace format {
27
Manuel Klimek0a3a3c92013-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 Klimek0a3a3c92013-01-23 09:32:48 +000033 Line.MustBeDeclaration = MustBeDeclaration;
Manuel Klimek39080572013-01-23 11:03:04 +000034 Stack.push_back(MustBeDeclaration);
Manuel Klimek0a3a3c92013-01-23 09:32:48 +000035 }
36 ~ScopedDeclarationState() {
Manuel Klimek0a3a3c92013-01-23 09:32:48 +000037 Stack.pop_back();
Manuel Klimekc1237a82013-01-23 14:08:21 +000038 if (!Stack.empty())
39 Line.MustBeDeclaration = Stack.back();
40 else
41 Line.MustBeDeclaration = true;
Manuel Klimek0a3a3c92013-01-23 09:32:48 +000042 }
43private:
44 UnwrappedLine &Line;
45 std::vector<bool> &Stack;
46};
47
Manuel Klimek1abf7892013-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 Klimekef2cfb12013-01-05 22:14:16 +000053 PreviousLineLevel(Line.Level), PreviousTokenSource(TokenSource) {
Manuel Klimek1abf7892013-01-04 23:34:14 +000054 TokenSource = this;
Manuel Klimekef2cfb12013-01-05 22:14:16 +000055 Line.Level = 0;
Manuel Klimek1abf7892013-01-04 23:34:14 +000056 Line.InPPDirective = true;
57 }
58
59 ~ScopedMacroState() {
60 TokenSource = PreviousTokenSource;
61 ResetToken = Token;
62 Line.InPPDirective = false;
Manuel Klimekef2cfb12013-01-05 22:14:16 +000063 Line.Level = PreviousLineLevel;
Manuel Klimek1abf7892013-01-04 23:34:14 +000064 }
65
66 virtual FormatToken getNextToken() {
Manuel Klimek78725712013-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 Klimek1abf7892013-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 Klimekef2cfb12013-01-05 22:14:16 +000091 unsigned PreviousLineLevel;
Manuel Klimek1abf7892013-01-04 23:34:14 +000092 FormatTokenSource *PreviousTokenSource;
93
94 FormatToken Token;
95};
96
Manuel Klimek8e07a1b2013-01-10 11:52:21 +000097class ScopedLineState {
98public:
Manuel Klimekd3b92fa2013-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 Klimek8e07a1b2013-01-10 11:52:21 +0000104 PreBlockLine = Parser.Line.take();
Daniel Jasperdaffc0d2013-01-16 09:10:19 +0000105 Parser.Line.reset(new UnwrappedLine());
106 Parser.Line->Level = PreBlockLine->Level;
107 Parser.Line->InPPDirective = PreBlockLine->InPPDirective;
Manuel Klimek8e07a1b2013-01-10 11:52:21 +0000108 }
109
110 ~ScopedLineState() {
Daniel Jasperdaffc0d2013-01-16 09:10:19 +0000111 if (!Parser.Line->Tokens.empty()) {
Manuel Klimek8e07a1b2013-01-10 11:52:21 +0000112 Parser.addUnwrappedLine();
113 }
Daniel Jasperdaffc0d2013-01-16 09:10:19 +0000114 assert(Parser.Line->Tokens.empty());
Manuel Klimek8e07a1b2013-01-10 11:52:21 +0000115 Parser.Line.reset(PreBlockLine);
Manuel Klimek8e07a1b2013-01-10 11:52:21 +0000116 Parser.MustBreakBeforeNextToken = true;
Manuel Klimekd3b92fa2013-01-18 14:04:34 +0000117 if (SwitchToPreprocessorLines)
118 Parser.CurrentLines = &Parser.Lines;
Manuel Klimek8e07a1b2013-01-10 11:52:21 +0000119 }
120
121private:
122 UnwrappedLineParser &Parser;
Manuel Klimekd3b92fa2013-01-18 14:04:34 +0000123 const bool SwitchToPreprocessorLines;
Manuel Klimek8e07a1b2013-01-10 11:52:21 +0000124
125 UnwrappedLine *PreBlockLine;
Manuel Klimek8e07a1b2013-01-10 11:52:21 +0000126};
127
Alexander Kornienko5b7157a2013-01-10 15:05:09 +0000128UnwrappedLineParser::UnwrappedLineParser(
129 clang::DiagnosticsEngine &Diag, const FormatStyle &Style,
130 FormatTokenSource &Tokens, UnwrappedLineConsumer &Callback)
Manuel Klimekd3b92fa2013-01-18 14:04:34 +0000131 : Line(new UnwrappedLine), MustBreakBeforeNextToken(false),
132 CurrentLines(&Lines), Diag(Diag), Style(Style), Tokens(&Tokens),
133 Callback(Callback) {}
Daniel Jasperf7935112012-12-03 18:12:45 +0000134
Alexander Kornienko870f9eb2012-12-04 17:27:50 +0000135bool UnwrappedLineParser::parse() {
Manuel Klimekab3dc002013-01-16 12:31:12 +0000136 DEBUG(llvm::dbgs() << "----\n");
Manuel Klimek1abf7892013-01-04 23:34:14 +0000137 readToken();
Manuel Klimekd3b92fa2013-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 Klimek1abf7892013-01-04 23:34:14 +0000145}
146
147bool UnwrappedLineParser::parseFile() {
Manuel Klimek0a3a3c92013-01-23 09:32:48 +0000148 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
149 /*MustBeDeclaration=*/ true);
Manuel Klimek1058d982013-01-06 20:07:31 +0000150 bool Error = parseLevel(/*HasOpeningBrace=*/false);
Manuel Klimek1abf7892013-01-04 23:34:14 +0000151 // Make sure to format the remaining tokens.
Manuel Klimekf92f7bc2013-01-22 16:31:55 +0000152 flushComments(true);
Manuel Klimek1abf7892013-01-04 23:34:14 +0000153 addUnwrappedLine();
154 return Error;
Daniel Jasperf7935112012-12-03 18:12:45 +0000155}
156
Manuel Klimek1058d982013-01-06 20:07:31 +0000157bool UnwrappedLineParser::parseLevel(bool HasOpeningBrace) {
Alexander Kornienko870f9eb2012-12-04 17:27:50 +0000158 bool Error = false;
Daniel Jasperf7935112012-12-03 18:12:45 +0000159 do {
160 switch (FormatTok.Tok.getKind()) {
Daniel Jasperf7935112012-12-03 18:12:45 +0000161 case tok::comment:
Daniel Jaspere25509f2012-12-17 11:29:41 +0000162 nextToken();
163 addUnwrappedLine();
Daniel Jasperf7935112012-12-03 18:12:45 +0000164 break;
165 case tok::l_brace:
Manuel Klimek0a3a3c92013-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 Jasperf7935112012-12-03 18:12:45 +0000169 addUnwrappedLine();
170 break;
171 case tok::r_brace:
Manuel Klimek1058d982013-01-06 20:07:31 +0000172 if (HasOpeningBrace) {
173 return false;
174 } else {
Alexander Kornienko5b7157a2013-01-10 15:05:09 +0000175 Diag.Report(FormatTok.Tok.getLocation(),
176 Diag.getCustomDiagID(clang::DiagnosticsEngine::Error,
Alexander Kornienko2cc2d602013-01-11 16:03:45 +0000177 "unexpected '}'"));
Manuel Klimek1058d982013-01-06 20:07:31 +0000178 Error = true;
179 nextToken();
180 addUnwrappedLine();
181 }
182 break;
Daniel Jasperf7935112012-12-03 18:12:45 +0000183 default:
Manuel Klimek6b9eeba2013-01-07 14:56:16 +0000184 parseStructuralElement();
Daniel Jasperf7935112012-12-03 18:12:45 +0000185 break;
186 }
187 } while (!eof());
Alexander Kornienko870f9eb2012-12-04 17:27:50 +0000188 return Error;
Daniel Jasperf7935112012-12-03 18:12:45 +0000189}
190
Manuel Klimek0a3a3c92013-01-23 09:32:48 +0000191bool UnwrappedLineParser::parseBlock(bool MustBeDeclaration, unsigned AddLevels) {
Alexander Kornienkoecdc7502012-12-06 17:49:17 +0000192 assert(FormatTok.Tok.is(tok::l_brace) && "'{' expected");
Daniel Jasperf7935112012-12-03 18:12:45 +0000193 nextToken();
194
Manuel Klimeka4fe1c12013-01-21 16:42:44 +0000195 addUnwrappedLine();
Daniel Jasperf7935112012-12-03 18:12:45 +0000196
Manuel Klimek0a3a3c92013-01-23 09:32:48 +0000197 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
198 MustBeDeclaration);
Manuel Klimeka4fe1c12013-01-21 16:42:44 +0000199 Line->Level += AddLevels;
200 parseLevel(/*HasOpeningBrace=*/true);
Alexander Kornienko578fdd82012-12-06 18:03:27 +0000201
Manuel Klimekf92f7bc2013-01-22 16:31:55 +0000202 if (!FormatTok.Tok.is(tok::r_brace)) {
203 Line->Level -= AddLevels;
Manuel Klimeka4fe1c12013-01-21 16:42:44 +0000204 return true;
Manuel Klimekf92f7bc2013-01-22 16:31:55 +0000205 }
Alexander Kornienko0ea8e102012-12-04 15:40:36 +0000206
Manuel Klimek28cacc72013-01-07 18:10:23 +0000207 nextToken(); // Munch the closing brace.
Manuel Klimekf92f7bc2013-01-22 16:31:55 +0000208 Line->Level -= AddLevels;
Alexander Kornienko870f9eb2012-12-04 17:27:50 +0000209 return false;
Daniel Jasperf7935112012-12-03 18:12:45 +0000210}
211
212void UnwrappedLineParser::parsePPDirective() {
Manuel Klimeka71e5d82013-01-02 16:30:12 +0000213 assert(FormatTok.Tok.is(tok::hash) && "'#' expected");
Manuel Klimek52b15152013-01-09 15:25:02 +0000214 ScopedMacroState MacroState(*Line, Tokens, FormatTok);
Manuel Klimeka71e5d82013-01-02 16:30:12 +0000215 nextToken();
216
Manuel Klimeka71e5d82013-01-02 16:30:12 +0000217 if (FormatTok.Tok.getIdentifierInfo() == NULL) {
Manuel Klimek591b5802013-01-31 15:58:48 +0000218 parsePPUnknown();
Manuel Klimeka71e5d82013-01-02 16:30:12 +0000219 return;
Daniel Jasperf7935112012-12-03 18:12:45 +0000220 }
Manuel Klimeka71e5d82013-01-02 16:30:12 +0000221
Manuel Klimek1abf7892013-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 Klimekd053c5b2013-01-23 14:37:36 +0000240 if (FormatTok.Tok.getKind() == tok::l_paren &&
241 FormatTok.WhiteSpaceLength == 0) {
Manuel Klimek1abf7892013-01-04 23:34:14 +0000242 parseParens();
243 }
244 addUnwrappedLine();
Manuel Klimek52b15152013-01-09 15:25:02 +0000245 Line->Level = 1;
Manuel Klimek1b896292013-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 Klimek1abf7892013-01-04 23:34:14 +0000252 parseFile();
253}
254
255void UnwrappedLineParser::parsePPUnknown() {
Manuel Klimeka71e5d82013-01-02 16:30:12 +0000256 do {
Manuel Klimeka71e5d82013-01-02 16:30:12 +0000257 nextToken();
258 } while (!eof());
259 addUnwrappedLine();
Daniel Jasperf7935112012-12-03 18:12:45 +0000260}
261
Manuel Klimek6b9eeba2013-01-07 14:56:16 +0000262void UnwrappedLineParser::parseStructuralElement() {
Manuel Klimek8e07a1b2013-01-10 11:52:21 +0000263 assert(!FormatTok.Tok.is(tok::l_brace));
Dmitri Gribenko58d64e22012-12-30 21:27:25 +0000264 int TokenNumber = 0;
Alexander Kornienkob7076a22012-12-04 14:46:19 +0000265 switch (FormatTok.Tok.getKind()) {
Nico Weber04e9f1a2013-01-07 19:05:19 +0000266 case tok::at:
267 nextToken();
268 switch (FormatTok.Tok.getObjCKeywordID()) {
269 case tok::objc_public:
270 case tok::objc_protected:
271 case tok::objc_package:
272 case tok::objc_private:
273 return parseAccessSpecifier();
Nico Weber7eecf4b2013-01-09 20:25:35 +0000274 case tok::objc_interface:
Nico Weber2ce0ac52013-01-09 23:25:37 +0000275 case tok::objc_implementation:
276 return parseObjCInterfaceOrImplementation();
Nico Weber8696a8d2013-01-09 21:15:03 +0000277 case tok::objc_protocol:
278 return parseObjCProtocol();
Nico Weberd8ffe752013-01-09 21:42:32 +0000279 case tok::objc_end:
280 return; // Handled by the caller.
Nico Weber51306d22013-01-10 00:25:19 +0000281 case tok::objc_optional:
282 case tok::objc_required:
283 nextToken();
284 addUnwrappedLine();
285 return;
Nico Weber04e9f1a2013-01-07 19:05:19 +0000286 default:
287 break;
288 }
289 break;
Alexander Kornienko578fdd82012-12-06 18:03:27 +0000290 case tok::kw_namespace:
291 parseNamespace();
292 return;
Dmitri Gribenko58d64e22012-12-30 21:27:25 +0000293 case tok::kw_inline:
294 nextToken();
295 TokenNumber++;
296 if (FormatTok.Tok.is(tok::kw_namespace)) {
297 parseNamespace();
298 return;
299 }
300 break;
Alexander Kornienkob7076a22012-12-04 14:46:19 +0000301 case tok::kw_public:
302 case tok::kw_protected:
303 case tok::kw_private:
Daniel Jasperf7935112012-12-03 18:12:45 +0000304 parseAccessSpecifier();
305 return;
Alexander Kornienkob7076a22012-12-04 14:46:19 +0000306 case tok::kw_if:
307 parseIfThenElse();
Daniel Jasperf7935112012-12-03 18:12:45 +0000308 return;
Alexander Kornienko37d6c942012-12-05 15:06:06 +0000309 case tok::kw_for:
310 case tok::kw_while:
311 parseForOrWhileLoop();
312 return;
Alexander Kornienkob7076a22012-12-04 14:46:19 +0000313 case tok::kw_do:
314 parseDoWhile();
315 return;
316 case tok::kw_switch:
317 parseSwitch();
318 return;
319 case tok::kw_default:
320 nextToken();
321 parseLabel();
322 return;
323 case tok::kw_case:
324 parseCaseLabel();
325 return;
Manuel Klimek762dd182013-01-21 10:07:49 +0000326 case tok::kw_return:
327 parseReturn();
328 return;
Manuel Klimekae610d12013-01-21 14:32:05 +0000329 case tok::kw_extern:
330 nextToken();
331 if (FormatTok.Tok.is(tok::string_literal)) {
332 nextToken();
333 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek0a3a3c92013-01-23 09:32:48 +0000334 parseBlock(/*MustBeDeclaration=*/ true, 0);
Manuel Klimekae610d12013-01-21 14:32:05 +0000335 addUnwrappedLine();
336 return;
337 }
338 }
339 // In all other cases, parse the declaration.
340 break;
Alexander Kornienkob7076a22012-12-04 14:46:19 +0000341 default:
342 break;
Daniel Jasperf7935112012-12-03 18:12:45 +0000343 }
Daniel Jasperf7935112012-12-03 18:12:45 +0000344 do {
345 ++TokenNumber;
346 switch (FormatTok.Tok.getKind()) {
Alexander Kornienkob7076a22012-12-04 14:46:19 +0000347 case tok::kw_enum:
348 parseEnum();
Manuel Klimek2cec0192013-01-21 19:17:52 +0000349 break;
Alexander Kornienko1231e062013-01-16 11:43:46 +0000350 case tok::kw_struct:
351 case tok::kw_union:
Manuel Klimek28cacc72013-01-07 18:10:23 +0000352 case tok::kw_class:
Manuel Klimeke01bab52013-01-15 13:38:33 +0000353 parseRecord();
354 // A record declaration or definition is always the start of a structural
355 // element.
356 break;
Daniel Jasperf7935112012-12-03 18:12:45 +0000357 case tok::semi:
358 nextToken();
359 addUnwrappedLine();
360 return;
Alexander Kornienko1231e062013-01-16 11:43:46 +0000361 case tok::r_brace:
362 addUnwrappedLine();
363 return;
Daniel Jasperf7935112012-12-03 18:12:45 +0000364 case tok::l_paren:
365 parseParens();
366 break;
367 case tok::l_brace:
Manuel Klimek8e07a1b2013-01-10 11:52:21 +0000368 // A block outside of parentheses must be the last part of a
369 // structural element.
370 // FIXME: Figure out cases where this is not true, and add projections for
371 // them (the one we know is missing are lambdas).
Manuel Klimek0a3a3c92013-01-23 09:32:48 +0000372 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperf7935112012-12-03 18:12:45 +0000373 addUnwrappedLine();
374 return;
Alexander Kornienkob7076a22012-12-04 14:46:19 +0000375 case tok::identifier:
Daniel Jasperf7935112012-12-03 18:12:45 +0000376 nextToken();
377 if (TokenNumber == 1 && FormatTok.Tok.is(tok::colon)) {
378 parseLabel();
379 return;
380 }
381 break;
Daniel Jaspere25509f2012-12-17 11:29:41 +0000382 case tok::equal:
383 nextToken();
Manuel Klimek8e07a1b2013-01-10 11:52:21 +0000384 if (FormatTok.Tok.is(tok::l_brace)) {
385 parseBracedList();
386 }
Daniel Jaspere25509f2012-12-17 11:29:41 +0000387 break;
Alexander Kornienkob7076a22012-12-04 14:46:19 +0000388 default:
389 nextToken();
390 break;
Daniel Jasperf7935112012-12-03 18:12:45 +0000391 }
392 } while (!eof());
393}
394
Manuel Klimek8e07a1b2013-01-10 11:52:21 +0000395void UnwrappedLineParser::parseBracedList() {
396 nextToken();
397
398 do {
399 switch (FormatTok.Tok.getKind()) {
400 case tok::l_brace:
401 parseBracedList();
402 break;
403 case tok::r_brace:
404 nextToken();
405 return;
406 default:
407 nextToken();
408 break;
409 }
410 } while (!eof());
411}
412
Manuel Klimek762dd182013-01-21 10:07:49 +0000413void UnwrappedLineParser::parseReturn() {
414 nextToken();
415
416 do {
417 switch (FormatTok.Tok.getKind()) {
418 case tok::l_brace:
419 parseBracedList();
420 break;
421 case tok::l_paren:
422 parseParens();
423 break;
424 case tok::r_brace:
425 // Assume missing ';'.
426 addUnwrappedLine();
427 return;
428 case tok::semi:
429 nextToken();
430 addUnwrappedLine();
431 return;
432 default:
433 nextToken();
434 break;
435 }
436 } while (!eof());
437}
438
Daniel Jasperf7935112012-12-03 18:12:45 +0000439void UnwrappedLineParser::parseParens() {
440 assert(FormatTok.Tok.is(tok::l_paren) && "'(' expected.");
441 nextToken();
442 do {
443 switch (FormatTok.Tok.getKind()) {
444 case tok::l_paren:
445 parseParens();
446 break;
447 case tok::r_paren:
448 nextToken();
449 return;
Nico Weber67ffb332013-02-10 04:38:23 +0000450 case tok::l_brace: {
451 nextToken();
452 ScopedLineState LineState(*this);
453 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
454 /*MustBeDeclaration=*/ false);
455 Line->Level += 1;
456 parseLevel(/*HasOpeningBrace=*/ true);
457 Line->Level -= 1;
Manuel Klimek8e07a1b2013-01-10 11:52:21 +0000458 break;
Nico Weber67ffb332013-02-10 04:38:23 +0000459 }
Daniel Jasperf7935112012-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 Klimekadededf2013-01-11 18:28:36 +0000470 if (FormatTok.Tok.is(tok::l_paren))
471 parseParens();
Daniel Jasperf7935112012-12-03 18:12:45 +0000472 bool NeedsUnwrappedLine = false;
473 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek0a3a3c92013-01-23 09:32:48 +0000474 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperf7935112012-12-03 18:12:45 +0000475 NeedsUnwrappedLine = true;
476 } else {
477 addUnwrappedLine();
Manuel Klimek52b15152013-01-09 15:25:02 +0000478 ++Line->Level;
Manuel Klimek6b9eeba2013-01-07 14:56:16 +0000479 parseStructuralElement();
Manuel Klimek52b15152013-01-09 15:25:02 +0000480 --Line->Level;
Daniel Jasperf7935112012-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 Klimek0a3a3c92013-01-23 09:32:48 +0000485 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperf7935112012-12-03 18:12:45 +0000486 addUnwrappedLine();
487 } else if (FormatTok.Tok.is(tok::kw_if)) {
488 parseIfThenElse();
489 } else {
490 addUnwrappedLine();
Manuel Klimek52b15152013-01-09 15:25:02 +0000491 ++Line->Level;
Manuel Klimek6b9eeba2013-01-07 14:56:16 +0000492 parseStructuralElement();
Manuel Klimek52b15152013-01-09 15:25:02 +0000493 --Line->Level;
Daniel Jasperf7935112012-12-03 18:12:45 +0000494 }
495 } else if (NeedsUnwrappedLine) {
496 addUnwrappedLine();
497 }
498}
499
Alexander Kornienko578fdd82012-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 Klimek0a3a3c92013-01-23 09:32:48 +0000506 parseBlock(/*MustBeDeclaration=*/ true, 0);
Manuel Klimek046b9302013-02-06 16:08:09 +0000507 // Munch the semicolon after a namespace. This is more common than one would
508 // think. Puttin the semicolon into its own line is very ugly.
509 if (FormatTok.Tok.is(tok::semi))
510 nextToken();
Alexander Kornienko578fdd82012-12-06 18:03:27 +0000511 addUnwrappedLine();
512 }
513 // FIXME: Add error handling.
514}
515
Alexander Kornienko37d6c942012-12-05 15:06:06 +0000516void UnwrappedLineParser::parseForOrWhileLoop() {
517 assert((FormatTok.Tok.is(tok::kw_for) || FormatTok.Tok.is(tok::kw_while)) &&
518 "'for' or 'while' expected");
519 nextToken();
Manuel Klimek9fa8d552013-01-11 19:23:05 +0000520 if (FormatTok.Tok.is(tok::l_paren))
521 parseParens();
Alexander Kornienko37d6c942012-12-05 15:06:06 +0000522 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek0a3a3c92013-01-23 09:32:48 +0000523 parseBlock(/*MustBeDeclaration=*/ false);
Alexander Kornienko37d6c942012-12-05 15:06:06 +0000524 addUnwrappedLine();
525 } else {
526 addUnwrappedLine();
Manuel Klimek52b15152013-01-09 15:25:02 +0000527 ++Line->Level;
Manuel Klimek6b9eeba2013-01-07 14:56:16 +0000528 parseStructuralElement();
Manuel Klimek52b15152013-01-09 15:25:02 +0000529 --Line->Level;
Alexander Kornienko37d6c942012-12-05 15:06:06 +0000530 }
531}
532
Daniel Jasperf7935112012-12-03 18:12:45 +0000533void UnwrappedLineParser::parseDoWhile() {
534 assert(FormatTok.Tok.is(tok::kw_do) && "'do' expected");
535 nextToken();
536 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek0a3a3c92013-01-23 09:32:48 +0000537 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperf7935112012-12-03 18:12:45 +0000538 } else {
539 addUnwrappedLine();
Manuel Klimek52b15152013-01-09 15:25:02 +0000540 ++Line->Level;
Manuel Klimek6b9eeba2013-01-07 14:56:16 +0000541 parseStructuralElement();
Manuel Klimek52b15152013-01-09 15:25:02 +0000542 --Line->Level;
Daniel Jasperf7935112012-12-03 18:12:45 +0000543 }
544
Alexander Kornienko0ea8e102012-12-04 15:40:36 +0000545 // FIXME: Add error handling.
546 if (!FormatTok.Tok.is(tok::kw_while)) {
547 addUnwrappedLine();
548 return;
549 }
550
Daniel Jasperf7935112012-12-03 18:12:45 +0000551 nextToken();
Manuel Klimek6b9eeba2013-01-07 14:56:16 +0000552 parseStructuralElement();
Daniel Jasperf7935112012-12-03 18:12:45 +0000553}
554
555void UnwrappedLineParser::parseLabel() {
556 // FIXME: remove all asserts.
557 assert(FormatTok.Tok.is(tok::colon) && "':' expected");
558 nextToken();
Manuel Klimek52b15152013-01-09 15:25:02 +0000559 unsigned OldLineLevel = Line->Level;
560 if (Line->Level > 0)
561 --Line->Level;
Daniel Jasperf7935112012-12-03 18:12:45 +0000562 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek0a3a3c92013-01-23 09:32:48 +0000563 parseBlock(/*MustBeDeclaration=*/ false);
Nico Webera5510af2013-01-18 05:50:57 +0000564 if (FormatTok.Tok.is(tok::kw_break))
565 parseStructuralElement(); // "break;" after "}" goes on the same line.
Daniel Jasperf7935112012-12-03 18:12:45 +0000566 }
567 addUnwrappedLine();
Manuel Klimek52b15152013-01-09 15:25:02 +0000568 Line->Level = OldLineLevel;
Daniel Jasperf7935112012-12-03 18:12:45 +0000569}
570
571void UnwrappedLineParser::parseCaseLabel() {
572 assert(FormatTok.Tok.is(tok::kw_case) && "'case' expected");
573 // FIXME: fix handling of complex expressions here.
574 do {
575 nextToken();
576 } while (!eof() && !FormatTok.Tok.is(tok::colon));
577 parseLabel();
578}
579
580void UnwrappedLineParser::parseSwitch() {
581 assert(FormatTok.Tok.is(tok::kw_switch) && "'switch' expected");
582 nextToken();
Manuel Klimek9fa8d552013-01-11 19:23:05 +0000583 if (FormatTok.Tok.is(tok::l_paren))
584 parseParens();
Daniel Jasperf7935112012-12-03 18:12:45 +0000585 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek0a3a3c92013-01-23 09:32:48 +0000586 parseBlock(/*MustBeDeclaration=*/ false, Style.IndentCaseLabels ? 2 : 1);
Daniel Jasperf7935112012-12-03 18:12:45 +0000587 addUnwrappedLine();
588 } else {
589 addUnwrappedLine();
Manuel Klimek52b15152013-01-09 15:25:02 +0000590 Line->Level += (Style.IndentCaseLabels ? 2 : 1);
Manuel Klimek6b9eeba2013-01-07 14:56:16 +0000591 parseStructuralElement();
Manuel Klimek52b15152013-01-09 15:25:02 +0000592 Line->Level -= (Style.IndentCaseLabels ? 2 : 1);
Daniel Jasperf7935112012-12-03 18:12:45 +0000593 }
594}
595
596void UnwrappedLineParser::parseAccessSpecifier() {
597 nextToken();
Alexander Kornienko2ca766f2012-12-10 16:34:48 +0000598 // Otherwise, we don't know what it is, and we'd better keep the next token.
599 if (FormatTok.Tok.is(tok::colon))
600 nextToken();
Daniel Jasperf7935112012-12-03 18:12:45 +0000601 addUnwrappedLine();
602}
603
604void UnwrappedLineParser::parseEnum() {
Manuel Klimek2cec0192013-01-21 19:17:52 +0000605 nextToken();
606 if (FormatTok.Tok.is(tok::identifier) ||
607 FormatTok.Tok.is(tok::kw___attribute) ||
608 FormatTok.Tok.is(tok::kw___declspec)) {
609 nextToken();
610 // We can have macros or attributes in between 'enum' and the enum name.
611 if (FormatTok.Tok.is(tok::l_paren)) {
Alexander Kornienkob7076a22012-12-04 14:46:19 +0000612 parseParens();
Daniel Jasperf7935112012-12-03 18:12:45 +0000613 }
Manuel Klimek2cec0192013-01-21 19:17:52 +0000614 if (FormatTok.Tok.is(tok::identifier))
615 nextToken();
616 }
617 if (FormatTok.Tok.is(tok::l_brace)) {
618 nextToken();
619 addUnwrappedLine();
620 ++Line->Level;
621 do {
622 switch (FormatTok.Tok.getKind()) {
Manuel Klimek2cec0192013-01-21 19:17:52 +0000623 case tok::l_paren:
624 parseParens();
625 break;
626 case tok::r_brace:
627 addUnwrappedLine();
628 nextToken();
629 --Line->Level;
630 return;
631 case tok::comma:
632 nextToken();
633 addUnwrappedLine();
634 break;
635 default:
636 nextToken();
637 break;
638 }
639 } while (!eof());
640 }
641 // We fall through to parsing a structural element afterwards, so that in
642 // enum A {} n, m;
643 // "} n, m;" will end up in one unwrapped line.
Daniel Jasperf7935112012-12-03 18:12:45 +0000644}
645
Manuel Klimeke01bab52013-01-15 13:38:33 +0000646void UnwrappedLineParser::parseRecord() {
Manuel Klimek28cacc72013-01-07 18:10:23 +0000647 nextToken();
Manuel Klimeke01bab52013-01-15 13:38:33 +0000648 if (FormatTok.Tok.is(tok::identifier) ||
649 FormatTok.Tok.is(tok::kw___attribute) ||
650 FormatTok.Tok.is(tok::kw___declspec)) {
651 nextToken();
652 // We can have macros or attributes in between 'class' and the class name.
653 if (FormatTok.Tok.is(tok::l_paren)) {
654 parseParens();
Manuel Klimek28cacc72013-01-07 18:10:23 +0000655 }
Manuel Klimekd2650902013-02-06 15:57:54 +0000656 // The actual identifier can be a nested name specifier, and in macros
657 // it is often token-pasted.
Manuel Klimek3c6b7c72013-01-21 10:17:14 +0000658 while (FormatTok.Tok.is(tok::identifier) ||
Manuel Klimekd2650902013-02-06 15:57:54 +0000659 FormatTok.Tok.is(tok::coloncolon) ||
660 FormatTok.Tok.is(tok::hashhash))
Manuel Klimeke01bab52013-01-15 13:38:33 +0000661 nextToken();
662
Manuel Klimekcdee74d2013-01-21 13:58:54 +0000663 // Note that parsing away template declarations here leads to incorrectly
664 // accepting function declarations as record declarations.
665 // In general, we cannot solve this problem. Consider:
666 // class A<int> B() {}
667 // which can be a function definition or a class definition when B() is a
668 // macro. If we find enough real-world cases where this is a problem, we
669 // can parse for the 'template' keyword in the beginning of the statement,
670 // and thus rule out the record production in case there is no template
671 // (this would still leave us with an ambiguity between template function
672 // and class declarations).
673 if (FormatTok.Tok.is(tok::colon) || FormatTok.Tok.is(tok::less)) {
Manuel Klimeke01bab52013-01-15 13:38:33 +0000674 while (FormatTok.Tok.isNot(tok::l_brace)) {
675 if (FormatTok.Tok.is(tok::semi))
676 return;
677 nextToken();
678 }
679 }
680 }
681 if (FormatTok.Tok.is(tok::l_brace))
Manuel Klimek0a3a3c92013-01-23 09:32:48 +0000682 parseBlock(/*MustBeDeclaration=*/ true);
Manuel Klimekcdee74d2013-01-21 13:58:54 +0000683 // We fall through to parsing a structural element afterwards, so
684 // class A {} n, m;
685 // will end up in one unwrapped line.
Manuel Klimek28cacc72013-01-07 18:10:23 +0000686}
687
Nico Weber8696a8d2013-01-09 21:15:03 +0000688void UnwrappedLineParser::parseObjCProtocolList() {
689 assert(FormatTok.Tok.is(tok::less) && "'<' expected.");
690 do
691 nextToken();
692 while (!eof() && FormatTok.Tok.isNot(tok::greater));
693 nextToken(); // Skip '>'.
694}
695
696void UnwrappedLineParser::parseObjCUntilAtEnd() {
697 do {
698 if (FormatTok.Tok.isObjCAtKeyword(tok::objc_end)) {
699 nextToken();
700 addUnwrappedLine();
701 break;
702 }
703 parseStructuralElement();
704 } while (!eof());
705}
706
Nico Weber2ce0ac52013-01-09 23:25:37 +0000707void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
Nico Weber7eecf4b2013-01-09 20:25:35 +0000708 nextToken();
709 nextToken(); // interface name
710
711 // @interface can be followed by either a base class, or a category.
712 if (FormatTok.Tok.is(tok::colon)) {
713 nextToken();
714 nextToken(); // base class name
715 } else if (FormatTok.Tok.is(tok::l_paren))
716 // Skip category, if present.
717 parseParens();
718
Nico Weber8696a8d2013-01-09 21:15:03 +0000719 if (FormatTok.Tok.is(tok::less))
720 parseObjCProtocolList();
Nico Weber7eecf4b2013-01-09 20:25:35 +0000721
722 // If instance variables are present, keep the '{' on the first line too.
723 if (FormatTok.Tok.is(tok::l_brace))
Manuel Klimek0a3a3c92013-01-23 09:32:48 +0000724 parseBlock(/*MustBeDeclaration=*/ true);
Nico Weber7eecf4b2013-01-09 20:25:35 +0000725
726 // With instance variables, this puts '}' on its own line. Without instance
727 // variables, this ends the @interface line.
728 addUnwrappedLine();
729
Nico Weber8696a8d2013-01-09 21:15:03 +0000730 parseObjCUntilAtEnd();
731}
Nico Weber7eecf4b2013-01-09 20:25:35 +0000732
Nico Weber8696a8d2013-01-09 21:15:03 +0000733void UnwrappedLineParser::parseObjCProtocol() {
734 nextToken();
735 nextToken(); // protocol name
736
737 if (FormatTok.Tok.is(tok::less))
738 parseObjCProtocolList();
739
740 // Check for protocol declaration.
741 if (FormatTok.Tok.is(tok::semi)) {
742 nextToken();
743 return addUnwrappedLine();
744 }
745
746 addUnwrappedLine();
747 parseObjCUntilAtEnd();
Nico Weber7eecf4b2013-01-09 20:25:35 +0000748}
749
Daniel Jasperf7935112012-12-03 18:12:45 +0000750void UnwrappedLineParser::addUnwrappedLine() {
Daniel Jasperdaffc0d2013-01-16 09:10:19 +0000751 if (Line->Tokens.empty())
Daniel Jasper7c85fde2013-01-08 14:56:18 +0000752 return;
Manuel Klimekab3dc002013-01-16 12:31:12 +0000753 DEBUG({
Manuel Klimekf92f7bc2013-01-22 16:31:55 +0000754 llvm::dbgs() << "Line(" << Line->Level << "): ";
Manuel Klimekab3dc002013-01-16 12:31:12 +0000755 for (std::list<FormatToken>::iterator I = Line->Tokens.begin(),
756 E = Line->Tokens.end();
757 I != E; ++I) {
758 llvm::dbgs() << I->Tok.getName() << " ";
Daniel Jasperdaffc0d2013-01-16 09:10:19 +0000759
Manuel Klimekab3dc002013-01-16 12:31:12 +0000760 }
761 llvm::dbgs() << "\n";
762 });
Manuel Klimekd3b92fa2013-01-18 14:04:34 +0000763 CurrentLines->push_back(*Line);
Daniel Jasperdaffc0d2013-01-16 09:10:19 +0000764 Line->Tokens.clear();
Manuel Klimekd3b92fa2013-01-18 14:04:34 +0000765 if (CurrentLines == &Lines && !PreprocessorDirectives.empty()) {
766 for (std::vector<UnwrappedLine>::iterator I = PreprocessorDirectives
767 .begin(), E = PreprocessorDirectives.end();
768 I != E; ++I) {
769 CurrentLines->push_back(*I);
770 }
771 PreprocessorDirectives.clear();
772 }
773
Daniel Jasperf7935112012-12-03 18:12:45 +0000774}
775
776bool UnwrappedLineParser::eof() const {
777 return FormatTok.Tok.is(tok::eof);
778}
779
Manuel Klimekf92f7bc2013-01-22 16:31:55 +0000780void UnwrappedLineParser::flushComments(bool NewlineBeforeNext) {
781 bool JustComments = Line->Tokens.empty();
782 for (SmallVectorImpl<FormatToken>::const_iterator
783 I = CommentsBeforeNextToken.begin(),
784 E = CommentsBeforeNextToken.end();
785 I != E; ++I) {
Manuel Klimek82b836a2013-02-06 16:40:56 +0000786 if (I->NewlinesBefore && JustComments) {
Manuel Klimekf92f7bc2013-01-22 16:31:55 +0000787 addUnwrappedLine();
788 }
789 pushToken(*I);
790 }
791 if (NewlineBeforeNext && JustComments) {
792 addUnwrappedLine();
793 }
794 CommentsBeforeNextToken.clear();
795}
796
Daniel Jasperf7935112012-12-03 18:12:45 +0000797void UnwrappedLineParser::nextToken() {
798 if (eof())
799 return;
Manuel Klimek82b836a2013-02-06 16:40:56 +0000800 flushComments(FormatTok.NewlinesBefore > 0);
Manuel Klimekf92f7bc2013-01-22 16:31:55 +0000801 pushToken(FormatTok);
Manuel Klimek1abf7892013-01-04 23:34:14 +0000802 readToken();
803}
804
805void UnwrappedLineParser::readToken() {
Manuel Klimekf92f7bc2013-01-22 16:31:55 +0000806 bool CommentsInCurrentLine = true;
807 do {
808 FormatTok = Tokens->getNextToken();
809 while (!Line->InPPDirective && FormatTok.Tok.is(tok::hash) &&
810 ((FormatTok.NewlinesBefore > 0 && FormatTok.HasUnescapedNewline) ||
811 FormatTok.IsFirst)) {
812 // If there is an unfinished unwrapped line, we flush the preprocessor
813 // directives only after that unwrapped line was finished later.
814 bool SwitchToPreprocessorLines = !Line->Tokens.empty() &&
815 CurrentLines == &Lines;
816 ScopedLineState BlockState(*this, SwitchToPreprocessorLines);
817 parsePPDirective();
818 }
819 if (!FormatTok.Tok.is(tok::comment))
820 return;
Manuel Klimek82b836a2013-02-06 16:40:56 +0000821 if (FormatTok.NewlinesBefore > 0 || FormatTok.IsFirst) {
Manuel Klimekf92f7bc2013-01-22 16:31:55 +0000822 CommentsInCurrentLine = false;
823 }
824 if (CommentsInCurrentLine) {
825 pushToken(FormatTok);
826 } else {
827 CommentsBeforeNextToken.push_back(FormatTok);
828 }
829 } while (!eof());
830}
831
832void UnwrappedLineParser::pushToken(const FormatToken &Tok) {
833 Line->Tokens.push_back(Tok);
834 if (MustBreakBeforeNextToken) {
835 Line->Tokens.back().MustBreakBefore = true;
836 MustBreakBeforeNextToken = false;
Manuel Klimek1abf7892013-01-04 23:34:14 +0000837 }
Daniel Jasperf7935112012-12-03 18:12:45 +0000838}
839
Daniel Jasper8d1832e2013-01-07 13:26:07 +0000840} // end namespace format
841} // end namespace clang