blob: a08790d80dcaf623d43325f2c4020bcc114b60f4 [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 Klimek44135b82013-05-13 12:51:40 +0000405 if (Style.BreakBeforeBraces == FormatStyle::BS_Linux ||
406 Style.BreakBeforeBraces == FormatStyle::BS_Stroustrup)
407 addUnwrappedLine();
408
Manuel Klimek70b03f42013-01-23 09:32:48 +0000409 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000410 addUnwrappedLine();
411 return;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000412 case tok::identifier:
Daniel Jasperbac016b2012-12-03 18:12:45 +0000413 nextToken();
Alexander Kornienko3d713a72013-04-08 22:16:06 +0000414 if (Line->Tokens.size() == 1) {
415 if (FormatTok.Tok.is(tok::colon)) {
416 parseLabel();
417 return;
418 }
Alexander Kornienko99b0e142013-04-09 16:15:19 +0000419 // Recognize function-like macro usages without trailing semicolon.
Alexander Kornienko3d713a72013-04-08 22:16:06 +0000420 if (FormatTok.Tok.is(tok::l_paren)) {
421 parseParens();
Alexander Kornienko99b0e142013-04-09 16:15:19 +0000422 if (FormatTok.HasUnescapedNewline &&
423 tokenCanStartNewLine(FormatTok.Tok)) {
Alexander Kornienko3d713a72013-04-08 22:16:06 +0000424 addUnwrappedLine();
425 return;
426 }
427 }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000428 }
429 break;
Daniel Jasper05b1ac82012-12-17 11:29:41 +0000430 case tok::equal:
431 nextToken();
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000432 if (FormatTok.Tok.is(tok::l_brace)) {
433 parseBracedList();
434 }
Daniel Jasper05b1ac82012-12-17 11:29:41 +0000435 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000436 default:
437 nextToken();
438 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000439 }
440 } while (!eof());
441}
442
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000443void UnwrappedLineParser::parseBracedList() {
444 nextToken();
445
Manuel Klimek423dd932013-04-10 09:52:05 +0000446 // FIXME: Once we have an expression parser in the UnwrappedLineParser,
447 // replace this by using parseAssigmentExpression() inside.
448 bool StartOfExpression = true;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000449 do {
Manuel Klimek423dd932013-04-10 09:52:05 +0000450 // FIXME: When we start to support lambdas, we'll want to parse them away
451 // here, otherwise our bail-out scenarios below break. The better solution
452 // might be to just implement a more or less complete expression parser.
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000453 switch (FormatTok.Tok.getKind()) {
454 case tok::l_brace:
Manuel Klimek423dd932013-04-10 09:52:05 +0000455 if (!StartOfExpression) {
456 // Probably a missing closing brace. Bail out.
457 addUnwrappedLine();
458 return;
459 }
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000460 parseBracedList();
Manuel Klimek423dd932013-04-10 09:52:05 +0000461 StartOfExpression = false;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000462 break;
463 case tok::r_brace:
464 nextToken();
465 return;
Manuel Klimek423dd932013-04-10 09:52:05 +0000466 case tok::semi:
467 // Probably a missing closing brace. Bail out.
468 return;
469 case tok::comma:
470 nextToken();
471 StartOfExpression = true;
472 break;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000473 default:
474 nextToken();
Manuel Klimek423dd932013-04-10 09:52:05 +0000475 StartOfExpression = false;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000476 break;
477 }
478 } while (!eof());
479}
480
Manuel Klimekc44ee892013-01-21 10:07:49 +0000481void UnwrappedLineParser::parseReturn() {
482 nextToken();
483
484 do {
485 switch (FormatTok.Tok.getKind()) {
486 case tok::l_brace:
487 parseBracedList();
Manuel Klimek423dd932013-04-10 09:52:05 +0000488 if (FormatTok.Tok.isNot(tok::semi)) {
489 // Assume missing ';'.
490 addUnwrappedLine();
491 return;
492 }
Manuel Klimekc44ee892013-01-21 10:07:49 +0000493 break;
494 case tok::l_paren:
495 parseParens();
496 break;
497 case tok::r_brace:
498 // Assume missing ';'.
499 addUnwrappedLine();
500 return;
501 case tok::semi:
502 nextToken();
503 addUnwrappedLine();
504 return;
505 default:
506 nextToken();
507 break;
508 }
509 } while (!eof());
510}
511
Daniel Jasperbac016b2012-12-03 18:12:45 +0000512void UnwrappedLineParser::parseParens() {
513 assert(FormatTok.Tok.is(tok::l_paren) && "'(' expected.");
514 nextToken();
515 do {
516 switch (FormatTok.Tok.getKind()) {
517 case tok::l_paren:
518 parseParens();
519 break;
520 case tok::r_paren:
521 nextToken();
522 return;
Nico Weber2afbe522013-02-10 04:38:23 +0000523 case tok::l_brace: {
524 nextToken();
525 ScopedLineState LineState(*this);
526 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
527 /*MustBeDeclaration=*/ false);
528 Line->Level += 1;
529 parseLevel(/*HasOpeningBrace=*/ true);
530 Line->Level -= 1;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000531 break;
Nico Weber2afbe522013-02-10 04:38:23 +0000532 }
Nico Weberd74fcdb2013-02-10 20:35:35 +0000533 case tok::at:
534 nextToken();
535 if (FormatTok.Tok.is(tok::l_brace))
536 parseBracedList();
537 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000538 default:
539 nextToken();
540 break;
541 }
542 } while (!eof());
543}
544
545void UnwrappedLineParser::parseIfThenElse() {
546 assert(FormatTok.Tok.is(tok::kw_if) && "'if' expected");
547 nextToken();
Manuel Klimekd4658432013-01-11 18:28:36 +0000548 if (FormatTok.Tok.is(tok::l_paren))
549 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000550 bool NeedsUnwrappedLine = false;
551 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000552 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000553 NeedsUnwrappedLine = true;
554 } else {
555 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000556 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000557 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000558 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000559 }
560 if (FormatTok.Tok.is(tok::kw_else)) {
561 nextToken();
562 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000563 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000564 addUnwrappedLine();
565 } else if (FormatTok.Tok.is(tok::kw_if)) {
566 parseIfThenElse();
567 } else {
568 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000569 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000570 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000571 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000572 }
573 } else if (NeedsUnwrappedLine) {
574 addUnwrappedLine();
575 }
576}
577
Alexander Kornienko15757312012-12-06 18:03:27 +0000578void UnwrappedLineParser::parseNamespace() {
579 assert(FormatTok.Tok.is(tok::kw_namespace) && "'namespace' expected");
580 nextToken();
581 if (FormatTok.Tok.is(tok::identifier))
582 nextToken();
583 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek44135b82013-05-13 12:51:40 +0000584 if (Style.BreakBeforeBraces == FormatStyle::BS_Linux)
585 addUnwrappedLine();
586
Manuel Klimek70b03f42013-01-23 09:32:48 +0000587 parseBlock(/*MustBeDeclaration=*/ true, 0);
Manuel Klimek7fc2db02013-02-06 16:08:09 +0000588 // Munch the semicolon after a namespace. This is more common than one would
589 // think. Puttin the semicolon into its own line is very ugly.
590 if (FormatTok.Tok.is(tok::semi))
591 nextToken();
Alexander Kornienko15757312012-12-06 18:03:27 +0000592 addUnwrappedLine();
593 }
594 // FIXME: Add error handling.
595}
596
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000597void UnwrappedLineParser::parseForOrWhileLoop() {
598 assert((FormatTok.Tok.is(tok::kw_for) || FormatTok.Tok.is(tok::kw_while)) &&
599 "'for' or 'while' expected");
600 nextToken();
Manuel Klimek6eca03f2013-01-11 19:23:05 +0000601 if (FormatTok.Tok.is(tok::l_paren))
602 parseParens();
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000603 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000604 parseBlock(/*MustBeDeclaration=*/ false);
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000605 addUnwrappedLine();
606 } else {
607 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000608 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000609 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000610 --Line->Level;
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000611 }
612}
613
Daniel Jasperbac016b2012-12-03 18:12:45 +0000614void UnwrappedLineParser::parseDoWhile() {
615 assert(FormatTok.Tok.is(tok::kw_do) && "'do' expected");
616 nextToken();
617 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000618 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000619 } else {
620 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000621 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000622 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000623 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000624 }
625
Alexander Kornienko393b0082012-12-04 15:40:36 +0000626 // FIXME: Add error handling.
627 if (!FormatTok.Tok.is(tok::kw_while)) {
628 addUnwrappedLine();
629 return;
630 }
631
Daniel Jasperbac016b2012-12-03 18:12:45 +0000632 nextToken();
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000633 parseStructuralElement();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000634}
635
636void UnwrappedLineParser::parseLabel() {
Daniel Jasper89a0daa2013-02-12 20:17:17 +0000637 if (FormatTok.Tok.isNot(tok::colon))
638 return;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000639 nextToken();
Manuel Klimek526ed112013-01-09 15:25:02 +0000640 unsigned OldLineLevel = Line->Level;
Daniel Jasperbcca7e42013-03-20 10:23:53 +0000641 if (Line->Level > 1 || (!Line->InPPDirective && Line->Level > 0))
Manuel Klimek526ed112013-01-09 15:25:02 +0000642 --Line->Level;
Daniel Jasperc30eb512013-03-19 18:33:58 +0000643 if (CommentsBeforeNextToken.empty() && FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000644 parseBlock(/*MustBeDeclaration=*/ false);
Nico Weber94fb7292013-01-18 05:50:57 +0000645 if (FormatTok.Tok.is(tok::kw_break))
646 parseStructuralElement(); // "break;" after "}" goes on the same line.
Daniel Jasperbac016b2012-12-03 18:12:45 +0000647 }
648 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000649 Line->Level = OldLineLevel;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000650}
651
652void UnwrappedLineParser::parseCaseLabel() {
653 assert(FormatTok.Tok.is(tok::kw_case) && "'case' expected");
654 // FIXME: fix handling of complex expressions here.
655 do {
656 nextToken();
657 } while (!eof() && !FormatTok.Tok.is(tok::colon));
658 parseLabel();
659}
660
661void UnwrappedLineParser::parseSwitch() {
662 assert(FormatTok.Tok.is(tok::kw_switch) && "'switch' expected");
663 nextToken();
Manuel Klimek6eca03f2013-01-11 19:23:05 +0000664 if (FormatTok.Tok.is(tok::l_paren))
665 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000666 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000667 parseBlock(/*MustBeDeclaration=*/ false, Style.IndentCaseLabels ? 2 : 1);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000668 addUnwrappedLine();
669 } else {
670 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000671 Line->Level += (Style.IndentCaseLabels ? 2 : 1);
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000672 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000673 Line->Level -= (Style.IndentCaseLabels ? 2 : 1);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000674 }
675}
676
677void UnwrappedLineParser::parseAccessSpecifier() {
678 nextToken();
Alexander Kornienko56e49c52012-12-10 16:34:48 +0000679 // Otherwise, we don't know what it is, and we'd better keep the next token.
680 if (FormatTok.Tok.is(tok::colon))
681 nextToken();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000682 addUnwrappedLine();
683}
684
685void UnwrappedLineParser::parseEnum() {
Manuel Klimek308232c2013-01-21 19:17:52 +0000686 nextToken();
687 if (FormatTok.Tok.is(tok::identifier) ||
688 FormatTok.Tok.is(tok::kw___attribute) ||
689 FormatTok.Tok.is(tok::kw___declspec)) {
690 nextToken();
691 // We can have macros or attributes in between 'enum' and the enum name.
692 if (FormatTok.Tok.is(tok::l_paren)) {
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000693 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000694 }
Manuel Klimek308232c2013-01-21 19:17:52 +0000695 if (FormatTok.Tok.is(tok::identifier))
696 nextToken();
697 }
698 if (FormatTok.Tok.is(tok::l_brace)) {
699 nextToken();
700 addUnwrappedLine();
701 ++Line->Level;
702 do {
703 switch (FormatTok.Tok.getKind()) {
Manuel Klimek308232c2013-01-21 19:17:52 +0000704 case tok::l_paren:
705 parseParens();
706 break;
707 case tok::r_brace:
708 addUnwrappedLine();
709 nextToken();
710 --Line->Level;
711 return;
712 case tok::comma:
713 nextToken();
714 addUnwrappedLine();
715 break;
716 default:
717 nextToken();
718 break;
719 }
720 } while (!eof());
721 }
722 // We fall through to parsing a structural element afterwards, so that in
723 // enum A {} n, m;
724 // "} n, m;" will end up in one unwrapped line.
Daniel Jasperbac016b2012-12-03 18:12:45 +0000725}
726
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000727void UnwrappedLineParser::parseRecord() {
Manuel Klimekde768542013-01-07 18:10:23 +0000728 nextToken();
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000729 if (FormatTok.Tok.is(tok::identifier) ||
730 FormatTok.Tok.is(tok::kw___attribute) ||
731 FormatTok.Tok.is(tok::kw___declspec)) {
732 nextToken();
733 // We can have macros or attributes in between 'class' and the class name.
734 if (FormatTok.Tok.is(tok::l_paren)) {
735 parseParens();
Manuel Klimekde768542013-01-07 18:10:23 +0000736 }
Manuel Klimekb8b1ce12013-02-06 15:57:54 +0000737 // The actual identifier can be a nested name specifier, and in macros
738 // it is often token-pasted.
Manuel Klimek7f5b0252013-01-21 10:17:14 +0000739 while (FormatTok.Tok.is(tok::identifier) ||
Daniel Jasperf9955d32013-03-20 12:37:50 +0000740 FormatTok.Tok.is(tok::coloncolon) || FormatTok.Tok.is(tok::hashhash))
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000741 nextToken();
742
Manuel Klimek3a3408c2013-01-21 13:58:54 +0000743 // Note that parsing away template declarations here leads to incorrectly
744 // accepting function declarations as record declarations.
745 // In general, we cannot solve this problem. Consider:
746 // class A<int> B() {}
747 // which can be a function definition or a class definition when B() is a
748 // macro. If we find enough real-world cases where this is a problem, we
749 // can parse for the 'template' keyword in the beginning of the statement,
750 // and thus rule out the record production in case there is no template
751 // (this would still leave us with an ambiguity between template function
752 // and class declarations).
753 if (FormatTok.Tok.is(tok::colon) || FormatTok.Tok.is(tok::less)) {
Daniel Jasper6fe554e2013-03-20 15:12:38 +0000754 while (!eof() && FormatTok.Tok.isNot(tok::l_brace)) {
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000755 if (FormatTok.Tok.is(tok::semi))
756 return;
757 nextToken();
758 }
759 }
760 }
Manuel Klimek44135b82013-05-13 12:51:40 +0000761 if (FormatTok.Tok.is(tok::l_brace)) {
762 if (Style.BreakBeforeBraces == FormatStyle::BS_Linux)
763 addUnwrappedLine();
764
Manuel Klimek70b03f42013-01-23 09:32:48 +0000765 parseBlock(/*MustBeDeclaration=*/ true);
Manuel Klimek44135b82013-05-13 12:51:40 +0000766 }
Manuel Klimek3a3408c2013-01-21 13:58:54 +0000767 // We fall through to parsing a structural element afterwards, so
768 // class A {} n, m;
769 // will end up in one unwrapped line.
Manuel Klimekde768542013-01-07 18:10:23 +0000770}
771
Nico Weber1abe6ea2013-01-09 21:15:03 +0000772void UnwrappedLineParser::parseObjCProtocolList() {
773 assert(FormatTok.Tok.is(tok::less) && "'<' expected.");
774 do
775 nextToken();
776 while (!eof() && FormatTok.Tok.isNot(tok::greater));
777 nextToken(); // Skip '>'.
778}
779
780void UnwrappedLineParser::parseObjCUntilAtEnd() {
781 do {
782 if (FormatTok.Tok.isObjCAtKeyword(tok::objc_end)) {
783 nextToken();
784 addUnwrappedLine();
785 break;
786 }
787 parseStructuralElement();
788 } while (!eof());
789}
790
Nico Weber50767d82013-01-09 23:25:37 +0000791void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
Nico Weber27d13672013-01-09 20:25:35 +0000792 nextToken();
Daniel Jasperf9955d32013-03-20 12:37:50 +0000793 nextToken(); // interface name
Nico Weber27d13672013-01-09 20:25:35 +0000794
795 // @interface can be followed by either a base class, or a category.
796 if (FormatTok.Tok.is(tok::colon)) {
797 nextToken();
Daniel Jasperf9955d32013-03-20 12:37:50 +0000798 nextToken(); // base class name
Nico Weber27d13672013-01-09 20:25:35 +0000799 } else if (FormatTok.Tok.is(tok::l_paren))
800 // Skip category, if present.
801 parseParens();
802
Nico Weber1abe6ea2013-01-09 21:15:03 +0000803 if (FormatTok.Tok.is(tok::less))
804 parseObjCProtocolList();
Nico Weber27d13672013-01-09 20:25:35 +0000805
806 // If instance variables are present, keep the '{' on the first line too.
807 if (FormatTok.Tok.is(tok::l_brace))
Manuel Klimek70b03f42013-01-23 09:32:48 +0000808 parseBlock(/*MustBeDeclaration=*/ true);
Nico Weber27d13672013-01-09 20:25:35 +0000809
810 // With instance variables, this puts '}' on its own line. Without instance
811 // variables, this ends the @interface line.
812 addUnwrappedLine();
813
Nico Weber1abe6ea2013-01-09 21:15:03 +0000814 parseObjCUntilAtEnd();
815}
Nico Weber27d13672013-01-09 20:25:35 +0000816
Nico Weber1abe6ea2013-01-09 21:15:03 +0000817void UnwrappedLineParser::parseObjCProtocol() {
818 nextToken();
Daniel Jasperf9955d32013-03-20 12:37:50 +0000819 nextToken(); // protocol name
Nico Weber1abe6ea2013-01-09 21:15:03 +0000820
821 if (FormatTok.Tok.is(tok::less))
822 parseObjCProtocolList();
823
824 // Check for protocol declaration.
825 if (FormatTok.Tok.is(tok::semi)) {
826 nextToken();
827 return addUnwrappedLine();
828 }
829
830 addUnwrappedLine();
831 parseObjCUntilAtEnd();
Nico Weber27d13672013-01-09 20:25:35 +0000832}
833
Daniel Jasperbac016b2012-12-03 18:12:45 +0000834void UnwrappedLineParser::addUnwrappedLine() {
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000835 if (Line->Tokens.empty())
Daniel Jasper26f7e782013-01-08 14:56:18 +0000836 return;
Manuel Klimek8fa37992013-01-16 12:31:12 +0000837 DEBUG({
Manuel Klimeka28fc062013-02-11 12:33:24 +0000838 llvm::dbgs() << "Line(" << Line->Level << ")"
839 << (Line->InPPDirective ? " MACRO" : "") << ": ";
Manuel Klimek8fa37992013-01-16 12:31:12 +0000840 for (std::list<FormatToken>::iterator I = Line->Tokens.begin(),
841 E = Line->Tokens.end();
842 I != E; ++I) {
843 llvm::dbgs() << I->Tok.getName() << " ";
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000844
Manuel Klimek8fa37992013-01-16 12:31:12 +0000845 }
846 llvm::dbgs() << "\n";
847 });
Manuel Klimek525fe162013-01-18 14:04:34 +0000848 CurrentLines->push_back(*Line);
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000849 Line->Tokens.clear();
Manuel Klimek525fe162013-01-18 14:04:34 +0000850 if (CurrentLines == &Lines && !PreprocessorDirectives.empty()) {
Daniel Jasper516fb312013-03-01 18:11:39 +0000851 for (std::vector<UnwrappedLine>::iterator
852 I = PreprocessorDirectives.begin(),
853 E = PreprocessorDirectives.end();
Manuel Klimek525fe162013-01-18 14:04:34 +0000854 I != E; ++I) {
855 CurrentLines->push_back(*I);
856 }
857 PreprocessorDirectives.clear();
858 }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000859}
860
Daniel Jasperf9955d32013-03-20 12:37:50 +0000861bool UnwrappedLineParser::eof() const { return FormatTok.Tok.is(tok::eof); }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000862
Manuel Klimek86721d22013-01-22 16:31:55 +0000863void UnwrappedLineParser::flushComments(bool NewlineBeforeNext) {
864 bool JustComments = Line->Tokens.empty();
865 for (SmallVectorImpl<FormatToken>::const_iterator
866 I = CommentsBeforeNextToken.begin(),
867 E = CommentsBeforeNextToken.end();
868 I != E; ++I) {
Manuel Klimekb3507cd2013-02-06 16:40:56 +0000869 if (I->NewlinesBefore && JustComments) {
Manuel Klimek86721d22013-01-22 16:31:55 +0000870 addUnwrappedLine();
871 }
872 pushToken(*I);
873 }
874 if (NewlineBeforeNext && JustComments) {
875 addUnwrappedLine();
876 }
877 CommentsBeforeNextToken.clear();
878}
879
Daniel Jasperbac016b2012-12-03 18:12:45 +0000880void UnwrappedLineParser::nextToken() {
881 if (eof())
882 return;
Manuel Klimekb3507cd2013-02-06 16:40:56 +0000883 flushComments(FormatTok.NewlinesBefore > 0);
Manuel Klimek86721d22013-01-22 16:31:55 +0000884 pushToken(FormatTok);
Manuel Klimekd4397b92013-01-04 23:34:14 +0000885 readToken();
886}
887
888void UnwrappedLineParser::readToken() {
Manuel Klimek86721d22013-01-22 16:31:55 +0000889 bool CommentsInCurrentLine = true;
890 do {
891 FormatTok = Tokens->getNextToken();
892 while (!Line->InPPDirective && FormatTok.Tok.is(tok::hash) &&
Alexander Kornienko3d713a72013-04-08 22:16:06 +0000893 (FormatTok.HasUnescapedNewline || FormatTok.IsFirst)) {
Manuel Klimek86721d22013-01-22 16:31:55 +0000894 // If there is an unfinished unwrapped line, we flush the preprocessor
895 // directives only after that unwrapped line was finished later.
Daniel Jasperf9955d32013-03-20 12:37:50 +0000896 bool SwitchToPreprocessorLines =
897 !Line->Tokens.empty() && CurrentLines == &Lines;
Manuel Klimek86721d22013-01-22 16:31:55 +0000898 ScopedLineState BlockState(*this, SwitchToPreprocessorLines);
Alexander Kornienko4128e192013-04-03 12:38:53 +0000899 // Comments stored before the preprocessor directive need to be output
900 // before the preprocessor directive, at the same level as the
901 // preprocessor directive, as we consider them to apply to the directive.
902 flushComments(FormatTok.NewlinesBefore > 0);
Manuel Klimek86721d22013-01-22 16:31:55 +0000903 parsePPDirective();
904 }
905 if (!FormatTok.Tok.is(tok::comment))
906 return;
Manuel Klimekb3507cd2013-02-06 16:40:56 +0000907 if (FormatTok.NewlinesBefore > 0 || FormatTok.IsFirst) {
Manuel Klimek86721d22013-01-22 16:31:55 +0000908 CommentsInCurrentLine = false;
909 }
910 if (CommentsInCurrentLine) {
911 pushToken(FormatTok);
912 } else {
913 CommentsBeforeNextToken.push_back(FormatTok);
914 }
915 } while (!eof());
916}
917
918void UnwrappedLineParser::pushToken(const FormatToken &Tok) {
919 Line->Tokens.push_back(Tok);
920 if (MustBreakBeforeNextToken) {
921 Line->Tokens.back().MustBreakBefore = true;
922 MustBreakBeforeNextToken = false;
Manuel Klimekd4397b92013-01-04 23:34:14 +0000923 }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000924}
925
Daniel Jaspercd162382013-01-07 13:26:07 +0000926} // end namespace format
927} // end namespace clang