blob: 4138bb98aed99539dc27498a601ea636de64a926 [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 "llvm/Support/Debug.h"
Manuel Klimek8fa37992013-01-16 12:31:12 +000020
Daniel Jasperbac016b2012-12-03 18:12:45 +000021namespace clang {
22namespace format {
23
Manuel Klimek70b03f42013-01-23 09:32:48 +000024class ScopedDeclarationState {
25public:
26 ScopedDeclarationState(UnwrappedLine &Line, std::vector<bool> &Stack,
27 bool MustBeDeclaration)
28 : Line(Line), Stack(Stack) {
Manuel Klimek70b03f42013-01-23 09:32:48 +000029 Line.MustBeDeclaration = MustBeDeclaration;
Manuel Klimek836b58f2013-01-23 11:03:04 +000030 Stack.push_back(MustBeDeclaration);
Manuel Klimek70b03f42013-01-23 09:32:48 +000031 }
32 ~ScopedDeclarationState() {
Manuel Klimek70b03f42013-01-23 09:32:48 +000033 Stack.pop_back();
Manuel Klimeka32a7fd2013-01-23 14:08:21 +000034 if (!Stack.empty())
35 Line.MustBeDeclaration = Stack.back();
36 else
37 Line.MustBeDeclaration = true;
Manuel Klimek70b03f42013-01-23 09:32:48 +000038 }
39private:
40 UnwrappedLine &Line;
41 std::vector<bool> &Stack;
42};
43
Manuel Klimekd4397b92013-01-04 23:34:14 +000044class ScopedMacroState : public FormatTokenSource {
45public:
46 ScopedMacroState(UnwrappedLine &Line, FormatTokenSource *&TokenSource,
Manuel Klimek67d080d2013-04-12 14:13:36 +000047 FormatToken &ResetToken, bool &StructuralError)
Manuel Klimekd4397b92013-01-04 23:34:14 +000048 : Line(Line), TokenSource(TokenSource), ResetToken(ResetToken),
Manuel Klimek67d080d2013-04-12 14:13:36 +000049 PreviousLineLevel(Line.Level), PreviousTokenSource(TokenSource),
50 StructuralError(StructuralError),
51 PreviousStructuralError(StructuralError) {
Manuel Klimekd4397b92013-01-04 23:34:14 +000052 TokenSource = this;
Manuel Klimekc37b4d62013-01-05 22:14:16 +000053 Line.Level = 0;
Manuel Klimekd4397b92013-01-04 23:34:14 +000054 Line.InPPDirective = true;
55 }
56
57 ~ScopedMacroState() {
58 TokenSource = PreviousTokenSource;
59 ResetToken = Token;
60 Line.InPPDirective = false;
Manuel Klimekc37b4d62013-01-05 22:14:16 +000061 Line.Level = PreviousLineLevel;
Manuel Klimek67d080d2013-04-12 14:13:36 +000062 StructuralError = PreviousStructuralError;
Manuel Klimekd4397b92013-01-04 23:34:14 +000063 }
64
65 virtual FormatToken getNextToken() {
Manuel Klimekdd5b1012013-01-07 10:03:37 +000066 // The \c UnwrappedLineParser guards against this by never calling
67 // \c getNextToken() after it has encountered the first eof token.
68 assert(!eof());
Manuel Klimekd4397b92013-01-04 23:34:14 +000069 Token = PreviousTokenSource->getNextToken();
70 if (eof())
71 return createEOF();
72 return Token;
73 }
74
75private:
Alexander Kornienko3d713a72013-04-08 22:16:06 +000076 bool eof() { return Token.HasUnescapedNewline; }
Manuel Klimekd4397b92013-01-04 23:34:14 +000077
78 FormatToken createEOF() {
79 FormatToken FormatTok;
80 FormatTok.Tok.startToken();
81 FormatTok.Tok.setKind(tok::eof);
82 return FormatTok;
83 }
84
85 UnwrappedLine &Line;
86 FormatTokenSource *&TokenSource;
87 FormatToken &ResetToken;
Manuel Klimekc37b4d62013-01-05 22:14:16 +000088 unsigned PreviousLineLevel;
Manuel Klimekd4397b92013-01-04 23:34:14 +000089 FormatTokenSource *PreviousTokenSource;
Manuel Klimek67d080d2013-04-12 14:13:36 +000090 bool &StructuralError;
91 bool PreviousStructuralError;
Manuel Klimekd4397b92013-01-04 23:34:14 +000092
93 FormatToken Token;
94};
95
Manuel Klimekbb42bf12013-01-10 11:52:21 +000096class ScopedLineState {
97public:
Manuel Klimek525fe162013-01-18 14:04:34 +000098 ScopedLineState(UnwrappedLineParser &Parser,
99 bool SwitchToPreprocessorLines = false)
100 : Parser(Parser), SwitchToPreprocessorLines(SwitchToPreprocessorLines) {
101 if (SwitchToPreprocessorLines)
102 Parser.CurrentLines = &Parser.PreprocessorDirectives;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000103 PreBlockLine = Parser.Line.take();
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000104 Parser.Line.reset(new UnwrappedLine());
105 Parser.Line->Level = PreBlockLine->Level;
106 Parser.Line->InPPDirective = PreBlockLine->InPPDirective;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000107 }
108
109 ~ScopedLineState() {
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000110 if (!Parser.Line->Tokens.empty()) {
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000111 Parser.addUnwrappedLine();
112 }
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000113 assert(Parser.Line->Tokens.empty());
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000114 Parser.Line.reset(PreBlockLine);
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000115 Parser.MustBreakBeforeNextToken = true;
Manuel Klimek525fe162013-01-18 14:04:34 +0000116 if (SwitchToPreprocessorLines)
117 Parser.CurrentLines = &Parser.Lines;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000118 }
119
120private:
121 UnwrappedLineParser &Parser;
Manuel Klimek525fe162013-01-18 14:04:34 +0000122 const bool SwitchToPreprocessorLines;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000123
124 UnwrappedLine *PreBlockLine;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000125};
126
Daniel Jaspercaf42a32013-05-15 08:14:19 +0000127UnwrappedLineParser::UnwrappedLineParser(const FormatStyle &Style,
128 FormatTokenSource &Tokens,
129 UnwrappedLineConsumer &Callback)
Manuel Klimek525fe162013-01-18 14:04:34 +0000130 : Line(new UnwrappedLine), MustBreakBeforeNextToken(false),
Daniel Jaspercaf42a32013-05-15 08:14:19 +0000131 CurrentLines(&Lines), StructuralError(false), Style(Style),
Manuel Klimek67d080d2013-04-12 14:13:36 +0000132 Tokens(&Tokens), Callback(Callback) {}
Daniel Jasperbac016b2012-12-03 18:12:45 +0000133
Alexander Kornienkocff563c2012-12-04 17:27:50 +0000134bool UnwrappedLineParser::parse() {
Manuel Klimek8fa37992013-01-16 12:31:12 +0000135 DEBUG(llvm::dbgs() << "----\n");
Manuel Klimekd4397b92013-01-04 23:34:14 +0000136 readToken();
Manuel Klimek67d080d2013-04-12 14:13:36 +0000137 parseFile();
Daniel Jasperf9955d32013-03-20 12:37:50 +0000138 for (std::vector<UnwrappedLine>::iterator I = Lines.begin(), E = Lines.end();
Manuel Klimek525fe162013-01-18 14:04:34 +0000139 I != E; ++I) {
140 Callback.consumeUnwrappedLine(*I);
141 }
Daniel Jasper516fb312013-03-01 18:11:39 +0000142
143 // Create line with eof token.
144 pushToken(FormatTok);
145 Callback.consumeUnwrappedLine(*Line);
Manuel Klimek67d080d2013-04-12 14:13:36 +0000146 return StructuralError;
Manuel Klimekd4397b92013-01-04 23:34:14 +0000147}
148
Manuel Klimek67d080d2013-04-12 14:13:36 +0000149void UnwrappedLineParser::parseFile() {
Daniel Jasper627707b2013-03-22 16:55:40 +0000150 ScopedDeclarationState DeclarationState(
151 *Line, DeclarationScopeStack,
152 /*MustBeDeclaration=*/ !Line->InPPDirective);
Manuel Klimek67d080d2013-04-12 14:13:36 +0000153 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();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000157}
158
Manuel Klimek67d080d2013-04-12 14:13:36 +0000159void UnwrappedLineParser::parseLevel(bool HasOpeningBrace) {
Daniel Jasperbac016b2012-12-03 18:12:45 +0000160 do {
161 switch (FormatTok.Tok.getKind()) {
Daniel Jasperbac016b2012-12-03 18:12:45 +0000162 case tok::comment:
Daniel Jasper05b1ac82012-12-17 11:29:41 +0000163 nextToken();
164 addUnwrappedLine();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000165 break;
166 case tok::l_brace:
Manuel Klimek70b03f42013-01-23 09:32:48 +0000167 // FIXME: Add parameter whether this can happen - if this happens, we must
168 // be in a non-declaration context.
Manuel Klimek67d080d2013-04-12 14:13:36 +0000169 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000170 addUnwrappedLine();
171 break;
172 case tok::r_brace:
Manuel Klimek67d080d2013-04-12 14:13:36 +0000173 if (HasOpeningBrace)
174 return;
Manuel Klimek67d080d2013-04-12 14:13:36 +0000175 StructuralError = true;
176 nextToken();
177 addUnwrappedLine();
Manuel Klimeka5342db2013-01-06 20:07:31 +0000178 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000179 default:
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000180 parseStructuralElement();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000181 break;
182 }
183 } while (!eof());
184}
185
Manuel Klimek67d080d2013-04-12 14:13:36 +0000186void UnwrappedLineParser::parseBlock(bool MustBeDeclaration,
Nico Weberd74fcdb2013-02-10 20:35:35 +0000187 unsigned AddLevels) {
Alexander Kornienkoa3a2b3a2012-12-06 17:49:17 +0000188 assert(FormatTok.Tok.is(tok::l_brace) && "'{' expected");
Daniel Jasperbac016b2012-12-03 18:12:45 +0000189 nextToken();
190
Manuel Klimek2f1ac412013-01-21 16:42:44 +0000191 addUnwrappedLine();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000192
Manuel Klimek70b03f42013-01-23 09:32:48 +0000193 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
194 MustBeDeclaration);
Manuel Klimek2f1ac412013-01-21 16:42:44 +0000195 Line->Level += AddLevels;
Daniel Jasperf9955d32013-03-20 12:37:50 +0000196 parseLevel(/*HasOpeningBrace=*/ true);
Alexander Kornienko15757312012-12-06 18:03:27 +0000197
Manuel Klimek86721d22013-01-22 16:31:55 +0000198 if (!FormatTok.Tok.is(tok::r_brace)) {
199 Line->Level -= AddLevels;
Manuel Klimek67d080d2013-04-12 14:13:36 +0000200 StructuralError = true;
201 return;
Manuel Klimek86721d22013-01-22 16:31:55 +0000202 }
Alexander Kornienko393b0082012-12-04 15:40:36 +0000203
Daniel Jasperf9955d32013-03-20 12:37:50 +0000204 nextToken(); // Munch the closing brace.
Manuel Klimek86721d22013-01-22 16:31:55 +0000205 Line->Level -= AddLevels;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000206}
207
208void UnwrappedLineParser::parsePPDirective() {
Manuel Klimeka080a182013-01-02 16:30:12 +0000209 assert(FormatTok.Tok.is(tok::hash) && "'#' expected");
Manuel Klimek67d080d2013-04-12 14:13:36 +0000210 ScopedMacroState MacroState(*Line, Tokens, FormatTok, StructuralError);
Manuel Klimeka080a182013-01-02 16:30:12 +0000211 nextToken();
212
Manuel Klimeka080a182013-01-02 16:30:12 +0000213 if (FormatTok.Tok.getIdentifierInfo() == NULL) {
Manuel Klimekbd04f2a2013-01-31 15:58:48 +0000214 parsePPUnknown();
Manuel Klimeka080a182013-01-02 16:30:12 +0000215 return;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000216 }
Manuel Klimeka080a182013-01-02 16:30:12 +0000217
Manuel Klimekd4397b92013-01-04 23:34:14 +0000218 switch (FormatTok.Tok.getIdentifierInfo()->getPPKeywordID()) {
219 case tok::pp_define:
220 parsePPDefine();
221 break;
222 default:
223 parsePPUnknown();
224 break;
225 }
226}
227
228void UnwrappedLineParser::parsePPDefine() {
229 nextToken();
230
231 if (FormatTok.Tok.getKind() != tok::identifier) {
232 parsePPUnknown();
233 return;
234 }
235 nextToken();
Manuel Klimek7ccbc212013-01-23 14:37:36 +0000236 if (FormatTok.Tok.getKind() == tok::l_paren &&
237 FormatTok.WhiteSpaceLength == 0) {
Manuel Klimekd4397b92013-01-04 23:34:14 +0000238 parseParens();
239 }
240 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000241 Line->Level = 1;
Manuel Klimekc3d0c822013-01-07 09:34:28 +0000242
243 // Errors during a preprocessor directive can only affect the layout of the
244 // preprocessor directive, and thus we ignore them. An alternative approach
245 // would be to use the same approach we use on the file level (no
246 // re-indentation if there was a structural error) within the macro
247 // definition.
Manuel Klimekd4397b92013-01-04 23:34:14 +0000248 parseFile();
249}
250
251void UnwrappedLineParser::parsePPUnknown() {
Manuel Klimeka080a182013-01-02 16:30:12 +0000252 do {
Manuel Klimeka080a182013-01-02 16:30:12 +0000253 nextToken();
254 } while (!eof());
255 addUnwrappedLine();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000256}
257
Alexander Kornienko99b0e142013-04-09 16:15:19 +0000258// Here we blacklist certain tokens that are not usually the first token in an
259// unwrapped line. This is used in attempt to distinguish macro calls without
260// trailing semicolons from other constructs split to several lines.
261bool tokenCanStartNewLine(clang::Token Tok) {
262 // Semicolon can be a null-statement, l_square can be a start of a macro or
263 // a C++11 attribute, but this doesn't seem to be common.
264 return Tok.isNot(tok::semi) && Tok.isNot(tok::l_brace) &&
265 Tok.isNot(tok::l_square) &&
266 // Tokens that can only be used as binary operators and a part of
267 // overloaded operator names.
268 Tok.isNot(tok::period) && Tok.isNot(tok::periodstar) &&
269 Tok.isNot(tok::arrow) && Tok.isNot(tok::arrowstar) &&
270 Tok.isNot(tok::less) && Tok.isNot(tok::greater) &&
271 Tok.isNot(tok::slash) && Tok.isNot(tok::percent) &&
272 Tok.isNot(tok::lessless) && Tok.isNot(tok::greatergreater) &&
273 Tok.isNot(tok::equal) && Tok.isNot(tok::plusequal) &&
274 Tok.isNot(tok::minusequal) && Tok.isNot(tok::starequal) &&
275 Tok.isNot(tok::slashequal) && Tok.isNot(tok::percentequal) &&
276 Tok.isNot(tok::ampequal) && Tok.isNot(tok::pipeequal) &&
277 Tok.isNot(tok::caretequal) && Tok.isNot(tok::greatergreaterequal) &&
278 Tok.isNot(tok::lesslessequal) &&
279 // Colon is used in labels, base class lists, initializer lists,
280 // range-based for loops, ternary operator, but should never be the
281 // first token in an unwrapped line.
282 Tok.isNot(tok::colon);
283}
284
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000285void UnwrappedLineParser::parseStructuralElement() {
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000286 assert(!FormatTok.Tok.is(tok::l_brace));
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000287 switch (FormatTok.Tok.getKind()) {
Nico Weber6092d4e2013-01-07 19:05:19 +0000288 case tok::at:
289 nextToken();
Nico Weberd74fcdb2013-02-10 20:35:35 +0000290 if (FormatTok.Tok.is(tok::l_brace)) {
291 parseBracedList();
292 break;
293 }
Nico Weber6092d4e2013-01-07 19:05:19 +0000294 switch (FormatTok.Tok.getObjCKeywordID()) {
295 case tok::objc_public:
296 case tok::objc_protected:
297 case tok::objc_package:
298 case tok::objc_private:
299 return parseAccessSpecifier();
Nico Weber27d13672013-01-09 20:25:35 +0000300 case tok::objc_interface:
Nico Weber50767d82013-01-09 23:25:37 +0000301 case tok::objc_implementation:
302 return parseObjCInterfaceOrImplementation();
Nico Weber1abe6ea2013-01-09 21:15:03 +0000303 case tok::objc_protocol:
304 return parseObjCProtocol();
Nico Weber049c4472013-01-09 21:42:32 +0000305 case tok::objc_end:
306 return; // Handled by the caller.
Nico Weberb530fa32013-01-10 00:25:19 +0000307 case tok::objc_optional:
308 case tok::objc_required:
309 nextToken();
310 addUnwrappedLine();
311 return;
Nico Weber6092d4e2013-01-07 19:05:19 +0000312 default:
313 break;
314 }
315 break;
Alexander Kornienko15757312012-12-06 18:03:27 +0000316 case tok::kw_namespace:
317 parseNamespace();
318 return;
Dmitri Gribenko1f94f2b2012-12-30 21:27:25 +0000319 case tok::kw_inline:
320 nextToken();
Dmitri Gribenko1f94f2b2012-12-30 21:27:25 +0000321 if (FormatTok.Tok.is(tok::kw_namespace)) {
322 parseNamespace();
323 return;
324 }
325 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000326 case tok::kw_public:
327 case tok::kw_protected:
328 case tok::kw_private:
Daniel Jasperbac016b2012-12-03 18:12:45 +0000329 parseAccessSpecifier();
330 return;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000331 case tok::kw_if:
332 parseIfThenElse();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000333 return;
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000334 case tok::kw_for:
335 case tok::kw_while:
336 parseForOrWhileLoop();
337 return;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000338 case tok::kw_do:
339 parseDoWhile();
340 return;
341 case tok::kw_switch:
342 parseSwitch();
343 return;
344 case tok::kw_default:
345 nextToken();
346 parseLabel();
347 return;
348 case tok::kw_case:
349 parseCaseLabel();
350 return;
Manuel Klimekc44ee892013-01-21 10:07:49 +0000351 case tok::kw_return:
352 parseReturn();
353 return;
Manuel Klimekd19dc2d2013-01-21 14:32:05 +0000354 case tok::kw_extern:
355 nextToken();
356 if (FormatTok.Tok.is(tok::string_literal)) {
357 nextToken();
358 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000359 parseBlock(/*MustBeDeclaration=*/ true, 0);
Manuel Klimekd19dc2d2013-01-21 14:32:05 +0000360 addUnwrappedLine();
361 return;
362 }
363 }
364 // In all other cases, parse the declaration.
365 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000366 default:
367 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000368 }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000369 do {
Daniel Jasperbac016b2012-12-03 18:12:45 +0000370 switch (FormatTok.Tok.getKind()) {
Nico Weberd74fcdb2013-02-10 20:35:35 +0000371 case tok::at:
372 nextToken();
373 if (FormatTok.Tok.is(tok::l_brace))
374 parseBracedList();
375 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000376 case tok::kw_enum:
377 parseEnum();
Manuel Klimek308232c2013-01-21 19:17:52 +0000378 break;
Alexander Kornienkod8818752013-01-16 11:43:46 +0000379 case tok::kw_struct:
380 case tok::kw_union:
Manuel Klimekde768542013-01-07 18:10:23 +0000381 case tok::kw_class:
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000382 parseRecord();
383 // A record declaration or definition is always the start of a structural
384 // element.
385 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000386 case tok::semi:
387 nextToken();
388 addUnwrappedLine();
389 return;
Alexander Kornienkod8818752013-01-16 11:43:46 +0000390 case tok::r_brace:
391 addUnwrappedLine();
392 return;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000393 case tok::l_paren:
394 parseParens();
395 break;
396 case tok::l_brace:
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000397 // A block outside of parentheses must be the last part of a
398 // structural element.
399 // FIXME: Figure out cases where this is not true, and add projections for
400 // them (the one we know is missing are lambdas).
Manuel Klimek44135b82013-05-13 12:51:40 +0000401 if (Style.BreakBeforeBraces == FormatStyle::BS_Linux ||
402 Style.BreakBeforeBraces == FormatStyle::BS_Stroustrup)
403 addUnwrappedLine();
404
Manuel Klimek70b03f42013-01-23 09:32:48 +0000405 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000406 addUnwrappedLine();
407 return;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000408 case tok::identifier:
Daniel Jasperbac016b2012-12-03 18:12:45 +0000409 nextToken();
Alexander Kornienko3d713a72013-04-08 22:16:06 +0000410 if (Line->Tokens.size() == 1) {
411 if (FormatTok.Tok.is(tok::colon)) {
412 parseLabel();
413 return;
414 }
Alexander Kornienko99b0e142013-04-09 16:15:19 +0000415 // Recognize function-like macro usages without trailing semicolon.
Alexander Kornienko3d713a72013-04-08 22:16:06 +0000416 if (FormatTok.Tok.is(tok::l_paren)) {
417 parseParens();
Alexander Kornienko99b0e142013-04-09 16:15:19 +0000418 if (FormatTok.HasUnescapedNewline &&
419 tokenCanStartNewLine(FormatTok.Tok)) {
Alexander Kornienko3d713a72013-04-08 22:16:06 +0000420 addUnwrappedLine();
421 return;
422 }
423 }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000424 }
425 break;
Daniel Jasper05b1ac82012-12-17 11:29:41 +0000426 case tok::equal:
427 nextToken();
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000428 if (FormatTok.Tok.is(tok::l_brace)) {
429 parseBracedList();
430 }
Daniel Jasper05b1ac82012-12-17 11:29:41 +0000431 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000432 default:
433 nextToken();
434 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000435 }
436 } while (!eof());
437}
438
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000439void UnwrappedLineParser::parseBracedList() {
440 nextToken();
441
Manuel Klimek423dd932013-04-10 09:52:05 +0000442 // FIXME: Once we have an expression parser in the UnwrappedLineParser,
443 // replace this by using parseAssigmentExpression() inside.
444 bool StartOfExpression = true;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000445 do {
Manuel Klimek423dd932013-04-10 09:52:05 +0000446 // FIXME: When we start to support lambdas, we'll want to parse them away
447 // here, otherwise our bail-out scenarios below break. The better solution
448 // might be to just implement a more or less complete expression parser.
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000449 switch (FormatTok.Tok.getKind()) {
450 case tok::l_brace:
Manuel Klimek423dd932013-04-10 09:52:05 +0000451 if (!StartOfExpression) {
452 // Probably a missing closing brace. Bail out.
453 addUnwrappedLine();
454 return;
455 }
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000456 parseBracedList();
Manuel Klimek423dd932013-04-10 09:52:05 +0000457 StartOfExpression = false;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000458 break;
459 case tok::r_brace:
460 nextToken();
461 return;
Manuel Klimek423dd932013-04-10 09:52:05 +0000462 case tok::semi:
463 // Probably a missing closing brace. Bail out.
464 return;
465 case tok::comma:
466 nextToken();
467 StartOfExpression = true;
468 break;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000469 default:
470 nextToken();
Manuel Klimek423dd932013-04-10 09:52:05 +0000471 StartOfExpression = false;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000472 break;
473 }
474 } while (!eof());
475}
476
Manuel Klimekc44ee892013-01-21 10:07:49 +0000477void UnwrappedLineParser::parseReturn() {
478 nextToken();
479
480 do {
481 switch (FormatTok.Tok.getKind()) {
482 case tok::l_brace:
483 parseBracedList();
Manuel Klimek423dd932013-04-10 09:52:05 +0000484 if (FormatTok.Tok.isNot(tok::semi)) {
485 // Assume missing ';'.
486 addUnwrappedLine();
487 return;
488 }
Manuel Klimekc44ee892013-01-21 10:07:49 +0000489 break;
490 case tok::l_paren:
491 parseParens();
492 break;
493 case tok::r_brace:
494 // Assume missing ';'.
495 addUnwrappedLine();
496 return;
497 case tok::semi:
498 nextToken();
499 addUnwrappedLine();
500 return;
501 default:
502 nextToken();
503 break;
504 }
505 } while (!eof());
506}
507
Daniel Jasperbac016b2012-12-03 18:12:45 +0000508void UnwrappedLineParser::parseParens() {
509 assert(FormatTok.Tok.is(tok::l_paren) && "'(' expected.");
510 nextToken();
511 do {
512 switch (FormatTok.Tok.getKind()) {
513 case tok::l_paren:
514 parseParens();
515 break;
516 case tok::r_paren:
517 nextToken();
518 return;
Nico Weber2afbe522013-02-10 04:38:23 +0000519 case tok::l_brace: {
520 nextToken();
521 ScopedLineState LineState(*this);
522 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
523 /*MustBeDeclaration=*/ false);
524 Line->Level += 1;
525 parseLevel(/*HasOpeningBrace=*/ true);
526 Line->Level -= 1;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000527 break;
Nico Weber2afbe522013-02-10 04:38:23 +0000528 }
Nico Weberd74fcdb2013-02-10 20:35:35 +0000529 case tok::at:
530 nextToken();
531 if (FormatTok.Tok.is(tok::l_brace))
532 parseBracedList();
533 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000534 default:
535 nextToken();
536 break;
537 }
538 } while (!eof());
539}
540
541void UnwrappedLineParser::parseIfThenElse() {
542 assert(FormatTok.Tok.is(tok::kw_if) && "'if' expected");
543 nextToken();
Manuel Klimekd4658432013-01-11 18:28:36 +0000544 if (FormatTok.Tok.is(tok::l_paren))
545 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000546 bool NeedsUnwrappedLine = false;
547 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000548 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000549 NeedsUnwrappedLine = true;
550 } else {
551 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000552 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000553 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000554 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000555 }
556 if (FormatTok.Tok.is(tok::kw_else)) {
557 nextToken();
558 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000559 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000560 addUnwrappedLine();
561 } else if (FormatTok.Tok.is(tok::kw_if)) {
562 parseIfThenElse();
563 } else {
564 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000565 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000566 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000567 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000568 }
569 } else if (NeedsUnwrappedLine) {
570 addUnwrappedLine();
571 }
572}
573
Alexander Kornienko15757312012-12-06 18:03:27 +0000574void UnwrappedLineParser::parseNamespace() {
575 assert(FormatTok.Tok.is(tok::kw_namespace) && "'namespace' expected");
576 nextToken();
577 if (FormatTok.Tok.is(tok::identifier))
578 nextToken();
579 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek44135b82013-05-13 12:51:40 +0000580 if (Style.BreakBeforeBraces == FormatStyle::BS_Linux)
581 addUnwrappedLine();
582
Manuel Klimek70b03f42013-01-23 09:32:48 +0000583 parseBlock(/*MustBeDeclaration=*/ true, 0);
Manuel Klimek7fc2db02013-02-06 16:08:09 +0000584 // Munch the semicolon after a namespace. This is more common than one would
585 // think. Puttin the semicolon into its own line is very ugly.
586 if (FormatTok.Tok.is(tok::semi))
587 nextToken();
Alexander Kornienko15757312012-12-06 18:03:27 +0000588 addUnwrappedLine();
589 }
590 // FIXME: Add error handling.
591}
592
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000593void UnwrappedLineParser::parseForOrWhileLoop() {
594 assert((FormatTok.Tok.is(tok::kw_for) || FormatTok.Tok.is(tok::kw_while)) &&
595 "'for' or 'while' expected");
596 nextToken();
Manuel Klimek6eca03f2013-01-11 19:23:05 +0000597 if (FormatTok.Tok.is(tok::l_paren))
598 parseParens();
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000599 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000600 parseBlock(/*MustBeDeclaration=*/ false);
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000601 addUnwrappedLine();
602 } else {
603 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000604 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000605 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000606 --Line->Level;
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000607 }
608}
609
Daniel Jasperbac016b2012-12-03 18:12:45 +0000610void UnwrappedLineParser::parseDoWhile() {
611 assert(FormatTok.Tok.is(tok::kw_do) && "'do' expected");
612 nextToken();
613 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000614 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000615 } else {
616 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000617 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000618 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000619 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000620 }
621
Alexander Kornienko393b0082012-12-04 15:40:36 +0000622 // FIXME: Add error handling.
623 if (!FormatTok.Tok.is(tok::kw_while)) {
624 addUnwrappedLine();
625 return;
626 }
627
Daniel Jasperbac016b2012-12-03 18:12:45 +0000628 nextToken();
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000629 parseStructuralElement();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000630}
631
632void UnwrappedLineParser::parseLabel() {
Daniel Jasper89a0daa2013-02-12 20:17:17 +0000633 if (FormatTok.Tok.isNot(tok::colon))
634 return;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000635 nextToken();
Manuel Klimek526ed112013-01-09 15:25:02 +0000636 unsigned OldLineLevel = Line->Level;
Daniel Jasperbcca7e42013-03-20 10:23:53 +0000637 if (Line->Level > 1 || (!Line->InPPDirective && Line->Level > 0))
Manuel Klimek526ed112013-01-09 15:25:02 +0000638 --Line->Level;
Daniel Jasperc30eb512013-03-19 18:33:58 +0000639 if (CommentsBeforeNextToken.empty() && FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000640 parseBlock(/*MustBeDeclaration=*/ false);
Nico Weber94fb7292013-01-18 05:50:57 +0000641 if (FormatTok.Tok.is(tok::kw_break))
642 parseStructuralElement(); // "break;" after "}" goes on the same line.
Daniel Jasperbac016b2012-12-03 18:12:45 +0000643 }
644 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000645 Line->Level = OldLineLevel;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000646}
647
648void UnwrappedLineParser::parseCaseLabel() {
649 assert(FormatTok.Tok.is(tok::kw_case) && "'case' expected");
650 // FIXME: fix handling of complex expressions here.
651 do {
652 nextToken();
653 } while (!eof() && !FormatTok.Tok.is(tok::colon));
654 parseLabel();
655}
656
657void UnwrappedLineParser::parseSwitch() {
658 assert(FormatTok.Tok.is(tok::kw_switch) && "'switch' expected");
659 nextToken();
Manuel Klimek6eca03f2013-01-11 19:23:05 +0000660 if (FormatTok.Tok.is(tok::l_paren))
661 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000662 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000663 parseBlock(/*MustBeDeclaration=*/ false, Style.IndentCaseLabels ? 2 : 1);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000664 addUnwrappedLine();
665 } else {
666 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000667 Line->Level += (Style.IndentCaseLabels ? 2 : 1);
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000668 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000669 Line->Level -= (Style.IndentCaseLabels ? 2 : 1);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000670 }
671}
672
673void UnwrappedLineParser::parseAccessSpecifier() {
674 nextToken();
Alexander Kornienko56e49c52012-12-10 16:34:48 +0000675 // Otherwise, we don't know what it is, and we'd better keep the next token.
676 if (FormatTok.Tok.is(tok::colon))
677 nextToken();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000678 addUnwrappedLine();
679}
680
681void UnwrappedLineParser::parseEnum() {
Manuel Klimek308232c2013-01-21 19:17:52 +0000682 nextToken();
683 if (FormatTok.Tok.is(tok::identifier) ||
684 FormatTok.Tok.is(tok::kw___attribute) ||
685 FormatTok.Tok.is(tok::kw___declspec)) {
686 nextToken();
687 // We can have macros or attributes in between 'enum' and the enum name.
688 if (FormatTok.Tok.is(tok::l_paren)) {
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000689 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000690 }
Manuel Klimek308232c2013-01-21 19:17:52 +0000691 if (FormatTok.Tok.is(tok::identifier))
692 nextToken();
693 }
694 if (FormatTok.Tok.is(tok::l_brace)) {
695 nextToken();
696 addUnwrappedLine();
697 ++Line->Level;
698 do {
699 switch (FormatTok.Tok.getKind()) {
Manuel Klimek308232c2013-01-21 19:17:52 +0000700 case tok::l_paren:
701 parseParens();
702 break;
703 case tok::r_brace:
704 addUnwrappedLine();
705 nextToken();
706 --Line->Level;
707 return;
708 case tok::comma:
709 nextToken();
710 addUnwrappedLine();
711 break;
712 default:
713 nextToken();
714 break;
715 }
716 } while (!eof());
717 }
718 // We fall through to parsing a structural element afterwards, so that in
719 // enum A {} n, m;
720 // "} n, m;" will end up in one unwrapped line.
Daniel Jasperbac016b2012-12-03 18:12:45 +0000721}
722
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000723void UnwrappedLineParser::parseRecord() {
Manuel Klimekde768542013-01-07 18:10:23 +0000724 nextToken();
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000725 if (FormatTok.Tok.is(tok::identifier) ||
726 FormatTok.Tok.is(tok::kw___attribute) ||
727 FormatTok.Tok.is(tok::kw___declspec)) {
728 nextToken();
729 // We can have macros or attributes in between 'class' and the class name.
730 if (FormatTok.Tok.is(tok::l_paren)) {
731 parseParens();
Manuel Klimekde768542013-01-07 18:10:23 +0000732 }
Manuel Klimekb8b1ce12013-02-06 15:57:54 +0000733 // The actual identifier can be a nested name specifier, and in macros
734 // it is often token-pasted.
Manuel Klimek7f5b0252013-01-21 10:17:14 +0000735 while (FormatTok.Tok.is(tok::identifier) ||
Daniel Jasperf9955d32013-03-20 12:37:50 +0000736 FormatTok.Tok.is(tok::coloncolon) || FormatTok.Tok.is(tok::hashhash))
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000737 nextToken();
738
Manuel Klimek3a3408c2013-01-21 13:58:54 +0000739 // Note that parsing away template declarations here leads to incorrectly
740 // accepting function declarations as record declarations.
741 // In general, we cannot solve this problem. Consider:
742 // class A<int> B() {}
743 // which can be a function definition or a class definition when B() is a
744 // macro. If we find enough real-world cases where this is a problem, we
745 // can parse for the 'template' keyword in the beginning of the statement,
746 // and thus rule out the record production in case there is no template
747 // (this would still leave us with an ambiguity between template function
748 // and class declarations).
749 if (FormatTok.Tok.is(tok::colon) || FormatTok.Tok.is(tok::less)) {
Daniel Jasper6fe554e2013-03-20 15:12:38 +0000750 while (!eof() && FormatTok.Tok.isNot(tok::l_brace)) {
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000751 if (FormatTok.Tok.is(tok::semi))
752 return;
753 nextToken();
754 }
755 }
756 }
Manuel Klimek44135b82013-05-13 12:51:40 +0000757 if (FormatTok.Tok.is(tok::l_brace)) {
758 if (Style.BreakBeforeBraces == FormatStyle::BS_Linux)
759 addUnwrappedLine();
760
Manuel Klimek70b03f42013-01-23 09:32:48 +0000761 parseBlock(/*MustBeDeclaration=*/ true);
Manuel Klimek44135b82013-05-13 12:51:40 +0000762 }
Manuel Klimek3a3408c2013-01-21 13:58:54 +0000763 // We fall through to parsing a structural element afterwards, so
764 // class A {} n, m;
765 // will end up in one unwrapped line.
Manuel Klimekde768542013-01-07 18:10:23 +0000766}
767
Nico Weber1abe6ea2013-01-09 21:15:03 +0000768void UnwrappedLineParser::parseObjCProtocolList() {
769 assert(FormatTok.Tok.is(tok::less) && "'<' expected.");
770 do
771 nextToken();
772 while (!eof() && FormatTok.Tok.isNot(tok::greater));
773 nextToken(); // Skip '>'.
774}
775
776void UnwrappedLineParser::parseObjCUntilAtEnd() {
777 do {
778 if (FormatTok.Tok.isObjCAtKeyword(tok::objc_end)) {
779 nextToken();
780 addUnwrappedLine();
781 break;
782 }
783 parseStructuralElement();
784 } while (!eof());
785}
786
Nico Weber50767d82013-01-09 23:25:37 +0000787void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
Nico Weber27d13672013-01-09 20:25:35 +0000788 nextToken();
Daniel Jasperf9955d32013-03-20 12:37:50 +0000789 nextToken(); // interface name
Nico Weber27d13672013-01-09 20:25:35 +0000790
791 // @interface can be followed by either a base class, or a category.
792 if (FormatTok.Tok.is(tok::colon)) {
793 nextToken();
Daniel Jasperf9955d32013-03-20 12:37:50 +0000794 nextToken(); // base class name
Nico Weber27d13672013-01-09 20:25:35 +0000795 } else if (FormatTok.Tok.is(tok::l_paren))
796 // Skip category, if present.
797 parseParens();
798
Nico Weber1abe6ea2013-01-09 21:15:03 +0000799 if (FormatTok.Tok.is(tok::less))
800 parseObjCProtocolList();
Nico Weber27d13672013-01-09 20:25:35 +0000801
802 // If instance variables are present, keep the '{' on the first line too.
803 if (FormatTok.Tok.is(tok::l_brace))
Manuel Klimek70b03f42013-01-23 09:32:48 +0000804 parseBlock(/*MustBeDeclaration=*/ true);
Nico Weber27d13672013-01-09 20:25:35 +0000805
806 // With instance variables, this puts '}' on its own line. Without instance
807 // variables, this ends the @interface line.
808 addUnwrappedLine();
809
Nico Weber1abe6ea2013-01-09 21:15:03 +0000810 parseObjCUntilAtEnd();
811}
Nico Weber27d13672013-01-09 20:25:35 +0000812
Nico Weber1abe6ea2013-01-09 21:15:03 +0000813void UnwrappedLineParser::parseObjCProtocol() {
814 nextToken();
Daniel Jasperf9955d32013-03-20 12:37:50 +0000815 nextToken(); // protocol name
Nico Weber1abe6ea2013-01-09 21:15:03 +0000816
817 if (FormatTok.Tok.is(tok::less))
818 parseObjCProtocolList();
819
820 // Check for protocol declaration.
821 if (FormatTok.Tok.is(tok::semi)) {
822 nextToken();
823 return addUnwrappedLine();
824 }
825
826 addUnwrappedLine();
827 parseObjCUntilAtEnd();
Nico Weber27d13672013-01-09 20:25:35 +0000828}
829
Daniel Jasperbac016b2012-12-03 18:12:45 +0000830void UnwrappedLineParser::addUnwrappedLine() {
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000831 if (Line->Tokens.empty())
Daniel Jasper26f7e782013-01-08 14:56:18 +0000832 return;
Manuel Klimek8fa37992013-01-16 12:31:12 +0000833 DEBUG({
Manuel Klimeka28fc062013-02-11 12:33:24 +0000834 llvm::dbgs() << "Line(" << Line->Level << ")"
835 << (Line->InPPDirective ? " MACRO" : "") << ": ";
Manuel Klimek8fa37992013-01-16 12:31:12 +0000836 for (std::list<FormatToken>::iterator I = Line->Tokens.begin(),
837 E = Line->Tokens.end();
838 I != E; ++I) {
839 llvm::dbgs() << I->Tok.getName() << " ";
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000840
Manuel Klimek8fa37992013-01-16 12:31:12 +0000841 }
842 llvm::dbgs() << "\n";
843 });
Manuel Klimek525fe162013-01-18 14:04:34 +0000844 CurrentLines->push_back(*Line);
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000845 Line->Tokens.clear();
Manuel Klimek525fe162013-01-18 14:04:34 +0000846 if (CurrentLines == &Lines && !PreprocessorDirectives.empty()) {
Daniel Jasper516fb312013-03-01 18:11:39 +0000847 for (std::vector<UnwrappedLine>::iterator
848 I = PreprocessorDirectives.begin(),
849 E = PreprocessorDirectives.end();
Manuel Klimek525fe162013-01-18 14:04:34 +0000850 I != E; ++I) {
851 CurrentLines->push_back(*I);
852 }
853 PreprocessorDirectives.clear();
854 }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000855}
856
Daniel Jasperf9955d32013-03-20 12:37:50 +0000857bool UnwrappedLineParser::eof() const { return FormatTok.Tok.is(tok::eof); }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000858
Manuel Klimek86721d22013-01-22 16:31:55 +0000859void UnwrappedLineParser::flushComments(bool NewlineBeforeNext) {
860 bool JustComments = Line->Tokens.empty();
861 for (SmallVectorImpl<FormatToken>::const_iterator
862 I = CommentsBeforeNextToken.begin(),
863 E = CommentsBeforeNextToken.end();
864 I != E; ++I) {
Manuel Klimekb3507cd2013-02-06 16:40:56 +0000865 if (I->NewlinesBefore && JustComments) {
Manuel Klimek86721d22013-01-22 16:31:55 +0000866 addUnwrappedLine();
867 }
868 pushToken(*I);
869 }
870 if (NewlineBeforeNext && JustComments) {
871 addUnwrappedLine();
872 }
873 CommentsBeforeNextToken.clear();
874}
875
Daniel Jasperbac016b2012-12-03 18:12:45 +0000876void UnwrappedLineParser::nextToken() {
877 if (eof())
878 return;
Manuel Klimekb3507cd2013-02-06 16:40:56 +0000879 flushComments(FormatTok.NewlinesBefore > 0);
Manuel Klimek86721d22013-01-22 16:31:55 +0000880 pushToken(FormatTok);
Manuel Klimekd4397b92013-01-04 23:34:14 +0000881 readToken();
882}
883
884void UnwrappedLineParser::readToken() {
Manuel Klimek86721d22013-01-22 16:31:55 +0000885 bool CommentsInCurrentLine = true;
886 do {
887 FormatTok = Tokens->getNextToken();
888 while (!Line->InPPDirective && FormatTok.Tok.is(tok::hash) &&
Alexander Kornienko3d713a72013-04-08 22:16:06 +0000889 (FormatTok.HasUnescapedNewline || FormatTok.IsFirst)) {
Manuel Klimek86721d22013-01-22 16:31:55 +0000890 // If there is an unfinished unwrapped line, we flush the preprocessor
891 // directives only after that unwrapped line was finished later.
Daniel Jasperf9955d32013-03-20 12:37:50 +0000892 bool SwitchToPreprocessorLines =
893 !Line->Tokens.empty() && CurrentLines == &Lines;
Manuel Klimek86721d22013-01-22 16:31:55 +0000894 ScopedLineState BlockState(*this, SwitchToPreprocessorLines);
Alexander Kornienko4128e192013-04-03 12:38:53 +0000895 // Comments stored before the preprocessor directive need to be output
896 // before the preprocessor directive, at the same level as the
897 // preprocessor directive, as we consider them to apply to the directive.
898 flushComments(FormatTok.NewlinesBefore > 0);
Manuel Klimek86721d22013-01-22 16:31:55 +0000899 parsePPDirective();
900 }
901 if (!FormatTok.Tok.is(tok::comment))
902 return;
Manuel Klimekb3507cd2013-02-06 16:40:56 +0000903 if (FormatTok.NewlinesBefore > 0 || FormatTok.IsFirst) {
Manuel Klimek86721d22013-01-22 16:31:55 +0000904 CommentsInCurrentLine = false;
905 }
906 if (CommentsInCurrentLine) {
907 pushToken(FormatTok);
908 } else {
909 CommentsBeforeNextToken.push_back(FormatTok);
910 }
911 } while (!eof());
912}
913
914void UnwrappedLineParser::pushToken(const FormatToken &Tok) {
915 Line->Tokens.push_back(Tok);
916 if (MustBreakBeforeNextToken) {
917 Line->Tokens.back().MustBreakBefore = true;
918 MustBreakBeforeNextToken = false;
Manuel Klimekd4397b92013-01-04 23:34:14 +0000919 }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000920}
921
Daniel Jaspercd162382013-01-07 13:26:07 +0000922} // end namespace format
923} // end namespace clang