blob: d218f88e551073fb196f6253f5aab0c3dd17e2ea [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;
Alexander Kornienkof52d5272013-04-02 13:04:06 +0000103 Parser.CommentsBeforeNextToken.swap(CommentsBeforeNextToken);
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000104 }
105
106 ~ScopedLineState() {
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000107 if (!Parser.Line->Tokens.empty()) {
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000108 Parser.addUnwrappedLine();
109 }
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000110 assert(Parser.Line->Tokens.empty());
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000111 Parser.Line.reset(PreBlockLine);
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000112 Parser.MustBreakBeforeNextToken = true;
Manuel Klimek525fe162013-01-18 14:04:34 +0000113 if (SwitchToPreprocessorLines)
114 Parser.CurrentLines = &Parser.Lines;
Alexander Kornienkof52d5272013-04-02 13:04:06 +0000115 Parser.CommentsBeforeNextToken.swap(CommentsBeforeNextToken);
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000116 }
117
118private:
119 UnwrappedLineParser &Parser;
Manuel Klimek525fe162013-01-18 14:04:34 +0000120 const bool SwitchToPreprocessorLines;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000121
122 UnwrappedLine *PreBlockLine;
Alexander Kornienkof52d5272013-04-02 13:04:06 +0000123 SmallVector<FormatToken, 1> CommentsBeforeNextToken;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000124};
125
Alexander Kornienko3048aea2013-01-10 15:05:09 +0000126UnwrappedLineParser::UnwrappedLineParser(
127 clang::DiagnosticsEngine &Diag, const FormatStyle &Style,
128 FormatTokenSource &Tokens, UnwrappedLineConsumer &Callback)
Manuel Klimek525fe162013-01-18 14:04:34 +0000129 : Line(new UnwrappedLine), MustBreakBeforeNextToken(false),
130 CurrentLines(&Lines), Diag(Diag), Style(Style), Tokens(&Tokens),
131 Callback(Callback) {}
Daniel Jasperbac016b2012-12-03 18:12:45 +0000132
Alexander Kornienkocff563c2012-12-04 17:27:50 +0000133bool UnwrappedLineParser::parse() {
Manuel Klimek8fa37992013-01-16 12:31:12 +0000134 DEBUG(llvm::dbgs() << "----\n");
Manuel Klimekd4397b92013-01-04 23:34:14 +0000135 readToken();
Manuel Klimek525fe162013-01-18 14:04:34 +0000136 bool Error = parseFile();
Daniel Jasperf9955d32013-03-20 12:37:50 +0000137 for (std::vector<UnwrappedLine>::iterator I = Lines.begin(), E = Lines.end();
Manuel Klimek525fe162013-01-18 14:04:34 +0000138 I != E; ++I) {
139 Callback.consumeUnwrappedLine(*I);
140 }
Daniel Jasper516fb312013-03-01 18:11:39 +0000141
142 // Create line with eof token.
143 pushToken(FormatTok);
144 Callback.consumeUnwrappedLine(*Line);
145
Manuel Klimek525fe162013-01-18 14:04:34 +0000146 return Error;
Manuel Klimekd4397b92013-01-04 23:34:14 +0000147}
148
149bool UnwrappedLineParser::parseFile() {
Daniel Jasper627707b2013-03-22 16:55:40 +0000150 ScopedDeclarationState DeclarationState(
151 *Line, DeclarationScopeStack,
152 /*MustBeDeclaration=*/ !Line->InPPDirective);
Daniel Jasperf9955d32013-03-20 12:37:50 +0000153 bool Error = parseLevel(/*HasOpeningBrace=*/ false);
Manuel Klimekd4397b92013-01-04 23:34:14 +0000154 // Make sure to format the remaining tokens.
Manuel Klimek86721d22013-01-22 16:31:55 +0000155 flushComments(true);
Manuel Klimekd4397b92013-01-04 23:34:14 +0000156 addUnwrappedLine();
157 return Error;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000158}
159
Manuel Klimeka5342db2013-01-06 20:07:31 +0000160bool UnwrappedLineParser::parseLevel(bool HasOpeningBrace) {
Alexander Kornienkocff563c2012-12-04 17:27:50 +0000161 bool Error = false;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000162 do {
163 switch (FormatTok.Tok.getKind()) {
Daniel Jasperbac016b2012-12-03 18:12:45 +0000164 case tok::comment:
Daniel Jasper05b1ac82012-12-17 11:29:41 +0000165 nextToken();
166 addUnwrappedLine();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000167 break;
168 case tok::l_brace:
Manuel Klimek70b03f42013-01-23 09:32:48 +0000169 // FIXME: Add parameter whether this can happen - if this happens, we must
170 // be in a non-declaration context.
171 Error |= parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000172 addUnwrappedLine();
173 break;
174 case tok::r_brace:
Manuel Klimeka5342db2013-01-06 20:07:31 +0000175 if (HasOpeningBrace) {
176 return false;
177 } else {
Alexander Kornienko3048aea2013-01-10 15:05:09 +0000178 Diag.Report(FormatTok.Tok.getLocation(),
179 Diag.getCustomDiagID(clang::DiagnosticsEngine::Error,
Alexander Kornienko276a2092013-01-11 16:03:45 +0000180 "unexpected '}'"));
Manuel Klimeka5342db2013-01-06 20:07:31 +0000181 Error = true;
182 nextToken();
183 addUnwrappedLine();
184 }
185 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000186 default:
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000187 parseStructuralElement();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000188 break;
189 }
190 } while (!eof());
Alexander Kornienkocff563c2012-12-04 17:27:50 +0000191 return Error;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000192}
193
Nico Weberd74fcdb2013-02-10 20:35:35 +0000194bool UnwrappedLineParser::parseBlock(bool MustBeDeclaration,
195 unsigned AddLevels) {
Alexander Kornienkoa3a2b3a2012-12-06 17:49:17 +0000196 assert(FormatTok.Tok.is(tok::l_brace) && "'{' expected");
Daniel Jasperbac016b2012-12-03 18:12:45 +0000197 nextToken();
198
Manuel Klimek2f1ac412013-01-21 16:42:44 +0000199 addUnwrappedLine();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000200
Manuel Klimek70b03f42013-01-23 09:32:48 +0000201 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
202 MustBeDeclaration);
Manuel Klimek2f1ac412013-01-21 16:42:44 +0000203 Line->Level += AddLevels;
Daniel Jasperf9955d32013-03-20 12:37:50 +0000204 parseLevel(/*HasOpeningBrace=*/ true);
Alexander Kornienko15757312012-12-06 18:03:27 +0000205
Manuel Klimek86721d22013-01-22 16:31:55 +0000206 if (!FormatTok.Tok.is(tok::r_brace)) {
207 Line->Level -= AddLevels;
Manuel Klimek2f1ac412013-01-21 16:42:44 +0000208 return true;
Manuel Klimek86721d22013-01-22 16:31:55 +0000209 }
Alexander Kornienko393b0082012-12-04 15:40:36 +0000210
Daniel Jasperf9955d32013-03-20 12:37:50 +0000211 nextToken(); // Munch the closing brace.
Manuel Klimek86721d22013-01-22 16:31:55 +0000212 Line->Level -= AddLevels;
Alexander Kornienkocff563c2012-12-04 17:27:50 +0000213 return false;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000214}
215
216void UnwrappedLineParser::parsePPDirective() {
Manuel Klimeka080a182013-01-02 16:30:12 +0000217 assert(FormatTok.Tok.is(tok::hash) && "'#' expected");
Manuel Klimek526ed112013-01-09 15:25:02 +0000218 ScopedMacroState MacroState(*Line, Tokens, FormatTok);
Manuel Klimeka080a182013-01-02 16:30:12 +0000219 nextToken();
220
Manuel Klimeka080a182013-01-02 16:30:12 +0000221 if (FormatTok.Tok.getIdentifierInfo() == NULL) {
Manuel Klimekbd04f2a2013-01-31 15:58:48 +0000222 parsePPUnknown();
Manuel Klimeka080a182013-01-02 16:30:12 +0000223 return;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000224 }
Manuel Klimeka080a182013-01-02 16:30:12 +0000225
Manuel Klimekd4397b92013-01-04 23:34:14 +0000226 switch (FormatTok.Tok.getIdentifierInfo()->getPPKeywordID()) {
227 case tok::pp_define:
228 parsePPDefine();
229 break;
230 default:
231 parsePPUnknown();
232 break;
233 }
234}
235
236void UnwrappedLineParser::parsePPDefine() {
237 nextToken();
238
239 if (FormatTok.Tok.getKind() != tok::identifier) {
240 parsePPUnknown();
241 return;
242 }
243 nextToken();
Manuel Klimek7ccbc212013-01-23 14:37:36 +0000244 if (FormatTok.Tok.getKind() == tok::l_paren &&
245 FormatTok.WhiteSpaceLength == 0) {
Manuel Klimekd4397b92013-01-04 23:34:14 +0000246 parseParens();
247 }
248 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000249 Line->Level = 1;
Manuel Klimekc3d0c822013-01-07 09:34:28 +0000250
251 // Errors during a preprocessor directive can only affect the layout of the
252 // preprocessor directive, and thus we ignore them. An alternative approach
253 // would be to use the same approach we use on the file level (no
254 // re-indentation if there was a structural error) within the macro
255 // definition.
Manuel Klimekd4397b92013-01-04 23:34:14 +0000256 parseFile();
257}
258
259void UnwrappedLineParser::parsePPUnknown() {
Manuel Klimeka080a182013-01-02 16:30:12 +0000260 do {
Manuel Klimeka080a182013-01-02 16:30:12 +0000261 nextToken();
262 } while (!eof());
263 addUnwrappedLine();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000264}
265
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000266void UnwrappedLineParser::parseStructuralElement() {
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000267 assert(!FormatTok.Tok.is(tok::l_brace));
Dmitri Gribenko1f94f2b2012-12-30 21:27:25 +0000268 int TokenNumber = 0;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000269 switch (FormatTok.Tok.getKind()) {
Nico Weber6092d4e2013-01-07 19:05:19 +0000270 case tok::at:
271 nextToken();
Nico Weberd74fcdb2013-02-10 20:35:35 +0000272 if (FormatTok.Tok.is(tok::l_brace)) {
273 parseBracedList();
274 break;
275 }
Nico Weber6092d4e2013-01-07 19:05:19 +0000276 switch (FormatTok.Tok.getObjCKeywordID()) {
277 case tok::objc_public:
278 case tok::objc_protected:
279 case tok::objc_package:
280 case tok::objc_private:
281 return parseAccessSpecifier();
Nico Weber27d13672013-01-09 20:25:35 +0000282 case tok::objc_interface:
Nico Weber50767d82013-01-09 23:25:37 +0000283 case tok::objc_implementation:
284 return parseObjCInterfaceOrImplementation();
Nico Weber1abe6ea2013-01-09 21:15:03 +0000285 case tok::objc_protocol:
286 return parseObjCProtocol();
Nico Weber049c4472013-01-09 21:42:32 +0000287 case tok::objc_end:
288 return; // Handled by the caller.
Nico Weberb530fa32013-01-10 00:25:19 +0000289 case tok::objc_optional:
290 case tok::objc_required:
291 nextToken();
292 addUnwrappedLine();
293 return;
Nico Weber6092d4e2013-01-07 19:05:19 +0000294 default:
295 break;
296 }
297 break;
Alexander Kornienko15757312012-12-06 18:03:27 +0000298 case tok::kw_namespace:
299 parseNamespace();
300 return;
Dmitri Gribenko1f94f2b2012-12-30 21:27:25 +0000301 case tok::kw_inline:
302 nextToken();
303 TokenNumber++;
304 if (FormatTok.Tok.is(tok::kw_namespace)) {
305 parseNamespace();
306 return;
307 }
308 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000309 case tok::kw_public:
310 case tok::kw_protected:
311 case tok::kw_private:
Daniel Jasperbac016b2012-12-03 18:12:45 +0000312 parseAccessSpecifier();
313 return;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000314 case tok::kw_if:
315 parseIfThenElse();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000316 return;
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000317 case tok::kw_for:
318 case tok::kw_while:
319 parseForOrWhileLoop();
320 return;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000321 case tok::kw_do:
322 parseDoWhile();
323 return;
324 case tok::kw_switch:
325 parseSwitch();
326 return;
327 case tok::kw_default:
328 nextToken();
329 parseLabel();
330 return;
331 case tok::kw_case:
332 parseCaseLabel();
333 return;
Manuel Klimekc44ee892013-01-21 10:07:49 +0000334 case tok::kw_return:
335 parseReturn();
336 return;
Manuel Klimekd19dc2d2013-01-21 14:32:05 +0000337 case tok::kw_extern:
338 nextToken();
339 if (FormatTok.Tok.is(tok::string_literal)) {
340 nextToken();
341 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000342 parseBlock(/*MustBeDeclaration=*/ true, 0);
Manuel Klimekd19dc2d2013-01-21 14:32:05 +0000343 addUnwrappedLine();
344 return;
345 }
346 }
347 // In all other cases, parse the declaration.
348 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000349 default:
350 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000351 }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000352 do {
353 ++TokenNumber;
354 switch (FormatTok.Tok.getKind()) {
Nico Weberd74fcdb2013-02-10 20:35:35 +0000355 case tok::at:
356 nextToken();
357 if (FormatTok.Tok.is(tok::l_brace))
358 parseBracedList();
359 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000360 case tok::kw_enum:
361 parseEnum();
Manuel Klimek308232c2013-01-21 19:17:52 +0000362 break;
Alexander Kornienkod8818752013-01-16 11:43:46 +0000363 case tok::kw_struct:
364 case tok::kw_union:
Manuel Klimekde768542013-01-07 18:10:23 +0000365 case tok::kw_class:
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000366 parseRecord();
367 // A record declaration or definition is always the start of a structural
368 // element.
369 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000370 case tok::semi:
371 nextToken();
372 addUnwrappedLine();
373 return;
Alexander Kornienkod8818752013-01-16 11:43:46 +0000374 case tok::r_brace:
375 addUnwrappedLine();
376 return;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000377 case tok::l_paren:
378 parseParens();
379 break;
380 case tok::l_brace:
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000381 // A block outside of parentheses must be the last part of a
382 // structural element.
383 // FIXME: Figure out cases where this is not true, and add projections for
384 // them (the one we know is missing are lambdas).
Manuel Klimek70b03f42013-01-23 09:32:48 +0000385 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000386 addUnwrappedLine();
387 return;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000388 case tok::identifier:
Daniel Jasperbac016b2012-12-03 18:12:45 +0000389 nextToken();
390 if (TokenNumber == 1 && FormatTok.Tok.is(tok::colon)) {
391 parseLabel();
392 return;
393 }
394 break;
Daniel Jasper05b1ac82012-12-17 11:29:41 +0000395 case tok::equal:
396 nextToken();
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000397 if (FormatTok.Tok.is(tok::l_brace)) {
398 parseBracedList();
399 }
Daniel Jasper05b1ac82012-12-17 11:29:41 +0000400 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000401 default:
402 nextToken();
403 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000404 }
405 } while (!eof());
406}
407
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000408void UnwrappedLineParser::parseBracedList() {
409 nextToken();
410
411 do {
412 switch (FormatTok.Tok.getKind()) {
413 case tok::l_brace:
414 parseBracedList();
415 break;
416 case tok::r_brace:
417 nextToken();
418 return;
419 default:
420 nextToken();
421 break;
422 }
423 } while (!eof());
424}
425
Manuel Klimekc44ee892013-01-21 10:07:49 +0000426void UnwrappedLineParser::parseReturn() {
427 nextToken();
428
429 do {
430 switch (FormatTok.Tok.getKind()) {
431 case tok::l_brace:
432 parseBracedList();
433 break;
434 case tok::l_paren:
435 parseParens();
436 break;
437 case tok::r_brace:
438 // Assume missing ';'.
439 addUnwrappedLine();
440 return;
441 case tok::semi:
442 nextToken();
443 addUnwrappedLine();
444 return;
445 default:
446 nextToken();
447 break;
448 }
449 } while (!eof());
450}
451
Daniel Jasperbac016b2012-12-03 18:12:45 +0000452void UnwrappedLineParser::parseParens() {
453 assert(FormatTok.Tok.is(tok::l_paren) && "'(' expected.");
454 nextToken();
455 do {
456 switch (FormatTok.Tok.getKind()) {
457 case tok::l_paren:
458 parseParens();
459 break;
460 case tok::r_paren:
461 nextToken();
462 return;
Nico Weber2afbe522013-02-10 04:38:23 +0000463 case tok::l_brace: {
464 nextToken();
465 ScopedLineState LineState(*this);
466 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
467 /*MustBeDeclaration=*/ false);
468 Line->Level += 1;
469 parseLevel(/*HasOpeningBrace=*/ true);
470 Line->Level -= 1;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000471 break;
Nico Weber2afbe522013-02-10 04:38:23 +0000472 }
Nico Weberd74fcdb2013-02-10 20:35:35 +0000473 case tok::at:
474 nextToken();
475 if (FormatTok.Tok.is(tok::l_brace))
476 parseBracedList();
477 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000478 default:
479 nextToken();
480 break;
481 }
482 } while (!eof());
483}
484
485void UnwrappedLineParser::parseIfThenElse() {
486 assert(FormatTok.Tok.is(tok::kw_if) && "'if' expected");
487 nextToken();
Manuel Klimekd4658432013-01-11 18:28:36 +0000488 if (FormatTok.Tok.is(tok::l_paren))
489 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000490 bool NeedsUnwrappedLine = false;
491 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000492 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000493 NeedsUnwrappedLine = true;
494 } else {
495 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000496 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000497 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000498 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000499 }
500 if (FormatTok.Tok.is(tok::kw_else)) {
501 nextToken();
502 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000503 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000504 addUnwrappedLine();
505 } else if (FormatTok.Tok.is(tok::kw_if)) {
506 parseIfThenElse();
507 } else {
508 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000509 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000510 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000511 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000512 }
513 } else if (NeedsUnwrappedLine) {
514 addUnwrappedLine();
515 }
516}
517
Alexander Kornienko15757312012-12-06 18:03:27 +0000518void UnwrappedLineParser::parseNamespace() {
519 assert(FormatTok.Tok.is(tok::kw_namespace) && "'namespace' expected");
520 nextToken();
521 if (FormatTok.Tok.is(tok::identifier))
522 nextToken();
523 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000524 parseBlock(/*MustBeDeclaration=*/ true, 0);
Manuel Klimek7fc2db02013-02-06 16:08:09 +0000525 // Munch the semicolon after a namespace. This is more common than one would
526 // think. Puttin the semicolon into its own line is very ugly.
527 if (FormatTok.Tok.is(tok::semi))
528 nextToken();
Alexander Kornienko15757312012-12-06 18:03:27 +0000529 addUnwrappedLine();
530 }
531 // FIXME: Add error handling.
532}
533
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000534void UnwrappedLineParser::parseForOrWhileLoop() {
535 assert((FormatTok.Tok.is(tok::kw_for) || FormatTok.Tok.is(tok::kw_while)) &&
536 "'for' or 'while' expected");
537 nextToken();
Manuel Klimek6eca03f2013-01-11 19:23:05 +0000538 if (FormatTok.Tok.is(tok::l_paren))
539 parseParens();
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000540 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000541 parseBlock(/*MustBeDeclaration=*/ false);
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000542 addUnwrappedLine();
543 } else {
544 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000545 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000546 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000547 --Line->Level;
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000548 }
549}
550
Daniel Jasperbac016b2012-12-03 18:12:45 +0000551void UnwrappedLineParser::parseDoWhile() {
552 assert(FormatTok.Tok.is(tok::kw_do) && "'do' expected");
553 nextToken();
554 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000555 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000556 } else {
557 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000558 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000559 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000560 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000561 }
562
Alexander Kornienko393b0082012-12-04 15:40:36 +0000563 // FIXME: Add error handling.
564 if (!FormatTok.Tok.is(tok::kw_while)) {
565 addUnwrappedLine();
566 return;
567 }
568
Daniel Jasperbac016b2012-12-03 18:12:45 +0000569 nextToken();
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000570 parseStructuralElement();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000571}
572
573void UnwrappedLineParser::parseLabel() {
Daniel Jasper89a0daa2013-02-12 20:17:17 +0000574 if (FormatTok.Tok.isNot(tok::colon))
575 return;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000576 nextToken();
Manuel Klimek526ed112013-01-09 15:25:02 +0000577 unsigned OldLineLevel = Line->Level;
Daniel Jasperbcca7e42013-03-20 10:23:53 +0000578 if (Line->Level > 1 || (!Line->InPPDirective && Line->Level > 0))
Manuel Klimek526ed112013-01-09 15:25:02 +0000579 --Line->Level;
Daniel Jasperc30eb512013-03-19 18:33:58 +0000580 if (CommentsBeforeNextToken.empty() && FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000581 parseBlock(/*MustBeDeclaration=*/ false);
Nico Weber94fb7292013-01-18 05:50:57 +0000582 if (FormatTok.Tok.is(tok::kw_break))
583 parseStructuralElement(); // "break;" after "}" goes on the same line.
Daniel Jasperbac016b2012-12-03 18:12:45 +0000584 }
585 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000586 Line->Level = OldLineLevel;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000587}
588
589void UnwrappedLineParser::parseCaseLabel() {
590 assert(FormatTok.Tok.is(tok::kw_case) && "'case' expected");
591 // FIXME: fix handling of complex expressions here.
592 do {
593 nextToken();
594 } while (!eof() && !FormatTok.Tok.is(tok::colon));
595 parseLabel();
596}
597
598void UnwrappedLineParser::parseSwitch() {
599 assert(FormatTok.Tok.is(tok::kw_switch) && "'switch' expected");
600 nextToken();
Manuel Klimek6eca03f2013-01-11 19:23:05 +0000601 if (FormatTok.Tok.is(tok::l_paren))
602 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000603 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000604 parseBlock(/*MustBeDeclaration=*/ false, Style.IndentCaseLabels ? 2 : 1);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000605 addUnwrappedLine();
606 } else {
607 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000608 Line->Level += (Style.IndentCaseLabels ? 2 : 1);
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000609 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000610 Line->Level -= (Style.IndentCaseLabels ? 2 : 1);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000611 }
612}
613
614void UnwrappedLineParser::parseAccessSpecifier() {
615 nextToken();
Alexander Kornienko56e49c52012-12-10 16:34:48 +0000616 // Otherwise, we don't know what it is, and we'd better keep the next token.
617 if (FormatTok.Tok.is(tok::colon))
618 nextToken();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000619 addUnwrappedLine();
620}
621
622void UnwrappedLineParser::parseEnum() {
Manuel Klimek308232c2013-01-21 19:17:52 +0000623 nextToken();
624 if (FormatTok.Tok.is(tok::identifier) ||
625 FormatTok.Tok.is(tok::kw___attribute) ||
626 FormatTok.Tok.is(tok::kw___declspec)) {
627 nextToken();
628 // We can have macros or attributes in between 'enum' and the enum name.
629 if (FormatTok.Tok.is(tok::l_paren)) {
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000630 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000631 }
Manuel Klimek308232c2013-01-21 19:17:52 +0000632 if (FormatTok.Tok.is(tok::identifier))
633 nextToken();
634 }
635 if (FormatTok.Tok.is(tok::l_brace)) {
636 nextToken();
637 addUnwrappedLine();
638 ++Line->Level;
639 do {
640 switch (FormatTok.Tok.getKind()) {
Manuel Klimek308232c2013-01-21 19:17:52 +0000641 case tok::l_paren:
642 parseParens();
643 break;
644 case tok::r_brace:
645 addUnwrappedLine();
646 nextToken();
647 --Line->Level;
648 return;
649 case tok::comma:
650 nextToken();
651 addUnwrappedLine();
652 break;
653 default:
654 nextToken();
655 break;
656 }
657 } while (!eof());
658 }
659 // We fall through to parsing a structural element afterwards, so that in
660 // enum A {} n, m;
661 // "} n, m;" will end up in one unwrapped line.
Daniel Jasperbac016b2012-12-03 18:12:45 +0000662}
663
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000664void UnwrappedLineParser::parseRecord() {
Manuel Klimekde768542013-01-07 18:10:23 +0000665 nextToken();
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000666 if (FormatTok.Tok.is(tok::identifier) ||
667 FormatTok.Tok.is(tok::kw___attribute) ||
668 FormatTok.Tok.is(tok::kw___declspec)) {
669 nextToken();
670 // We can have macros or attributes in between 'class' and the class name.
671 if (FormatTok.Tok.is(tok::l_paren)) {
672 parseParens();
Manuel Klimekde768542013-01-07 18:10:23 +0000673 }
Manuel Klimekb8b1ce12013-02-06 15:57:54 +0000674 // The actual identifier can be a nested name specifier, and in macros
675 // it is often token-pasted.
Manuel Klimek7f5b0252013-01-21 10:17:14 +0000676 while (FormatTok.Tok.is(tok::identifier) ||
Daniel Jasperf9955d32013-03-20 12:37:50 +0000677 FormatTok.Tok.is(tok::coloncolon) || FormatTok.Tok.is(tok::hashhash))
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000678 nextToken();
679
Manuel Klimek3a3408c2013-01-21 13:58:54 +0000680 // Note that parsing away template declarations here leads to incorrectly
681 // accepting function declarations as record declarations.
682 // In general, we cannot solve this problem. Consider:
683 // class A<int> B() {}
684 // which can be a function definition or a class definition when B() is a
685 // macro. If we find enough real-world cases where this is a problem, we
686 // can parse for the 'template' keyword in the beginning of the statement,
687 // and thus rule out the record production in case there is no template
688 // (this would still leave us with an ambiguity between template function
689 // and class declarations).
690 if (FormatTok.Tok.is(tok::colon) || FormatTok.Tok.is(tok::less)) {
Daniel Jasper6fe554e2013-03-20 15:12:38 +0000691 while (!eof() && FormatTok.Tok.isNot(tok::l_brace)) {
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000692 if (FormatTok.Tok.is(tok::semi))
693 return;
694 nextToken();
695 }
696 }
697 }
698 if (FormatTok.Tok.is(tok::l_brace))
Manuel Klimek70b03f42013-01-23 09:32:48 +0000699 parseBlock(/*MustBeDeclaration=*/ true);
Manuel Klimek3a3408c2013-01-21 13:58:54 +0000700 // We fall through to parsing a structural element afterwards, so
701 // class A {} n, m;
702 // will end up in one unwrapped line.
Manuel Klimekde768542013-01-07 18:10:23 +0000703}
704
Nico Weber1abe6ea2013-01-09 21:15:03 +0000705void UnwrappedLineParser::parseObjCProtocolList() {
706 assert(FormatTok.Tok.is(tok::less) && "'<' expected.");
707 do
708 nextToken();
709 while (!eof() && FormatTok.Tok.isNot(tok::greater));
710 nextToken(); // Skip '>'.
711}
712
713void UnwrappedLineParser::parseObjCUntilAtEnd() {
714 do {
715 if (FormatTok.Tok.isObjCAtKeyword(tok::objc_end)) {
716 nextToken();
717 addUnwrappedLine();
718 break;
719 }
720 parseStructuralElement();
721 } while (!eof());
722}
723
Nico Weber50767d82013-01-09 23:25:37 +0000724void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
Nico Weber27d13672013-01-09 20:25:35 +0000725 nextToken();
Daniel Jasperf9955d32013-03-20 12:37:50 +0000726 nextToken(); // interface name
Nico Weber27d13672013-01-09 20:25:35 +0000727
728 // @interface can be followed by either a base class, or a category.
729 if (FormatTok.Tok.is(tok::colon)) {
730 nextToken();
Daniel Jasperf9955d32013-03-20 12:37:50 +0000731 nextToken(); // base class name
Nico Weber27d13672013-01-09 20:25:35 +0000732 } else if (FormatTok.Tok.is(tok::l_paren))
733 // Skip category, if present.
734 parseParens();
735
Nico Weber1abe6ea2013-01-09 21:15:03 +0000736 if (FormatTok.Tok.is(tok::less))
737 parseObjCProtocolList();
Nico Weber27d13672013-01-09 20:25:35 +0000738
739 // If instance variables are present, keep the '{' on the first line too.
740 if (FormatTok.Tok.is(tok::l_brace))
Manuel Klimek70b03f42013-01-23 09:32:48 +0000741 parseBlock(/*MustBeDeclaration=*/ true);
Nico Weber27d13672013-01-09 20:25:35 +0000742
743 // With instance variables, this puts '}' on its own line. Without instance
744 // variables, this ends the @interface line.
745 addUnwrappedLine();
746
Nico Weber1abe6ea2013-01-09 21:15:03 +0000747 parseObjCUntilAtEnd();
748}
Nico Weber27d13672013-01-09 20:25:35 +0000749
Nico Weber1abe6ea2013-01-09 21:15:03 +0000750void UnwrappedLineParser::parseObjCProtocol() {
751 nextToken();
Daniel Jasperf9955d32013-03-20 12:37:50 +0000752 nextToken(); // protocol name
Nico Weber1abe6ea2013-01-09 21:15:03 +0000753
754 if (FormatTok.Tok.is(tok::less))
755 parseObjCProtocolList();
756
757 // Check for protocol declaration.
758 if (FormatTok.Tok.is(tok::semi)) {
759 nextToken();
760 return addUnwrappedLine();
761 }
762
763 addUnwrappedLine();
764 parseObjCUntilAtEnd();
Nico Weber27d13672013-01-09 20:25:35 +0000765}
766
Daniel Jasperbac016b2012-12-03 18:12:45 +0000767void UnwrappedLineParser::addUnwrappedLine() {
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000768 if (Line->Tokens.empty())
Daniel Jasper26f7e782013-01-08 14:56:18 +0000769 return;
Manuel Klimek8fa37992013-01-16 12:31:12 +0000770 DEBUG({
Manuel Klimeka28fc062013-02-11 12:33:24 +0000771 llvm::dbgs() << "Line(" << Line->Level << ")"
772 << (Line->InPPDirective ? " MACRO" : "") << ": ";
Manuel Klimek8fa37992013-01-16 12:31:12 +0000773 for (std::list<FormatToken>::iterator I = Line->Tokens.begin(),
774 E = Line->Tokens.end();
775 I != E; ++I) {
776 llvm::dbgs() << I->Tok.getName() << " ";
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000777
Manuel Klimek8fa37992013-01-16 12:31:12 +0000778 }
779 llvm::dbgs() << "\n";
780 });
Manuel Klimek525fe162013-01-18 14:04:34 +0000781 CurrentLines->push_back(*Line);
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000782 Line->Tokens.clear();
Manuel Klimek525fe162013-01-18 14:04:34 +0000783 if (CurrentLines == &Lines && !PreprocessorDirectives.empty()) {
Daniel Jasper516fb312013-03-01 18:11:39 +0000784 for (std::vector<UnwrappedLine>::iterator
785 I = PreprocessorDirectives.begin(),
786 E = PreprocessorDirectives.end();
Manuel Klimek525fe162013-01-18 14:04:34 +0000787 I != E; ++I) {
788 CurrentLines->push_back(*I);
789 }
790 PreprocessorDirectives.clear();
791 }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000792}
793
Daniel Jasperf9955d32013-03-20 12:37:50 +0000794bool UnwrappedLineParser::eof() const { return FormatTok.Tok.is(tok::eof); }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000795
Manuel Klimek86721d22013-01-22 16:31:55 +0000796void UnwrappedLineParser::flushComments(bool NewlineBeforeNext) {
797 bool JustComments = Line->Tokens.empty();
798 for (SmallVectorImpl<FormatToken>::const_iterator
799 I = CommentsBeforeNextToken.begin(),
800 E = CommentsBeforeNextToken.end();
801 I != E; ++I) {
Manuel Klimekb3507cd2013-02-06 16:40:56 +0000802 if (I->NewlinesBefore && JustComments) {
Manuel Klimek86721d22013-01-22 16:31:55 +0000803 addUnwrappedLine();
804 }
805 pushToken(*I);
806 }
807 if (NewlineBeforeNext && JustComments) {
808 addUnwrappedLine();
809 }
810 CommentsBeforeNextToken.clear();
811}
812
Daniel Jasperbac016b2012-12-03 18:12:45 +0000813void UnwrappedLineParser::nextToken() {
814 if (eof())
815 return;
Manuel Klimekb3507cd2013-02-06 16:40:56 +0000816 flushComments(FormatTok.NewlinesBefore > 0);
Manuel Klimek86721d22013-01-22 16:31:55 +0000817 pushToken(FormatTok);
Manuel Klimekd4397b92013-01-04 23:34:14 +0000818 readToken();
819}
820
821void UnwrappedLineParser::readToken() {
Manuel Klimek86721d22013-01-22 16:31:55 +0000822 bool CommentsInCurrentLine = true;
823 do {
824 FormatTok = Tokens->getNextToken();
825 while (!Line->InPPDirective && FormatTok.Tok.is(tok::hash) &&
826 ((FormatTok.NewlinesBefore > 0 && FormatTok.HasUnescapedNewline) ||
827 FormatTok.IsFirst)) {
828 // If there is an unfinished unwrapped line, we flush the preprocessor
829 // directives only after that unwrapped line was finished later.
Daniel Jasperf9955d32013-03-20 12:37:50 +0000830 bool SwitchToPreprocessorLines =
831 !Line->Tokens.empty() && CurrentLines == &Lines;
Manuel Klimek86721d22013-01-22 16:31:55 +0000832 ScopedLineState BlockState(*this, SwitchToPreprocessorLines);
833 parsePPDirective();
834 }
835 if (!FormatTok.Tok.is(tok::comment))
836 return;
Manuel Klimekb3507cd2013-02-06 16:40:56 +0000837 if (FormatTok.NewlinesBefore > 0 || FormatTok.IsFirst) {
Manuel Klimek86721d22013-01-22 16:31:55 +0000838 CommentsInCurrentLine = false;
839 }
840 if (CommentsInCurrentLine) {
841 pushToken(FormatTok);
842 } else {
843 CommentsBeforeNextToken.push_back(FormatTok);
844 }
845 } while (!eof());
846}
847
848void UnwrappedLineParser::pushToken(const FormatToken &Tok) {
849 Line->Tokens.push_back(Tok);
850 if (MustBreakBeforeNextToken) {
851 Line->Tokens.back().MustBreakBefore = true;
852 MustBreakBeforeNextToken = false;
Manuel Klimekd4397b92013-01-04 23:34:14 +0000853 }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000854}
855
Daniel Jaspercd162382013-01-07 13:26:07 +0000856} // end namespace format
857} // end namespace clang