blob: 722af5d2b7630874a8b67b551cc6f1d1aabb8e3b [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,
Manuel Klimek67d080d2013-04-12 14:13:36 +000048 FormatToken &ResetToken, bool &StructuralError)
Manuel Klimekd4397b92013-01-04 23:34:14 +000049 : Line(Line), TokenSource(TokenSource), ResetToken(ResetToken),
Manuel Klimek67d080d2013-04-12 14:13:36 +000050 PreviousLineLevel(Line.Level), PreviousTokenSource(TokenSource),
51 StructuralError(StructuralError),
52 PreviousStructuralError(StructuralError) {
Manuel Klimekd4397b92013-01-04 23:34:14 +000053 TokenSource = this;
Manuel Klimekc37b4d62013-01-05 22:14:16 +000054 Line.Level = 0;
Manuel Klimekd4397b92013-01-04 23:34:14 +000055 Line.InPPDirective = true;
56 }
57
58 ~ScopedMacroState() {
59 TokenSource = PreviousTokenSource;
60 ResetToken = Token;
61 Line.InPPDirective = false;
Manuel Klimekc37b4d62013-01-05 22:14:16 +000062 Line.Level = PreviousLineLevel;
Manuel Klimek67d080d2013-04-12 14:13:36 +000063 StructuralError = PreviousStructuralError;
Manuel Klimekd4397b92013-01-04 23:34:14 +000064 }
65
66 virtual FormatToken getNextToken() {
Manuel Klimekdd5b1012013-01-07 10:03:37 +000067 // The \c UnwrappedLineParser guards against this by never calling
68 // \c getNextToken() after it has encountered the first eof token.
69 assert(!eof());
Manuel Klimekd4397b92013-01-04 23:34:14 +000070 Token = PreviousTokenSource->getNextToken();
71 if (eof())
72 return createEOF();
73 return Token;
74 }
75
76private:
Alexander Kornienko3d713a72013-04-08 22:16:06 +000077 bool eof() { return Token.HasUnescapedNewline; }
Manuel Klimekd4397b92013-01-04 23:34:14 +000078
79 FormatToken createEOF() {
80 FormatToken FormatTok;
81 FormatTok.Tok.startToken();
82 FormatTok.Tok.setKind(tok::eof);
83 return FormatTok;
84 }
85
86 UnwrappedLine &Line;
87 FormatTokenSource *&TokenSource;
88 FormatToken &ResetToken;
Manuel Klimekc37b4d62013-01-05 22:14:16 +000089 unsigned PreviousLineLevel;
Manuel Klimekd4397b92013-01-04 23:34:14 +000090 FormatTokenSource *PreviousTokenSource;
Manuel Klimek67d080d2013-04-12 14:13:36 +000091 bool &StructuralError;
92 bool PreviousStructuralError;
Manuel Klimekd4397b92013-01-04 23:34:14 +000093
94 FormatToken Token;
95};
96
Manuel Klimekbb42bf12013-01-10 11:52:21 +000097class ScopedLineState {
98public:
Manuel Klimek525fe162013-01-18 14:04:34 +000099 ScopedLineState(UnwrappedLineParser &Parser,
100 bool SwitchToPreprocessorLines = false)
101 : Parser(Parser), SwitchToPreprocessorLines(SwitchToPreprocessorLines) {
102 if (SwitchToPreprocessorLines)
103 Parser.CurrentLines = &Parser.PreprocessorDirectives;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000104 PreBlockLine = Parser.Line.take();
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000105 Parser.Line.reset(new UnwrappedLine());
106 Parser.Line->Level = PreBlockLine->Level;
107 Parser.Line->InPPDirective = PreBlockLine->InPPDirective;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000108 }
109
110 ~ScopedLineState() {
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000111 if (!Parser.Line->Tokens.empty()) {
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000112 Parser.addUnwrappedLine();
113 }
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000114 assert(Parser.Line->Tokens.empty());
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000115 Parser.Line.reset(PreBlockLine);
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000116 Parser.MustBreakBeforeNextToken = true;
Manuel Klimek525fe162013-01-18 14:04:34 +0000117 if (SwitchToPreprocessorLines)
118 Parser.CurrentLines = &Parser.Lines;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000119 }
120
121private:
122 UnwrappedLineParser &Parser;
Manuel Klimek525fe162013-01-18 14:04:34 +0000123 const bool SwitchToPreprocessorLines;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000124
125 UnwrappedLine *PreBlockLine;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000126};
127
Alexander Kornienko3048aea2013-01-10 15:05:09 +0000128UnwrappedLineParser::UnwrappedLineParser(
129 clang::DiagnosticsEngine &Diag, const FormatStyle &Style,
130 FormatTokenSource &Tokens, UnwrappedLineConsumer &Callback)
Manuel Klimek525fe162013-01-18 14:04:34 +0000131 : Line(new UnwrappedLine), MustBreakBeforeNextToken(false),
Manuel Klimek67d080d2013-04-12 14:13:36 +0000132 CurrentLines(&Lines), StructuralError(false), Diag(Diag), Style(Style),
133 Tokens(&Tokens), Callback(Callback) {}
Daniel Jasperbac016b2012-12-03 18:12:45 +0000134
Alexander Kornienkocff563c2012-12-04 17:27:50 +0000135bool UnwrappedLineParser::parse() {
Manuel Klimek8fa37992013-01-16 12:31:12 +0000136 DEBUG(llvm::dbgs() << "----\n");
Manuel Klimekd4397b92013-01-04 23:34:14 +0000137 readToken();
Manuel Klimek67d080d2013-04-12 14:13:36 +0000138 parseFile();
Daniel Jasperf9955d32013-03-20 12:37:50 +0000139 for (std::vector<UnwrappedLine>::iterator I = Lines.begin(), E = Lines.end();
Manuel Klimek525fe162013-01-18 14:04:34 +0000140 I != E; ++I) {
141 Callback.consumeUnwrappedLine(*I);
142 }
Daniel Jasper516fb312013-03-01 18:11:39 +0000143
144 // Create line with eof token.
145 pushToken(FormatTok);
146 Callback.consumeUnwrappedLine(*Line);
Manuel Klimek67d080d2013-04-12 14:13:36 +0000147 return StructuralError;
Manuel Klimekd4397b92013-01-04 23:34:14 +0000148}
149
Manuel Klimek67d080d2013-04-12 14:13:36 +0000150void UnwrappedLineParser::parseFile() {
Daniel Jasper627707b2013-03-22 16:55:40 +0000151 ScopedDeclarationState DeclarationState(
152 *Line, DeclarationScopeStack,
153 /*MustBeDeclaration=*/ !Line->InPPDirective);
Manuel Klimek67d080d2013-04-12 14:13:36 +0000154 parseLevel(/*HasOpeningBrace=*/ false);
Manuel Klimekd4397b92013-01-04 23:34:14 +0000155 // Make sure to format the remaining tokens.
Manuel Klimek86721d22013-01-22 16:31:55 +0000156 flushComments(true);
Manuel Klimekd4397b92013-01-04 23:34:14 +0000157 addUnwrappedLine();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000158}
159
Manuel Klimek67d080d2013-04-12 14:13:36 +0000160void UnwrappedLineParser::parseLevel(bool HasOpeningBrace) {
Daniel Jasperbac016b2012-12-03 18:12:45 +0000161 do {
162 switch (FormatTok.Tok.getKind()) {
Daniel Jasperbac016b2012-12-03 18:12:45 +0000163 case tok::comment:
Daniel Jasper05b1ac82012-12-17 11:29:41 +0000164 nextToken();
165 addUnwrappedLine();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000166 break;
167 case tok::l_brace:
Manuel Klimek70b03f42013-01-23 09:32:48 +0000168 // FIXME: Add parameter whether this can happen - if this happens, we must
169 // be in a non-declaration context.
Manuel Klimek67d080d2013-04-12 14:13:36 +0000170 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000171 addUnwrappedLine();
172 break;
173 case tok::r_brace:
Manuel Klimek67d080d2013-04-12 14:13:36 +0000174 if (HasOpeningBrace)
175 return;
176 Diag.Report(FormatTok.Tok.getLocation(),
177 Diag.getCustomDiagID(clang::DiagnosticsEngine::Error,
178 "unexpected '}'"));
179 StructuralError = true;
180 nextToken();
181 addUnwrappedLine();
Manuel Klimeka5342db2013-01-06 20:07:31 +0000182 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000183 default:
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000184 parseStructuralElement();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000185 break;
186 }
187 } while (!eof());
188}
189
Manuel Klimek67d080d2013-04-12 14:13:36 +0000190void UnwrappedLineParser::parseBlock(bool MustBeDeclaration,
Nico Weberd74fcdb2013-02-10 20:35:35 +0000191 unsigned AddLevels) {
Alexander Kornienkoa3a2b3a2012-12-06 17:49:17 +0000192 assert(FormatTok.Tok.is(tok::l_brace) && "'{' expected");
Daniel Jasperbac016b2012-12-03 18:12:45 +0000193 nextToken();
194
Manuel Klimek2f1ac412013-01-21 16:42:44 +0000195 addUnwrappedLine();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000196
Manuel Klimek70b03f42013-01-23 09:32:48 +0000197 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
198 MustBeDeclaration);
Manuel Klimek2f1ac412013-01-21 16:42:44 +0000199 Line->Level += AddLevels;
Daniel Jasperf9955d32013-03-20 12:37:50 +0000200 parseLevel(/*HasOpeningBrace=*/ true);
Alexander Kornienko15757312012-12-06 18:03:27 +0000201
Manuel Klimek86721d22013-01-22 16:31:55 +0000202 if (!FormatTok.Tok.is(tok::r_brace)) {
203 Line->Level -= AddLevels;
Manuel Klimek67d080d2013-04-12 14:13:36 +0000204 StructuralError = true;
205 return;
Manuel Klimek86721d22013-01-22 16:31:55 +0000206 }
Alexander Kornienko393b0082012-12-04 15:40:36 +0000207
Daniel Jasperf9955d32013-03-20 12:37:50 +0000208 nextToken(); // Munch the closing brace.
Manuel Klimek86721d22013-01-22 16:31:55 +0000209 Line->Level -= AddLevels;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000210}
211
212void UnwrappedLineParser::parsePPDirective() {
Manuel Klimeka080a182013-01-02 16:30:12 +0000213 assert(FormatTok.Tok.is(tok::hash) && "'#' expected");
Manuel Klimek67d080d2013-04-12 14:13:36 +0000214 ScopedMacroState MacroState(*Line, Tokens, FormatTok, StructuralError);
Manuel Klimeka080a182013-01-02 16:30:12 +0000215 nextToken();
216
Manuel Klimeka080a182013-01-02 16:30:12 +0000217 if (FormatTok.Tok.getIdentifierInfo() == NULL) {
Manuel Klimekbd04f2a2013-01-31 15:58:48 +0000218 parsePPUnknown();
Manuel Klimeka080a182013-01-02 16:30:12 +0000219 return;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000220 }
Manuel Klimeka080a182013-01-02 16:30:12 +0000221
Manuel Klimekd4397b92013-01-04 23:34:14 +0000222 switch (FormatTok.Tok.getIdentifierInfo()->getPPKeywordID()) {
223 case tok::pp_define:
224 parsePPDefine();
225 break;
226 default:
227 parsePPUnknown();
228 break;
229 }
230}
231
232void UnwrappedLineParser::parsePPDefine() {
233 nextToken();
234
235 if (FormatTok.Tok.getKind() != tok::identifier) {
236 parsePPUnknown();
237 return;
238 }
239 nextToken();
Manuel Klimek7ccbc212013-01-23 14:37:36 +0000240 if (FormatTok.Tok.getKind() == tok::l_paren &&
241 FormatTok.WhiteSpaceLength == 0) {
Manuel Klimekd4397b92013-01-04 23:34:14 +0000242 parseParens();
243 }
244 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000245 Line->Level = 1;
Manuel Klimekc3d0c822013-01-07 09:34:28 +0000246
247 // Errors during a preprocessor directive can only affect the layout of the
248 // preprocessor directive, and thus we ignore them. An alternative approach
249 // would be to use the same approach we use on the file level (no
250 // re-indentation if there was a structural error) within the macro
251 // definition.
Manuel Klimekd4397b92013-01-04 23:34:14 +0000252 parseFile();
253}
254
255void UnwrappedLineParser::parsePPUnknown() {
Manuel Klimeka080a182013-01-02 16:30:12 +0000256 do {
Manuel Klimeka080a182013-01-02 16:30:12 +0000257 nextToken();
258 } while (!eof());
259 addUnwrappedLine();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000260}
261
Alexander Kornienko99b0e142013-04-09 16:15:19 +0000262// Here we blacklist certain tokens that are not usually the first token in an
263// unwrapped line. This is used in attempt to distinguish macro calls without
264// trailing semicolons from other constructs split to several lines.
265bool tokenCanStartNewLine(clang::Token Tok) {
266 // Semicolon can be a null-statement, l_square can be a start of a macro or
267 // a C++11 attribute, but this doesn't seem to be common.
268 return Tok.isNot(tok::semi) && Tok.isNot(tok::l_brace) &&
269 Tok.isNot(tok::l_square) &&
270 // Tokens that can only be used as binary operators and a part of
271 // overloaded operator names.
272 Tok.isNot(tok::period) && Tok.isNot(tok::periodstar) &&
273 Tok.isNot(tok::arrow) && Tok.isNot(tok::arrowstar) &&
274 Tok.isNot(tok::less) && Tok.isNot(tok::greater) &&
275 Tok.isNot(tok::slash) && Tok.isNot(tok::percent) &&
276 Tok.isNot(tok::lessless) && Tok.isNot(tok::greatergreater) &&
277 Tok.isNot(tok::equal) && Tok.isNot(tok::plusequal) &&
278 Tok.isNot(tok::minusequal) && Tok.isNot(tok::starequal) &&
279 Tok.isNot(tok::slashequal) && Tok.isNot(tok::percentequal) &&
280 Tok.isNot(tok::ampequal) && Tok.isNot(tok::pipeequal) &&
281 Tok.isNot(tok::caretequal) && Tok.isNot(tok::greatergreaterequal) &&
282 Tok.isNot(tok::lesslessequal) &&
283 // Colon is used in labels, base class lists, initializer lists,
284 // range-based for loops, ternary operator, but should never be the
285 // first token in an unwrapped line.
286 Tok.isNot(tok::colon);
287}
288
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000289void UnwrappedLineParser::parseStructuralElement() {
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000290 assert(!FormatTok.Tok.is(tok::l_brace));
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000291 switch (FormatTok.Tok.getKind()) {
Nico Weber6092d4e2013-01-07 19:05:19 +0000292 case tok::at:
293 nextToken();
Nico Weberd74fcdb2013-02-10 20:35:35 +0000294 if (FormatTok.Tok.is(tok::l_brace)) {
295 parseBracedList();
296 break;
297 }
Nico Weber6092d4e2013-01-07 19:05:19 +0000298 switch (FormatTok.Tok.getObjCKeywordID()) {
299 case tok::objc_public:
300 case tok::objc_protected:
301 case tok::objc_package:
302 case tok::objc_private:
303 return parseAccessSpecifier();
Nico Weber27d13672013-01-09 20:25:35 +0000304 case tok::objc_interface:
Nico Weber50767d82013-01-09 23:25:37 +0000305 case tok::objc_implementation:
306 return parseObjCInterfaceOrImplementation();
Nico Weber1abe6ea2013-01-09 21:15:03 +0000307 case tok::objc_protocol:
308 return parseObjCProtocol();
Nico Weber049c4472013-01-09 21:42:32 +0000309 case tok::objc_end:
310 return; // Handled by the caller.
Nico Weberb530fa32013-01-10 00:25:19 +0000311 case tok::objc_optional:
312 case tok::objc_required:
313 nextToken();
314 addUnwrappedLine();
315 return;
Nico Weber6092d4e2013-01-07 19:05:19 +0000316 default:
317 break;
318 }
319 break;
Alexander Kornienko15757312012-12-06 18:03:27 +0000320 case tok::kw_namespace:
321 parseNamespace();
322 return;
Dmitri Gribenko1f94f2b2012-12-30 21:27:25 +0000323 case tok::kw_inline:
324 nextToken();
Dmitri Gribenko1f94f2b2012-12-30 21:27:25 +0000325 if (FormatTok.Tok.is(tok::kw_namespace)) {
326 parseNamespace();
327 return;
328 }
329 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000330 case tok::kw_public:
331 case tok::kw_protected:
332 case tok::kw_private:
Daniel Jasperbac016b2012-12-03 18:12:45 +0000333 parseAccessSpecifier();
334 return;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000335 case tok::kw_if:
336 parseIfThenElse();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000337 return;
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000338 case tok::kw_for:
339 case tok::kw_while:
340 parseForOrWhileLoop();
341 return;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000342 case tok::kw_do:
343 parseDoWhile();
344 return;
345 case tok::kw_switch:
346 parseSwitch();
347 return;
348 case tok::kw_default:
349 nextToken();
350 parseLabel();
351 return;
352 case tok::kw_case:
353 parseCaseLabel();
354 return;
Manuel Klimekc44ee892013-01-21 10:07:49 +0000355 case tok::kw_return:
356 parseReturn();
357 return;
Manuel Klimekd19dc2d2013-01-21 14:32:05 +0000358 case tok::kw_extern:
359 nextToken();
360 if (FormatTok.Tok.is(tok::string_literal)) {
361 nextToken();
362 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000363 parseBlock(/*MustBeDeclaration=*/ true, 0);
Manuel Klimekd19dc2d2013-01-21 14:32:05 +0000364 addUnwrappedLine();
365 return;
366 }
367 }
368 // In all other cases, parse the declaration.
369 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000370 default:
371 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000372 }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000373 do {
Daniel Jasperbac016b2012-12-03 18:12:45 +0000374 switch (FormatTok.Tok.getKind()) {
Nico Weberd74fcdb2013-02-10 20:35:35 +0000375 case tok::at:
376 nextToken();
377 if (FormatTok.Tok.is(tok::l_brace))
378 parseBracedList();
379 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000380 case tok::kw_enum:
381 parseEnum();
Manuel Klimek308232c2013-01-21 19:17:52 +0000382 break;
Alexander Kornienkod8818752013-01-16 11:43:46 +0000383 case tok::kw_struct:
384 case tok::kw_union:
Manuel Klimekde768542013-01-07 18:10:23 +0000385 case tok::kw_class:
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000386 parseRecord();
387 // A record declaration or definition is always the start of a structural
388 // element.
389 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000390 case tok::semi:
391 nextToken();
392 addUnwrappedLine();
393 return;
Alexander Kornienkod8818752013-01-16 11:43:46 +0000394 case tok::r_brace:
395 addUnwrappedLine();
396 return;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000397 case tok::l_paren:
398 parseParens();
399 break;
400 case tok::l_brace:
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000401 // A block outside of parentheses must be the last part of a
402 // structural element.
403 // FIXME: Figure out cases where this is not true, and add projections for
404 // them (the one we know is missing are lambdas).
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 Klimek70b03f42013-01-23 09:32:48 +0000580 parseBlock(/*MustBeDeclaration=*/ true, 0);
Manuel Klimek7fc2db02013-02-06 16:08:09 +0000581 // Munch the semicolon after a namespace. This is more common than one would
582 // think. Puttin the semicolon into its own line is very ugly.
583 if (FormatTok.Tok.is(tok::semi))
584 nextToken();
Alexander Kornienko15757312012-12-06 18:03:27 +0000585 addUnwrappedLine();
586 }
587 // FIXME: Add error handling.
588}
589
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000590void UnwrappedLineParser::parseForOrWhileLoop() {
591 assert((FormatTok.Tok.is(tok::kw_for) || FormatTok.Tok.is(tok::kw_while)) &&
592 "'for' or 'while' expected");
593 nextToken();
Manuel Klimek6eca03f2013-01-11 19:23:05 +0000594 if (FormatTok.Tok.is(tok::l_paren))
595 parseParens();
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000596 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000597 parseBlock(/*MustBeDeclaration=*/ false);
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000598 addUnwrappedLine();
599 } else {
600 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000601 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000602 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000603 --Line->Level;
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000604 }
605}
606
Daniel Jasperbac016b2012-12-03 18:12:45 +0000607void UnwrappedLineParser::parseDoWhile() {
608 assert(FormatTok.Tok.is(tok::kw_do) && "'do' expected");
609 nextToken();
610 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000611 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000612 } else {
613 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000614 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000615 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000616 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000617 }
618
Alexander Kornienko393b0082012-12-04 15:40:36 +0000619 // FIXME: Add error handling.
620 if (!FormatTok.Tok.is(tok::kw_while)) {
621 addUnwrappedLine();
622 return;
623 }
624
Daniel Jasperbac016b2012-12-03 18:12:45 +0000625 nextToken();
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000626 parseStructuralElement();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000627}
628
629void UnwrappedLineParser::parseLabel() {
Daniel Jasper89a0daa2013-02-12 20:17:17 +0000630 if (FormatTok.Tok.isNot(tok::colon))
631 return;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000632 nextToken();
Manuel Klimek526ed112013-01-09 15:25:02 +0000633 unsigned OldLineLevel = Line->Level;
Daniel Jasperbcca7e42013-03-20 10:23:53 +0000634 if (Line->Level > 1 || (!Line->InPPDirective && Line->Level > 0))
Manuel Klimek526ed112013-01-09 15:25:02 +0000635 --Line->Level;
Daniel Jasperc30eb512013-03-19 18:33:58 +0000636 if (CommentsBeforeNextToken.empty() && FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000637 parseBlock(/*MustBeDeclaration=*/ false);
Nico Weber94fb7292013-01-18 05:50:57 +0000638 if (FormatTok.Tok.is(tok::kw_break))
639 parseStructuralElement(); // "break;" after "}" goes on the same line.
Daniel Jasperbac016b2012-12-03 18:12:45 +0000640 }
641 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000642 Line->Level = OldLineLevel;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000643}
644
645void UnwrappedLineParser::parseCaseLabel() {
646 assert(FormatTok.Tok.is(tok::kw_case) && "'case' expected");
647 // FIXME: fix handling of complex expressions here.
648 do {
649 nextToken();
650 } while (!eof() && !FormatTok.Tok.is(tok::colon));
651 parseLabel();
652}
653
654void UnwrappedLineParser::parseSwitch() {
655 assert(FormatTok.Tok.is(tok::kw_switch) && "'switch' expected");
656 nextToken();
Manuel Klimek6eca03f2013-01-11 19:23:05 +0000657 if (FormatTok.Tok.is(tok::l_paren))
658 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000659 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000660 parseBlock(/*MustBeDeclaration=*/ false, Style.IndentCaseLabels ? 2 : 1);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000661 addUnwrappedLine();
662 } else {
663 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000664 Line->Level += (Style.IndentCaseLabels ? 2 : 1);
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000665 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000666 Line->Level -= (Style.IndentCaseLabels ? 2 : 1);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000667 }
668}
669
670void UnwrappedLineParser::parseAccessSpecifier() {
671 nextToken();
Alexander Kornienko56e49c52012-12-10 16:34:48 +0000672 // Otherwise, we don't know what it is, and we'd better keep the next token.
673 if (FormatTok.Tok.is(tok::colon))
674 nextToken();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000675 addUnwrappedLine();
676}
677
678void UnwrappedLineParser::parseEnum() {
Manuel Klimek308232c2013-01-21 19:17:52 +0000679 nextToken();
680 if (FormatTok.Tok.is(tok::identifier) ||
681 FormatTok.Tok.is(tok::kw___attribute) ||
682 FormatTok.Tok.is(tok::kw___declspec)) {
683 nextToken();
684 // We can have macros or attributes in between 'enum' and the enum name.
685 if (FormatTok.Tok.is(tok::l_paren)) {
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000686 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000687 }
Manuel Klimek308232c2013-01-21 19:17:52 +0000688 if (FormatTok.Tok.is(tok::identifier))
689 nextToken();
690 }
691 if (FormatTok.Tok.is(tok::l_brace)) {
692 nextToken();
693 addUnwrappedLine();
694 ++Line->Level;
695 do {
696 switch (FormatTok.Tok.getKind()) {
Manuel Klimek308232c2013-01-21 19:17:52 +0000697 case tok::l_paren:
698 parseParens();
699 break;
700 case tok::r_brace:
701 addUnwrappedLine();
702 nextToken();
703 --Line->Level;
704 return;
705 case tok::comma:
706 nextToken();
707 addUnwrappedLine();
708 break;
709 default:
710 nextToken();
711 break;
712 }
713 } while (!eof());
714 }
715 // We fall through to parsing a structural element afterwards, so that in
716 // enum A {} n, m;
717 // "} n, m;" will end up in one unwrapped line.
Daniel Jasperbac016b2012-12-03 18:12:45 +0000718}
719
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000720void UnwrappedLineParser::parseRecord() {
Manuel Klimekde768542013-01-07 18:10:23 +0000721 nextToken();
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000722 if (FormatTok.Tok.is(tok::identifier) ||
723 FormatTok.Tok.is(tok::kw___attribute) ||
724 FormatTok.Tok.is(tok::kw___declspec)) {
725 nextToken();
726 // We can have macros or attributes in between 'class' and the class name.
727 if (FormatTok.Tok.is(tok::l_paren)) {
728 parseParens();
Manuel Klimekde768542013-01-07 18:10:23 +0000729 }
Manuel Klimekb8b1ce12013-02-06 15:57:54 +0000730 // The actual identifier can be a nested name specifier, and in macros
731 // it is often token-pasted.
Manuel Klimek7f5b0252013-01-21 10:17:14 +0000732 while (FormatTok.Tok.is(tok::identifier) ||
Daniel Jasperf9955d32013-03-20 12:37:50 +0000733 FormatTok.Tok.is(tok::coloncolon) || FormatTok.Tok.is(tok::hashhash))
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000734 nextToken();
735
Manuel Klimek3a3408c2013-01-21 13:58:54 +0000736 // Note that parsing away template declarations here leads to incorrectly
737 // accepting function declarations as record declarations.
738 // In general, we cannot solve this problem. Consider:
739 // class A<int> B() {}
740 // which can be a function definition or a class definition when B() is a
741 // macro. If we find enough real-world cases where this is a problem, we
742 // can parse for the 'template' keyword in the beginning of the statement,
743 // and thus rule out the record production in case there is no template
744 // (this would still leave us with an ambiguity between template function
745 // and class declarations).
746 if (FormatTok.Tok.is(tok::colon) || FormatTok.Tok.is(tok::less)) {
Daniel Jasper6fe554e2013-03-20 15:12:38 +0000747 while (!eof() && FormatTok.Tok.isNot(tok::l_brace)) {
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000748 if (FormatTok.Tok.is(tok::semi))
749 return;
750 nextToken();
751 }
752 }
753 }
754 if (FormatTok.Tok.is(tok::l_brace))
Manuel Klimek70b03f42013-01-23 09:32:48 +0000755 parseBlock(/*MustBeDeclaration=*/ true);
Manuel Klimek3a3408c2013-01-21 13:58:54 +0000756 // We fall through to parsing a structural element afterwards, so
757 // class A {} n, m;
758 // will end up in one unwrapped line.
Manuel Klimekde768542013-01-07 18:10:23 +0000759}
760
Nico Weber1abe6ea2013-01-09 21:15:03 +0000761void UnwrappedLineParser::parseObjCProtocolList() {
762 assert(FormatTok.Tok.is(tok::less) && "'<' expected.");
763 do
764 nextToken();
765 while (!eof() && FormatTok.Tok.isNot(tok::greater));
766 nextToken(); // Skip '>'.
767}
768
769void UnwrappedLineParser::parseObjCUntilAtEnd() {
770 do {
771 if (FormatTok.Tok.isObjCAtKeyword(tok::objc_end)) {
772 nextToken();
773 addUnwrappedLine();
774 break;
775 }
776 parseStructuralElement();
777 } while (!eof());
778}
779
Nico Weber50767d82013-01-09 23:25:37 +0000780void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
Nico Weber27d13672013-01-09 20:25:35 +0000781 nextToken();
Daniel Jasperf9955d32013-03-20 12:37:50 +0000782 nextToken(); // interface name
Nico Weber27d13672013-01-09 20:25:35 +0000783
784 // @interface can be followed by either a base class, or a category.
785 if (FormatTok.Tok.is(tok::colon)) {
786 nextToken();
Daniel Jasperf9955d32013-03-20 12:37:50 +0000787 nextToken(); // base class name
Nico Weber27d13672013-01-09 20:25:35 +0000788 } else if (FormatTok.Tok.is(tok::l_paren))
789 // Skip category, if present.
790 parseParens();
791
Nico Weber1abe6ea2013-01-09 21:15:03 +0000792 if (FormatTok.Tok.is(tok::less))
793 parseObjCProtocolList();
Nico Weber27d13672013-01-09 20:25:35 +0000794
795 // If instance variables are present, keep the '{' on the first line too.
796 if (FormatTok.Tok.is(tok::l_brace))
Manuel Klimek70b03f42013-01-23 09:32:48 +0000797 parseBlock(/*MustBeDeclaration=*/ true);
Nico Weber27d13672013-01-09 20:25:35 +0000798
799 // With instance variables, this puts '}' on its own line. Without instance
800 // variables, this ends the @interface line.
801 addUnwrappedLine();
802
Nico Weber1abe6ea2013-01-09 21:15:03 +0000803 parseObjCUntilAtEnd();
804}
Nico Weber27d13672013-01-09 20:25:35 +0000805
Nico Weber1abe6ea2013-01-09 21:15:03 +0000806void UnwrappedLineParser::parseObjCProtocol() {
807 nextToken();
Daniel Jasperf9955d32013-03-20 12:37:50 +0000808 nextToken(); // protocol name
Nico Weber1abe6ea2013-01-09 21:15:03 +0000809
810 if (FormatTok.Tok.is(tok::less))
811 parseObjCProtocolList();
812
813 // Check for protocol declaration.
814 if (FormatTok.Tok.is(tok::semi)) {
815 nextToken();
816 return addUnwrappedLine();
817 }
818
819 addUnwrappedLine();
820 parseObjCUntilAtEnd();
Nico Weber27d13672013-01-09 20:25:35 +0000821}
822
Daniel Jasperbac016b2012-12-03 18:12:45 +0000823void UnwrappedLineParser::addUnwrappedLine() {
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000824 if (Line->Tokens.empty())
Daniel Jasper26f7e782013-01-08 14:56:18 +0000825 return;
Manuel Klimek8fa37992013-01-16 12:31:12 +0000826 DEBUG({
Manuel Klimeka28fc062013-02-11 12:33:24 +0000827 llvm::dbgs() << "Line(" << Line->Level << ")"
828 << (Line->InPPDirective ? " MACRO" : "") << ": ";
Manuel Klimek8fa37992013-01-16 12:31:12 +0000829 for (std::list<FormatToken>::iterator I = Line->Tokens.begin(),
830 E = Line->Tokens.end();
831 I != E; ++I) {
832 llvm::dbgs() << I->Tok.getName() << " ";
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000833
Manuel Klimek8fa37992013-01-16 12:31:12 +0000834 }
835 llvm::dbgs() << "\n";
836 });
Manuel Klimek525fe162013-01-18 14:04:34 +0000837 CurrentLines->push_back(*Line);
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000838 Line->Tokens.clear();
Manuel Klimek525fe162013-01-18 14:04:34 +0000839 if (CurrentLines == &Lines && !PreprocessorDirectives.empty()) {
Daniel Jasper516fb312013-03-01 18:11:39 +0000840 for (std::vector<UnwrappedLine>::iterator
841 I = PreprocessorDirectives.begin(),
842 E = PreprocessorDirectives.end();
Manuel Klimek525fe162013-01-18 14:04:34 +0000843 I != E; ++I) {
844 CurrentLines->push_back(*I);
845 }
846 PreprocessorDirectives.clear();
847 }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000848}
849
Daniel Jasperf9955d32013-03-20 12:37:50 +0000850bool UnwrappedLineParser::eof() const { return FormatTok.Tok.is(tok::eof); }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000851
Manuel Klimek86721d22013-01-22 16:31:55 +0000852void UnwrappedLineParser::flushComments(bool NewlineBeforeNext) {
853 bool JustComments = Line->Tokens.empty();
854 for (SmallVectorImpl<FormatToken>::const_iterator
855 I = CommentsBeforeNextToken.begin(),
856 E = CommentsBeforeNextToken.end();
857 I != E; ++I) {
Manuel Klimekb3507cd2013-02-06 16:40:56 +0000858 if (I->NewlinesBefore && JustComments) {
Manuel Klimek86721d22013-01-22 16:31:55 +0000859 addUnwrappedLine();
860 }
861 pushToken(*I);
862 }
863 if (NewlineBeforeNext && JustComments) {
864 addUnwrappedLine();
865 }
866 CommentsBeforeNextToken.clear();
867}
868
Daniel Jasperbac016b2012-12-03 18:12:45 +0000869void UnwrappedLineParser::nextToken() {
870 if (eof())
871 return;
Manuel Klimekb3507cd2013-02-06 16:40:56 +0000872 flushComments(FormatTok.NewlinesBefore > 0);
Manuel Klimek86721d22013-01-22 16:31:55 +0000873 pushToken(FormatTok);
Manuel Klimekd4397b92013-01-04 23:34:14 +0000874 readToken();
875}
876
877void UnwrappedLineParser::readToken() {
Manuel Klimek86721d22013-01-22 16:31:55 +0000878 bool CommentsInCurrentLine = true;
879 do {
880 FormatTok = Tokens->getNextToken();
881 while (!Line->InPPDirective && FormatTok.Tok.is(tok::hash) &&
Alexander Kornienko3d713a72013-04-08 22:16:06 +0000882 (FormatTok.HasUnescapedNewline || FormatTok.IsFirst)) {
Manuel Klimek86721d22013-01-22 16:31:55 +0000883 // If there is an unfinished unwrapped line, we flush the preprocessor
884 // directives only after that unwrapped line was finished later.
Daniel Jasperf9955d32013-03-20 12:37:50 +0000885 bool SwitchToPreprocessorLines =
886 !Line->Tokens.empty() && CurrentLines == &Lines;
Manuel Klimek86721d22013-01-22 16:31:55 +0000887 ScopedLineState BlockState(*this, SwitchToPreprocessorLines);
Alexander Kornienko4128e192013-04-03 12:38:53 +0000888 // Comments stored before the preprocessor directive need to be output
889 // before the preprocessor directive, at the same level as the
890 // preprocessor directive, as we consider them to apply to the directive.
891 flushComments(FormatTok.NewlinesBefore > 0);
Manuel Klimek86721d22013-01-22 16:31:55 +0000892 parsePPDirective();
893 }
894 if (!FormatTok.Tok.is(tok::comment))
895 return;
Manuel Klimekb3507cd2013-02-06 16:40:56 +0000896 if (FormatTok.NewlinesBefore > 0 || FormatTok.IsFirst) {
Manuel Klimek86721d22013-01-22 16:31:55 +0000897 CommentsInCurrentLine = false;
898 }
899 if (CommentsInCurrentLine) {
900 pushToken(FormatTok);
901 } else {
902 CommentsBeforeNextToken.push_back(FormatTok);
903 }
904 } while (!eof());
905}
906
907void UnwrappedLineParser::pushToken(const FormatToken &Tok) {
908 Line->Tokens.push_back(Tok);
909 if (MustBreakBeforeNextToken) {
910 Line->Tokens.back().MustBreakBefore = true;
911 MustBreakBeforeNextToken = false;
Manuel Klimekd4397b92013-01-04 23:34:14 +0000912 }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000913}
914
Daniel Jaspercd162382013-01-07 13:26:07 +0000915} // end namespace format
916} // end namespace clang