blob: 9c33e4f484ee9c1a2f9e737761421472925d7e74 [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
Manuel Klimek80829bd2013-05-23 09:41:43 +000075 virtual unsigned getPosition() {
76 return PreviousTokenSource->getPosition();
77 }
78
79 virtual FormatToken setPosition(unsigned Position) {
80 Token = PreviousTokenSource->setPosition(Position);
81 return Token;
82 }
83
Manuel Klimekd4397b92013-01-04 23:34:14 +000084private:
Alexander Kornienko3d713a72013-04-08 22:16:06 +000085 bool eof() { return Token.HasUnescapedNewline; }
Manuel Klimekd4397b92013-01-04 23:34:14 +000086
87 FormatToken createEOF() {
88 FormatToken FormatTok;
89 FormatTok.Tok.startToken();
90 FormatTok.Tok.setKind(tok::eof);
91 return FormatTok;
92 }
93
94 UnwrappedLine &Line;
95 FormatTokenSource *&TokenSource;
96 FormatToken &ResetToken;
Manuel Klimekc37b4d62013-01-05 22:14:16 +000097 unsigned PreviousLineLevel;
Manuel Klimekd4397b92013-01-04 23:34:14 +000098 FormatTokenSource *PreviousTokenSource;
Manuel Klimek67d080d2013-04-12 14:13:36 +000099 bool &StructuralError;
100 bool PreviousStructuralError;
Manuel Klimekd4397b92013-01-04 23:34:14 +0000101
102 FormatToken Token;
103};
104
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000105class ScopedLineState {
106public:
Manuel Klimek525fe162013-01-18 14:04:34 +0000107 ScopedLineState(UnwrappedLineParser &Parser,
108 bool SwitchToPreprocessorLines = false)
109 : Parser(Parser), SwitchToPreprocessorLines(SwitchToPreprocessorLines) {
110 if (SwitchToPreprocessorLines)
111 Parser.CurrentLines = &Parser.PreprocessorDirectives;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000112 PreBlockLine = Parser.Line.take();
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000113 Parser.Line.reset(new UnwrappedLine());
114 Parser.Line->Level = PreBlockLine->Level;
115 Parser.Line->InPPDirective = PreBlockLine->InPPDirective;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000116 }
117
118 ~ScopedLineState() {
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000119 if (!Parser.Line->Tokens.empty()) {
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000120 Parser.addUnwrappedLine();
121 }
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000122 assert(Parser.Line->Tokens.empty());
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000123 Parser.Line.reset(PreBlockLine);
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000124 Parser.MustBreakBeforeNextToken = true;
Manuel Klimek525fe162013-01-18 14:04:34 +0000125 if (SwitchToPreprocessorLines)
126 Parser.CurrentLines = &Parser.Lines;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000127 }
128
129private:
130 UnwrappedLineParser &Parser;
Manuel Klimek525fe162013-01-18 14:04:34 +0000131 const bool SwitchToPreprocessorLines;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000132
133 UnwrappedLine *PreBlockLine;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000134};
135
Manuel Klimek80829bd2013-05-23 09:41:43 +0000136class IndexedTokenSource : public FormatTokenSource {
137public:
138 IndexedTokenSource(ArrayRef<FormatToken> Tokens)
139 : Tokens(Tokens), Position(-1) {}
140
141 virtual FormatToken getNextToken() {
142 ++Position;
143 return Tokens[Position];
144 }
145
146 virtual unsigned getPosition() {
147 assert(Position >= 0);
148 return Position;
149 }
150
151 virtual FormatToken setPosition(unsigned P) {
152 Position = P;
153 return Tokens[Position];
154 }
155
156private:
157 ArrayRef<FormatToken> Tokens;
158 int Position;
159};
160
Daniel Jaspercaf42a32013-05-15 08:14:19 +0000161UnwrappedLineParser::UnwrappedLineParser(const FormatStyle &Style,
162 FormatTokenSource &Tokens,
163 UnwrappedLineConsumer &Callback)
Manuel Klimek525fe162013-01-18 14:04:34 +0000164 : Line(new UnwrappedLine), MustBreakBeforeNextToken(false),
Daniel Jaspercaf42a32013-05-15 08:14:19 +0000165 CurrentLines(&Lines), StructuralError(false), Style(Style),
Manuel Klimek80829bd2013-05-23 09:41:43 +0000166 Tokens(NULL), Callback(Callback) {
167 FormatToken Tok;
168 do {
169 Tok = Tokens.getNextToken();
170 AllTokens.push_back(Tok);
171 } while (Tok.Tok.isNot(tok::eof));
172 LBraces.resize(AllTokens.size(), BS_Unknown);
173}
Daniel Jasperbac016b2012-12-03 18:12:45 +0000174
Alexander Kornienkocff563c2012-12-04 17:27:50 +0000175bool UnwrappedLineParser::parse() {
Manuel Klimek8fa37992013-01-16 12:31:12 +0000176 DEBUG(llvm::dbgs() << "----\n");
Manuel Klimek80829bd2013-05-23 09:41:43 +0000177 IndexedTokenSource TokenSource(AllTokens);
178 Tokens = &TokenSource;
Manuel Klimekd4397b92013-01-04 23:34:14 +0000179 readToken();
Manuel Klimek67d080d2013-04-12 14:13:36 +0000180 parseFile();
Daniel Jasperf9955d32013-03-20 12:37:50 +0000181 for (std::vector<UnwrappedLine>::iterator I = Lines.begin(), E = Lines.end();
Manuel Klimek525fe162013-01-18 14:04:34 +0000182 I != E; ++I) {
183 Callback.consumeUnwrappedLine(*I);
184 }
Daniel Jasper516fb312013-03-01 18:11:39 +0000185
186 // Create line with eof token.
187 pushToken(FormatTok);
188 Callback.consumeUnwrappedLine(*Line);
Manuel Klimek67d080d2013-04-12 14:13:36 +0000189 return StructuralError;
Manuel Klimekd4397b92013-01-04 23:34:14 +0000190}
191
Manuel Klimek67d080d2013-04-12 14:13:36 +0000192void UnwrappedLineParser::parseFile() {
Daniel Jasper627707b2013-03-22 16:55:40 +0000193 ScopedDeclarationState DeclarationState(
194 *Line, DeclarationScopeStack,
195 /*MustBeDeclaration=*/ !Line->InPPDirective);
Manuel Klimek67d080d2013-04-12 14:13:36 +0000196 parseLevel(/*HasOpeningBrace=*/ false);
Manuel Klimekd4397b92013-01-04 23:34:14 +0000197 // Make sure to format the remaining tokens.
Manuel Klimek86721d22013-01-22 16:31:55 +0000198 flushComments(true);
Manuel Klimekd4397b92013-01-04 23:34:14 +0000199 addUnwrappedLine();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000200}
201
Manuel Klimek67d080d2013-04-12 14:13:36 +0000202void UnwrappedLineParser::parseLevel(bool HasOpeningBrace) {
Daniel Jasperbac016b2012-12-03 18:12:45 +0000203 do {
204 switch (FormatTok.Tok.getKind()) {
Daniel Jasperbac016b2012-12-03 18:12:45 +0000205 case tok::comment:
Daniel Jasper05b1ac82012-12-17 11:29:41 +0000206 nextToken();
207 addUnwrappedLine();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000208 break;
209 case tok::l_brace:
Manuel Klimek70b03f42013-01-23 09:32:48 +0000210 // FIXME: Add parameter whether this can happen - if this happens, we must
211 // be in a non-declaration context.
Manuel Klimek67d080d2013-04-12 14:13:36 +0000212 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000213 addUnwrappedLine();
214 break;
215 case tok::r_brace:
Manuel Klimek67d080d2013-04-12 14:13:36 +0000216 if (HasOpeningBrace)
217 return;
Manuel Klimek67d080d2013-04-12 14:13:36 +0000218 StructuralError = true;
219 nextToken();
220 addUnwrappedLine();
Manuel Klimeka5342db2013-01-06 20:07:31 +0000221 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000222 default:
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000223 parseStructuralElement();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000224 break;
225 }
226 } while (!eof());
227}
228
Manuel Klimek80829bd2013-05-23 09:41:43 +0000229void UnwrappedLineParser::calculateBraceTypes() {
230 // We'll parse forward through the tokens until we hit
231 // a closing brace or eof - note that getNextToken() will
232 // parse macros, so this will magically work inside macro
233 // definitions, too.
234 unsigned StoredPosition = Tokens->getPosition();
235 unsigned Position = StoredPosition;
236 FormatToken Tok = FormatTok;
237 // Keep a stack of positions of lbrace tokens. We will
238 // update information about whether an lbrace starts a
239 // braced init list or a different block during the loop.
240 SmallVector<unsigned, 8> LBraceStack;
241 assert(Tok.Tok.is(tok::l_brace));
242 do {
243 FormatToken NextTok = Tokens->getNextToken();
244 switch (Tok.Tok.getKind()) {
245 case tok::l_brace:
246 LBraceStack.push_back(Position);
247 break;
248 case tok::r_brace:
249 if (!LBraceStack.empty()) {
250 if (LBraces[LBraceStack.back()] == BS_Unknown) {
251 // If there is a comma, semicolon or right paren after the closing
252 // brace, we assume this is a braced initializer list.
253
254 // FIXME: Note that this currently works only because we do not
255 // use the brace information while inside a braced init list.
256 // Thus, if the parent is a braced init list, we consider all
257 // brace blocks inside it braced init list. That works good enough
258 // for now, but we will need to fix it to correctly handle lambdas.
259 if (NextTok.Tok.is(tok::comma) || NextTok.Tok.is(tok::semi) ||
260 NextTok.Tok.is(tok::r_paren))
261 LBraces[LBraceStack.back()] = BS_BracedInit;
262 else
263 LBraces[LBraceStack.back()] = BS_Block;
264 }
265 LBraceStack.pop_back();
266 }
267 break;
268 case tok::semi:
269 case tok::kw_if:
270 case tok::kw_while:
271 case tok::kw_for:
272 case tok::kw_switch:
273 case tok::kw_try:
274 if (!LBraceStack.empty())
275 LBraces[LBraceStack.back()] = BS_Block;
276 break;
277 default:
278 break;
279 }
280 Tok = NextTok;
281 ++Position;
282 } while (Tok.Tok.isNot(tok::eof));
283 // Assume other blocks for all unclosed opening braces.
284 for (unsigned i = 0, e = LBraceStack.size(); i != e; ++i) {
285 if (LBraces[LBraceStack[i]] == BS_Unknown)
286 LBraces[LBraceStack[i]] = BS_Block;
287 }
288 FormatTok = Tokens->setPosition(StoredPosition);
289}
290
Manuel Klimek67d080d2013-04-12 14:13:36 +0000291void UnwrappedLineParser::parseBlock(bool MustBeDeclaration,
Nico Weberd74fcdb2013-02-10 20:35:35 +0000292 unsigned AddLevels) {
Alexander Kornienkoa3a2b3a2012-12-06 17:49:17 +0000293 assert(FormatTok.Tok.is(tok::l_brace) && "'{' expected");
Daniel Jasperbac016b2012-12-03 18:12:45 +0000294 nextToken();
295
Manuel Klimek2f1ac412013-01-21 16:42:44 +0000296 addUnwrappedLine();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000297
Manuel Klimek70b03f42013-01-23 09:32:48 +0000298 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
299 MustBeDeclaration);
Manuel Klimek2f1ac412013-01-21 16:42:44 +0000300 Line->Level += AddLevels;
Daniel Jasperf9955d32013-03-20 12:37:50 +0000301 parseLevel(/*HasOpeningBrace=*/ true);
Alexander Kornienko15757312012-12-06 18:03:27 +0000302
Manuel Klimek86721d22013-01-22 16:31:55 +0000303 if (!FormatTok.Tok.is(tok::r_brace)) {
304 Line->Level -= AddLevels;
Manuel Klimek67d080d2013-04-12 14:13:36 +0000305 StructuralError = true;
306 return;
Manuel Klimek86721d22013-01-22 16:31:55 +0000307 }
Alexander Kornienko393b0082012-12-04 15:40:36 +0000308
Daniel Jasperf9955d32013-03-20 12:37:50 +0000309 nextToken(); // Munch the closing brace.
Manuel Klimek86721d22013-01-22 16:31:55 +0000310 Line->Level -= AddLevels;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000311}
312
313void UnwrappedLineParser::parsePPDirective() {
Manuel Klimeka080a182013-01-02 16:30:12 +0000314 assert(FormatTok.Tok.is(tok::hash) && "'#' expected");
Manuel Klimek67d080d2013-04-12 14:13:36 +0000315 ScopedMacroState MacroState(*Line, Tokens, FormatTok, StructuralError);
Manuel Klimeka080a182013-01-02 16:30:12 +0000316 nextToken();
317
Manuel Klimeka080a182013-01-02 16:30:12 +0000318 if (FormatTok.Tok.getIdentifierInfo() == NULL) {
Manuel Klimekbd04f2a2013-01-31 15:58:48 +0000319 parsePPUnknown();
Manuel Klimeka080a182013-01-02 16:30:12 +0000320 return;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000321 }
Manuel Klimeka080a182013-01-02 16:30:12 +0000322
Manuel Klimekd4397b92013-01-04 23:34:14 +0000323 switch (FormatTok.Tok.getIdentifierInfo()->getPPKeywordID()) {
324 case tok::pp_define:
325 parsePPDefine();
326 break;
327 default:
328 parsePPUnknown();
329 break;
330 }
331}
332
333void UnwrappedLineParser::parsePPDefine() {
334 nextToken();
335
336 if (FormatTok.Tok.getKind() != tok::identifier) {
337 parsePPUnknown();
338 return;
339 }
340 nextToken();
Manuel Klimek7ccbc212013-01-23 14:37:36 +0000341 if (FormatTok.Tok.getKind() == tok::l_paren &&
342 FormatTok.WhiteSpaceLength == 0) {
Manuel Klimekd4397b92013-01-04 23:34:14 +0000343 parseParens();
344 }
345 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000346 Line->Level = 1;
Manuel Klimekc3d0c822013-01-07 09:34:28 +0000347
348 // Errors during a preprocessor directive can only affect the layout of the
349 // preprocessor directive, and thus we ignore them. An alternative approach
350 // would be to use the same approach we use on the file level (no
351 // re-indentation if there was a structural error) within the macro
352 // definition.
Manuel Klimekd4397b92013-01-04 23:34:14 +0000353 parseFile();
354}
355
356void UnwrappedLineParser::parsePPUnknown() {
Manuel Klimeka080a182013-01-02 16:30:12 +0000357 do {
Manuel Klimeka080a182013-01-02 16:30:12 +0000358 nextToken();
359 } while (!eof());
360 addUnwrappedLine();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000361}
362
Alexander Kornienko99b0e142013-04-09 16:15:19 +0000363// Here we blacklist certain tokens that are not usually the first token in an
364// unwrapped line. This is used in attempt to distinguish macro calls without
365// trailing semicolons from other constructs split to several lines.
366bool tokenCanStartNewLine(clang::Token Tok) {
367 // Semicolon can be a null-statement, l_square can be a start of a macro or
368 // a C++11 attribute, but this doesn't seem to be common.
369 return Tok.isNot(tok::semi) && Tok.isNot(tok::l_brace) &&
370 Tok.isNot(tok::l_square) &&
371 // Tokens that can only be used as binary operators and a part of
372 // overloaded operator names.
373 Tok.isNot(tok::period) && Tok.isNot(tok::periodstar) &&
374 Tok.isNot(tok::arrow) && Tok.isNot(tok::arrowstar) &&
375 Tok.isNot(tok::less) && Tok.isNot(tok::greater) &&
376 Tok.isNot(tok::slash) && Tok.isNot(tok::percent) &&
377 Tok.isNot(tok::lessless) && Tok.isNot(tok::greatergreater) &&
378 Tok.isNot(tok::equal) && Tok.isNot(tok::plusequal) &&
379 Tok.isNot(tok::minusequal) && Tok.isNot(tok::starequal) &&
380 Tok.isNot(tok::slashequal) && Tok.isNot(tok::percentequal) &&
381 Tok.isNot(tok::ampequal) && Tok.isNot(tok::pipeequal) &&
382 Tok.isNot(tok::caretequal) && Tok.isNot(tok::greatergreaterequal) &&
383 Tok.isNot(tok::lesslessequal) &&
384 // Colon is used in labels, base class lists, initializer lists,
385 // range-based for loops, ternary operator, but should never be the
386 // first token in an unwrapped line.
387 Tok.isNot(tok::colon);
388}
389
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000390void UnwrappedLineParser::parseStructuralElement() {
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000391 assert(!FormatTok.Tok.is(tok::l_brace));
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000392 switch (FormatTok.Tok.getKind()) {
Nico Weber6092d4e2013-01-07 19:05:19 +0000393 case tok::at:
394 nextToken();
Nico Weberd74fcdb2013-02-10 20:35:35 +0000395 if (FormatTok.Tok.is(tok::l_brace)) {
396 parseBracedList();
397 break;
398 }
Nico Weber6092d4e2013-01-07 19:05:19 +0000399 switch (FormatTok.Tok.getObjCKeywordID()) {
400 case tok::objc_public:
401 case tok::objc_protected:
402 case tok::objc_package:
403 case tok::objc_private:
404 return parseAccessSpecifier();
Nico Weber27d13672013-01-09 20:25:35 +0000405 case tok::objc_interface:
Nico Weber50767d82013-01-09 23:25:37 +0000406 case tok::objc_implementation:
407 return parseObjCInterfaceOrImplementation();
Nico Weber1abe6ea2013-01-09 21:15:03 +0000408 case tok::objc_protocol:
409 return parseObjCProtocol();
Nico Weber049c4472013-01-09 21:42:32 +0000410 case tok::objc_end:
411 return; // Handled by the caller.
Nico Weberb530fa32013-01-10 00:25:19 +0000412 case tok::objc_optional:
413 case tok::objc_required:
414 nextToken();
415 addUnwrappedLine();
416 return;
Nico Weber6092d4e2013-01-07 19:05:19 +0000417 default:
418 break;
419 }
420 break;
Alexander Kornienko15757312012-12-06 18:03:27 +0000421 case tok::kw_namespace:
422 parseNamespace();
423 return;
Dmitri Gribenko1f94f2b2012-12-30 21:27:25 +0000424 case tok::kw_inline:
425 nextToken();
Dmitri Gribenko1f94f2b2012-12-30 21:27:25 +0000426 if (FormatTok.Tok.is(tok::kw_namespace)) {
427 parseNamespace();
428 return;
429 }
430 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000431 case tok::kw_public:
432 case tok::kw_protected:
433 case tok::kw_private:
Daniel Jasperbac016b2012-12-03 18:12:45 +0000434 parseAccessSpecifier();
435 return;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000436 case tok::kw_if:
437 parseIfThenElse();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000438 return;
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000439 case tok::kw_for:
440 case tok::kw_while:
441 parseForOrWhileLoop();
442 return;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000443 case tok::kw_do:
444 parseDoWhile();
445 return;
446 case tok::kw_switch:
447 parseSwitch();
448 return;
449 case tok::kw_default:
450 nextToken();
451 parseLabel();
452 return;
453 case tok::kw_case:
454 parseCaseLabel();
455 return;
Manuel Klimekc44ee892013-01-21 10:07:49 +0000456 case tok::kw_return:
457 parseReturn();
458 return;
Manuel Klimekd19dc2d2013-01-21 14:32:05 +0000459 case tok::kw_extern:
460 nextToken();
461 if (FormatTok.Tok.is(tok::string_literal)) {
462 nextToken();
463 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000464 parseBlock(/*MustBeDeclaration=*/ true, 0);
Manuel Klimekd19dc2d2013-01-21 14:32:05 +0000465 addUnwrappedLine();
466 return;
467 }
468 }
469 // In all other cases, parse the declaration.
470 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000471 default:
472 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000473 }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000474 do {
Daniel Jasperbac016b2012-12-03 18:12:45 +0000475 switch (FormatTok.Tok.getKind()) {
Nico Weberd74fcdb2013-02-10 20:35:35 +0000476 case tok::at:
477 nextToken();
478 if (FormatTok.Tok.is(tok::l_brace))
479 parseBracedList();
480 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000481 case tok::kw_enum:
482 parseEnum();
Manuel Klimek308232c2013-01-21 19:17:52 +0000483 break;
Alexander Kornienkod8818752013-01-16 11:43:46 +0000484 case tok::kw_struct:
485 case tok::kw_union:
Manuel Klimekde768542013-01-07 18:10:23 +0000486 case tok::kw_class:
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000487 parseRecord();
488 // A record declaration or definition is always the start of a structural
489 // element.
490 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000491 case tok::semi:
492 nextToken();
493 addUnwrappedLine();
494 return;
Alexander Kornienkod8818752013-01-16 11:43:46 +0000495 case tok::r_brace:
496 addUnwrappedLine();
497 return;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000498 case tok::l_paren:
499 parseParens();
500 break;
501 case tok::l_brace:
Manuel Klimek80829bd2013-05-23 09:41:43 +0000502 if (!tryToParseBracedList()) {
503 // A block outside of parentheses must be the last part of a
504 // structural element.
505 // FIXME: Figure out cases where this is not true, and add projections
506 // for them (the one we know is missing are lambdas).
507 if (Style.BreakBeforeBraces == FormatStyle::BS_Linux ||
508 Style.BreakBeforeBraces == FormatStyle::BS_Stroustrup)
509 addUnwrappedLine();
510 parseBlock(/*MustBeDeclaration=*/ false);
Manuel Klimek44135b82013-05-13 12:51:40 +0000511 addUnwrappedLine();
Manuel Klimek80829bd2013-05-23 09:41:43 +0000512 return;
513 }
514 // Otherwise this was a braced init list, and the structural
515 // element continues.
516 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000517 case tok::identifier:
Daniel Jasperbac016b2012-12-03 18:12:45 +0000518 nextToken();
Alexander Kornienko3d713a72013-04-08 22:16:06 +0000519 if (Line->Tokens.size() == 1) {
520 if (FormatTok.Tok.is(tok::colon)) {
521 parseLabel();
522 return;
523 }
Alexander Kornienko99b0e142013-04-09 16:15:19 +0000524 // Recognize function-like macro usages without trailing semicolon.
Alexander Kornienko3d713a72013-04-08 22:16:06 +0000525 if (FormatTok.Tok.is(tok::l_paren)) {
526 parseParens();
Alexander Kornienko99b0e142013-04-09 16:15:19 +0000527 if (FormatTok.HasUnescapedNewline &&
528 tokenCanStartNewLine(FormatTok.Tok)) {
Alexander Kornienko3d713a72013-04-08 22:16:06 +0000529 addUnwrappedLine();
530 return;
531 }
532 }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000533 }
534 break;
Daniel Jasper05b1ac82012-12-17 11:29:41 +0000535 case tok::equal:
536 nextToken();
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000537 if (FormatTok.Tok.is(tok::l_brace)) {
538 parseBracedList();
539 }
Daniel Jasper05b1ac82012-12-17 11:29:41 +0000540 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000541 default:
542 nextToken();
543 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000544 }
545 } while (!eof());
546}
547
Manuel Klimek80829bd2013-05-23 09:41:43 +0000548bool UnwrappedLineParser::tryToParseBracedList() {
549 if (LBraces[Tokens->getPosition()] == BS_Unknown)
550 calculateBraceTypes();
551 assert(LBraces[Tokens->getPosition()] != BS_Unknown);
552 if (LBraces[Tokens->getPosition()] == BS_Block)
553 return false;
554 parseBracedList();
555 return true;
556}
557
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000558void UnwrappedLineParser::parseBracedList() {
559 nextToken();
560
Manuel Klimek423dd932013-04-10 09:52:05 +0000561 // FIXME: Once we have an expression parser in the UnwrappedLineParser,
562 // replace this by using parseAssigmentExpression() inside.
563 bool StartOfExpression = true;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000564 do {
Manuel Klimek423dd932013-04-10 09:52:05 +0000565 // FIXME: When we start to support lambdas, we'll want to parse them away
566 // here, otherwise our bail-out scenarios below break. The better solution
567 // might be to just implement a more or less complete expression parser.
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000568 switch (FormatTok.Tok.getKind()) {
569 case tok::l_brace:
Manuel Klimek423dd932013-04-10 09:52:05 +0000570 if (!StartOfExpression) {
571 // Probably a missing closing brace. Bail out.
572 addUnwrappedLine();
573 return;
574 }
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000575 parseBracedList();
Manuel Klimek423dd932013-04-10 09:52:05 +0000576 StartOfExpression = false;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000577 break;
578 case tok::r_brace:
579 nextToken();
580 return;
Manuel Klimek423dd932013-04-10 09:52:05 +0000581 case tok::semi:
582 // Probably a missing closing brace. Bail out.
583 return;
584 case tok::comma:
585 nextToken();
586 StartOfExpression = true;
587 break;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000588 default:
589 nextToken();
Manuel Klimek423dd932013-04-10 09:52:05 +0000590 StartOfExpression = false;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000591 break;
592 }
593 } while (!eof());
594}
595
Manuel Klimekc44ee892013-01-21 10:07:49 +0000596void UnwrappedLineParser::parseReturn() {
597 nextToken();
598
599 do {
600 switch (FormatTok.Tok.getKind()) {
601 case tok::l_brace:
602 parseBracedList();
Manuel Klimek423dd932013-04-10 09:52:05 +0000603 if (FormatTok.Tok.isNot(tok::semi)) {
604 // Assume missing ';'.
605 addUnwrappedLine();
606 return;
607 }
Manuel Klimekc44ee892013-01-21 10:07:49 +0000608 break;
609 case tok::l_paren:
610 parseParens();
611 break;
612 case tok::r_brace:
613 // Assume missing ';'.
614 addUnwrappedLine();
615 return;
616 case tok::semi:
617 nextToken();
618 addUnwrappedLine();
619 return;
620 default:
621 nextToken();
622 break;
623 }
624 } while (!eof());
625}
626
Daniel Jasperbac016b2012-12-03 18:12:45 +0000627void UnwrappedLineParser::parseParens() {
628 assert(FormatTok.Tok.is(tok::l_paren) && "'(' expected.");
629 nextToken();
630 do {
631 switch (FormatTok.Tok.getKind()) {
632 case tok::l_paren:
633 parseParens();
634 break;
635 case tok::r_paren:
636 nextToken();
637 return;
Nico Weber2afbe522013-02-10 04:38:23 +0000638 case tok::l_brace: {
Manuel Klimek80829bd2013-05-23 09:41:43 +0000639 if (!tryToParseBracedList()) {
640 nextToken();
641 ScopedLineState LineState(*this);
642 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
643 /*MustBeDeclaration=*/ false);
644 Line->Level += 1;
645 parseLevel(/*HasOpeningBrace=*/ true);
646 Line->Level -= 1;
647 }
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000648 break;
Nico Weber2afbe522013-02-10 04:38:23 +0000649 }
Nico Weberd74fcdb2013-02-10 20:35:35 +0000650 case tok::at:
651 nextToken();
652 if (FormatTok.Tok.is(tok::l_brace))
653 parseBracedList();
654 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000655 default:
656 nextToken();
657 break;
658 }
659 } while (!eof());
660}
661
662void UnwrappedLineParser::parseIfThenElse() {
663 assert(FormatTok.Tok.is(tok::kw_if) && "'if' expected");
664 nextToken();
Manuel Klimekd4658432013-01-11 18:28:36 +0000665 if (FormatTok.Tok.is(tok::l_paren))
666 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000667 bool NeedsUnwrappedLine = false;
668 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000669 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000670 NeedsUnwrappedLine = true;
671 } else {
672 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000673 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000674 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000675 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000676 }
677 if (FormatTok.Tok.is(tok::kw_else)) {
678 nextToken();
679 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000680 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000681 addUnwrappedLine();
682 } else if (FormatTok.Tok.is(tok::kw_if)) {
683 parseIfThenElse();
684 } else {
685 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000686 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000687 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000688 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000689 }
690 } else if (NeedsUnwrappedLine) {
691 addUnwrappedLine();
692 }
693}
694
Alexander Kornienko15757312012-12-06 18:03:27 +0000695void UnwrappedLineParser::parseNamespace() {
696 assert(FormatTok.Tok.is(tok::kw_namespace) && "'namespace' expected");
697 nextToken();
698 if (FormatTok.Tok.is(tok::identifier))
699 nextToken();
700 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek44135b82013-05-13 12:51:40 +0000701 if (Style.BreakBeforeBraces == FormatStyle::BS_Linux)
702 addUnwrappedLine();
703
Manuel Klimek70b03f42013-01-23 09:32:48 +0000704 parseBlock(/*MustBeDeclaration=*/ true, 0);
Manuel Klimek7fc2db02013-02-06 16:08:09 +0000705 // Munch the semicolon after a namespace. This is more common than one would
706 // think. Puttin the semicolon into its own line is very ugly.
707 if (FormatTok.Tok.is(tok::semi))
708 nextToken();
Alexander Kornienko15757312012-12-06 18:03:27 +0000709 addUnwrappedLine();
710 }
711 // FIXME: Add error handling.
712}
713
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000714void UnwrappedLineParser::parseForOrWhileLoop() {
715 assert((FormatTok.Tok.is(tok::kw_for) || FormatTok.Tok.is(tok::kw_while)) &&
716 "'for' or 'while' expected");
717 nextToken();
Manuel Klimek6eca03f2013-01-11 19:23:05 +0000718 if (FormatTok.Tok.is(tok::l_paren))
719 parseParens();
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000720 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000721 parseBlock(/*MustBeDeclaration=*/ false);
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000722 addUnwrappedLine();
723 } else {
724 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000725 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000726 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000727 --Line->Level;
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000728 }
729}
730
Daniel Jasperbac016b2012-12-03 18:12:45 +0000731void UnwrappedLineParser::parseDoWhile() {
732 assert(FormatTok.Tok.is(tok::kw_do) && "'do' expected");
733 nextToken();
734 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000735 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000736 } else {
737 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000738 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000739 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000740 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000741 }
742
Alexander Kornienko393b0082012-12-04 15:40:36 +0000743 // FIXME: Add error handling.
744 if (!FormatTok.Tok.is(tok::kw_while)) {
745 addUnwrappedLine();
746 return;
747 }
748
Daniel Jasperbac016b2012-12-03 18:12:45 +0000749 nextToken();
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000750 parseStructuralElement();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000751}
752
753void UnwrappedLineParser::parseLabel() {
Daniel Jasper89a0daa2013-02-12 20:17:17 +0000754 if (FormatTok.Tok.isNot(tok::colon))
755 return;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000756 nextToken();
Manuel Klimek526ed112013-01-09 15:25:02 +0000757 unsigned OldLineLevel = Line->Level;
Daniel Jasperbcca7e42013-03-20 10:23:53 +0000758 if (Line->Level > 1 || (!Line->InPPDirective && Line->Level > 0))
Manuel Klimek526ed112013-01-09 15:25:02 +0000759 --Line->Level;
Daniel Jasperc30eb512013-03-19 18:33:58 +0000760 if (CommentsBeforeNextToken.empty() && FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000761 parseBlock(/*MustBeDeclaration=*/ false);
Nico Weber94fb7292013-01-18 05:50:57 +0000762 if (FormatTok.Tok.is(tok::kw_break))
763 parseStructuralElement(); // "break;" after "}" goes on the same line.
Daniel Jasperbac016b2012-12-03 18:12:45 +0000764 }
765 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000766 Line->Level = OldLineLevel;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000767}
768
769void UnwrappedLineParser::parseCaseLabel() {
770 assert(FormatTok.Tok.is(tok::kw_case) && "'case' expected");
771 // FIXME: fix handling of complex expressions here.
772 do {
773 nextToken();
774 } while (!eof() && !FormatTok.Tok.is(tok::colon));
775 parseLabel();
776}
777
778void UnwrappedLineParser::parseSwitch() {
779 assert(FormatTok.Tok.is(tok::kw_switch) && "'switch' expected");
780 nextToken();
Manuel Klimek6eca03f2013-01-11 19:23:05 +0000781 if (FormatTok.Tok.is(tok::l_paren))
782 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000783 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000784 parseBlock(/*MustBeDeclaration=*/ false, Style.IndentCaseLabels ? 2 : 1);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000785 addUnwrappedLine();
786 } else {
787 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000788 Line->Level += (Style.IndentCaseLabels ? 2 : 1);
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000789 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000790 Line->Level -= (Style.IndentCaseLabels ? 2 : 1);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000791 }
792}
793
794void UnwrappedLineParser::parseAccessSpecifier() {
795 nextToken();
Alexander Kornienko56e49c52012-12-10 16:34:48 +0000796 // Otherwise, we don't know what it is, and we'd better keep the next token.
797 if (FormatTok.Tok.is(tok::colon))
798 nextToken();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000799 addUnwrappedLine();
800}
801
802void UnwrappedLineParser::parseEnum() {
Manuel Klimek308232c2013-01-21 19:17:52 +0000803 nextToken();
804 if (FormatTok.Tok.is(tok::identifier) ||
805 FormatTok.Tok.is(tok::kw___attribute) ||
806 FormatTok.Tok.is(tok::kw___declspec)) {
807 nextToken();
808 // We can have macros or attributes in between 'enum' and the enum name.
809 if (FormatTok.Tok.is(tok::l_paren)) {
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000810 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000811 }
Manuel Klimek308232c2013-01-21 19:17:52 +0000812 if (FormatTok.Tok.is(tok::identifier))
813 nextToken();
814 }
815 if (FormatTok.Tok.is(tok::l_brace)) {
816 nextToken();
817 addUnwrappedLine();
818 ++Line->Level;
819 do {
820 switch (FormatTok.Tok.getKind()) {
Manuel Klimek308232c2013-01-21 19:17:52 +0000821 case tok::l_paren:
822 parseParens();
823 break;
824 case tok::r_brace:
825 addUnwrappedLine();
826 nextToken();
827 --Line->Level;
828 return;
829 case tok::comma:
830 nextToken();
831 addUnwrappedLine();
832 break;
833 default:
834 nextToken();
835 break;
836 }
837 } while (!eof());
838 }
839 // We fall through to parsing a structural element afterwards, so that in
840 // enum A {} n, m;
841 // "} n, m;" will end up in one unwrapped line.
Daniel Jasperbac016b2012-12-03 18:12:45 +0000842}
843
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000844void UnwrappedLineParser::parseRecord() {
Manuel Klimekde768542013-01-07 18:10:23 +0000845 nextToken();
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000846 if (FormatTok.Tok.is(tok::identifier) ||
847 FormatTok.Tok.is(tok::kw___attribute) ||
848 FormatTok.Tok.is(tok::kw___declspec)) {
849 nextToken();
850 // We can have macros or attributes in between 'class' and the class name.
851 if (FormatTok.Tok.is(tok::l_paren)) {
852 parseParens();
Manuel Klimekde768542013-01-07 18:10:23 +0000853 }
Manuel Klimekb8b1ce12013-02-06 15:57:54 +0000854 // The actual identifier can be a nested name specifier, and in macros
855 // it is often token-pasted.
Manuel Klimek7f5b0252013-01-21 10:17:14 +0000856 while (FormatTok.Tok.is(tok::identifier) ||
Daniel Jasperf9955d32013-03-20 12:37:50 +0000857 FormatTok.Tok.is(tok::coloncolon) || FormatTok.Tok.is(tok::hashhash))
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000858 nextToken();
859
Manuel Klimek3a3408c2013-01-21 13:58:54 +0000860 // Note that parsing away template declarations here leads to incorrectly
861 // accepting function declarations as record declarations.
862 // In general, we cannot solve this problem. Consider:
863 // class A<int> B() {}
864 // which can be a function definition or a class definition when B() is a
865 // macro. If we find enough real-world cases where this is a problem, we
866 // can parse for the 'template' keyword in the beginning of the statement,
867 // and thus rule out the record production in case there is no template
868 // (this would still leave us with an ambiguity between template function
869 // and class declarations).
870 if (FormatTok.Tok.is(tok::colon) || FormatTok.Tok.is(tok::less)) {
Daniel Jasper6fe554e2013-03-20 15:12:38 +0000871 while (!eof() && FormatTok.Tok.isNot(tok::l_brace)) {
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000872 if (FormatTok.Tok.is(tok::semi))
873 return;
874 nextToken();
875 }
876 }
877 }
Manuel Klimek44135b82013-05-13 12:51:40 +0000878 if (FormatTok.Tok.is(tok::l_brace)) {
879 if (Style.BreakBeforeBraces == FormatStyle::BS_Linux)
880 addUnwrappedLine();
881
Manuel Klimek70b03f42013-01-23 09:32:48 +0000882 parseBlock(/*MustBeDeclaration=*/ true);
Manuel Klimek44135b82013-05-13 12:51:40 +0000883 }
Manuel Klimek3a3408c2013-01-21 13:58:54 +0000884 // We fall through to parsing a structural element afterwards, so
885 // class A {} n, m;
886 // will end up in one unwrapped line.
Manuel Klimekde768542013-01-07 18:10:23 +0000887}
888
Nico Weber1abe6ea2013-01-09 21:15:03 +0000889void UnwrappedLineParser::parseObjCProtocolList() {
890 assert(FormatTok.Tok.is(tok::less) && "'<' expected.");
891 do
892 nextToken();
893 while (!eof() && FormatTok.Tok.isNot(tok::greater));
894 nextToken(); // Skip '>'.
895}
896
897void UnwrappedLineParser::parseObjCUntilAtEnd() {
898 do {
899 if (FormatTok.Tok.isObjCAtKeyword(tok::objc_end)) {
900 nextToken();
901 addUnwrappedLine();
902 break;
903 }
904 parseStructuralElement();
905 } while (!eof());
906}
907
Nico Weber50767d82013-01-09 23:25:37 +0000908void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
Nico Weber27d13672013-01-09 20:25:35 +0000909 nextToken();
Daniel Jasperf9955d32013-03-20 12:37:50 +0000910 nextToken(); // interface name
Nico Weber27d13672013-01-09 20:25:35 +0000911
912 // @interface can be followed by either a base class, or a category.
913 if (FormatTok.Tok.is(tok::colon)) {
914 nextToken();
Daniel Jasperf9955d32013-03-20 12:37:50 +0000915 nextToken(); // base class name
Nico Weber27d13672013-01-09 20:25:35 +0000916 } else if (FormatTok.Tok.is(tok::l_paren))
917 // Skip category, if present.
918 parseParens();
919
Nico Weber1abe6ea2013-01-09 21:15:03 +0000920 if (FormatTok.Tok.is(tok::less))
921 parseObjCProtocolList();
Nico Weber27d13672013-01-09 20:25:35 +0000922
923 // If instance variables are present, keep the '{' on the first line too.
924 if (FormatTok.Tok.is(tok::l_brace))
Manuel Klimek70b03f42013-01-23 09:32:48 +0000925 parseBlock(/*MustBeDeclaration=*/ true);
Nico Weber27d13672013-01-09 20:25:35 +0000926
927 // With instance variables, this puts '}' on its own line. Without instance
928 // variables, this ends the @interface line.
929 addUnwrappedLine();
930
Nico Weber1abe6ea2013-01-09 21:15:03 +0000931 parseObjCUntilAtEnd();
932}
Nico Weber27d13672013-01-09 20:25:35 +0000933
Nico Weber1abe6ea2013-01-09 21:15:03 +0000934void UnwrappedLineParser::parseObjCProtocol() {
935 nextToken();
Daniel Jasperf9955d32013-03-20 12:37:50 +0000936 nextToken(); // protocol name
Nico Weber1abe6ea2013-01-09 21:15:03 +0000937
938 if (FormatTok.Tok.is(tok::less))
939 parseObjCProtocolList();
940
941 // Check for protocol declaration.
942 if (FormatTok.Tok.is(tok::semi)) {
943 nextToken();
944 return addUnwrappedLine();
945 }
946
947 addUnwrappedLine();
948 parseObjCUntilAtEnd();
Nico Weber27d13672013-01-09 20:25:35 +0000949}
950
Daniel Jasperbac016b2012-12-03 18:12:45 +0000951void UnwrappedLineParser::addUnwrappedLine() {
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000952 if (Line->Tokens.empty())
Daniel Jasper26f7e782013-01-08 14:56:18 +0000953 return;
Manuel Klimek8fa37992013-01-16 12:31:12 +0000954 DEBUG({
Manuel Klimeka28fc062013-02-11 12:33:24 +0000955 llvm::dbgs() << "Line(" << Line->Level << ")"
956 << (Line->InPPDirective ? " MACRO" : "") << ": ";
Manuel Klimek8fa37992013-01-16 12:31:12 +0000957 for (std::list<FormatToken>::iterator I = Line->Tokens.begin(),
958 E = Line->Tokens.end();
959 I != E; ++I) {
960 llvm::dbgs() << I->Tok.getName() << " ";
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000961
Manuel Klimek8fa37992013-01-16 12:31:12 +0000962 }
963 llvm::dbgs() << "\n";
964 });
Manuel Klimek525fe162013-01-18 14:04:34 +0000965 CurrentLines->push_back(*Line);
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000966 Line->Tokens.clear();
Manuel Klimek525fe162013-01-18 14:04:34 +0000967 if (CurrentLines == &Lines && !PreprocessorDirectives.empty()) {
Daniel Jasper516fb312013-03-01 18:11:39 +0000968 for (std::vector<UnwrappedLine>::iterator
969 I = PreprocessorDirectives.begin(),
970 E = PreprocessorDirectives.end();
Manuel Klimek525fe162013-01-18 14:04:34 +0000971 I != E; ++I) {
972 CurrentLines->push_back(*I);
973 }
974 PreprocessorDirectives.clear();
975 }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000976}
977
Daniel Jasperf9955d32013-03-20 12:37:50 +0000978bool UnwrappedLineParser::eof() const { return FormatTok.Tok.is(tok::eof); }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000979
Manuel Klimek86721d22013-01-22 16:31:55 +0000980void UnwrappedLineParser::flushComments(bool NewlineBeforeNext) {
981 bool JustComments = Line->Tokens.empty();
982 for (SmallVectorImpl<FormatToken>::const_iterator
983 I = CommentsBeforeNextToken.begin(),
984 E = CommentsBeforeNextToken.end();
985 I != E; ++I) {
Manuel Klimekb3507cd2013-02-06 16:40:56 +0000986 if (I->NewlinesBefore && JustComments) {
Manuel Klimek86721d22013-01-22 16:31:55 +0000987 addUnwrappedLine();
988 }
989 pushToken(*I);
990 }
991 if (NewlineBeforeNext && JustComments) {
992 addUnwrappedLine();
993 }
994 CommentsBeforeNextToken.clear();
995}
996
Daniel Jasperbac016b2012-12-03 18:12:45 +0000997void UnwrappedLineParser::nextToken() {
998 if (eof())
999 return;
Manuel Klimekb3507cd2013-02-06 16:40:56 +00001000 flushComments(FormatTok.NewlinesBefore > 0);
Manuel Klimek86721d22013-01-22 16:31:55 +00001001 pushToken(FormatTok);
Manuel Klimekd4397b92013-01-04 23:34:14 +00001002 readToken();
1003}
1004
1005void UnwrappedLineParser::readToken() {
Manuel Klimek86721d22013-01-22 16:31:55 +00001006 bool CommentsInCurrentLine = true;
1007 do {
1008 FormatTok = Tokens->getNextToken();
1009 while (!Line->InPPDirective && FormatTok.Tok.is(tok::hash) &&
Alexander Kornienko3d713a72013-04-08 22:16:06 +00001010 (FormatTok.HasUnescapedNewline || FormatTok.IsFirst)) {
Manuel Klimek86721d22013-01-22 16:31:55 +00001011 // If there is an unfinished unwrapped line, we flush the preprocessor
1012 // directives only after that unwrapped line was finished later.
Daniel Jasperf9955d32013-03-20 12:37:50 +00001013 bool SwitchToPreprocessorLines =
1014 !Line->Tokens.empty() && CurrentLines == &Lines;
Manuel Klimek86721d22013-01-22 16:31:55 +00001015 ScopedLineState BlockState(*this, SwitchToPreprocessorLines);
Alexander Kornienko4128e192013-04-03 12:38:53 +00001016 // Comments stored before the preprocessor directive need to be output
1017 // before the preprocessor directive, at the same level as the
1018 // preprocessor directive, as we consider them to apply to the directive.
1019 flushComments(FormatTok.NewlinesBefore > 0);
Manuel Klimek86721d22013-01-22 16:31:55 +00001020 parsePPDirective();
1021 }
1022 if (!FormatTok.Tok.is(tok::comment))
1023 return;
Manuel Klimekb3507cd2013-02-06 16:40:56 +00001024 if (FormatTok.NewlinesBefore > 0 || FormatTok.IsFirst) {
Manuel Klimek86721d22013-01-22 16:31:55 +00001025 CommentsInCurrentLine = false;
1026 }
1027 if (CommentsInCurrentLine) {
1028 pushToken(FormatTok);
1029 } else {
1030 CommentsBeforeNextToken.push_back(FormatTok);
1031 }
1032 } while (!eof());
1033}
1034
1035void UnwrappedLineParser::pushToken(const FormatToken &Tok) {
1036 Line->Tokens.push_back(Tok);
1037 if (MustBreakBeforeNextToken) {
1038 Line->Tokens.back().MustBreakBefore = true;
1039 MustBreakBeforeNextToken = false;
Manuel Klimekd4397b92013-01-04 23:34:14 +00001040 }
Daniel Jasperbac016b2012-12-03 18:12:45 +00001041}
1042
Daniel Jaspercd162382013-01-07 13:26:07 +00001043} // end namespace format
1044} // end namespace clang