blob: aaed97c30205150a92ff0cf644c990d5585d3444 [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) ||
Daniel Jasperde0d61f2013-05-23 18:29:16 +0000260 NextTok.Tok.is(tok::r_paren) || NextTok.Tok.is(tok::l_brace))
Manuel Klimek80829bd2013-05-23 09:41:43 +0000261 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();
Alexander Kornienko6fb46b02013-05-24 18:24:24 +0000326 return;
327 case tok::pp_if:
328 parsePPIf();
329 break;
330 case tok::pp_ifdef:
331 case tok::pp_ifndef:
332 parsePPIfdef();
333 break;
334 case tok::pp_else:
335 parsePPElse();
336 break;
337 case tok::pp_elif:
338 parsePPElIf();
339 break;
340 case tok::pp_endif:
341 parsePPEndIf();
Manuel Klimekd4397b92013-01-04 23:34:14 +0000342 break;
343 default:
344 parsePPUnknown();
345 break;
346 }
347}
348
Alexander Kornienko6fb46b02013-05-24 18:24:24 +0000349void UnwrappedLineParser::pushPPConditional() {
350 if (!PPStack.empty() && PPStack.back() == PP_Unreachable)
351 PPStack.push_back(PP_Unreachable);
352 else
353 PPStack.push_back(PP_Conditional);
354}
355
356void UnwrappedLineParser::parsePPIf() {
357 nextToken();
358 if ((FormatTok.Tok.isLiteral() &&
359 StringRef(FormatTok.Tok.getLiteralData(), FormatTok.Tok.getLength()) ==
360 "0") ||
361 FormatTok.Tok.is(tok::kw_false)) {
362 PPStack.push_back(PP_Unreachable);
363 } else {
364 pushPPConditional();
365 }
366 parsePPUnknown();
367}
368
369void UnwrappedLineParser::parsePPIfdef() {
370 pushPPConditional();
371 parsePPUnknown();
372}
373
374void UnwrappedLineParser::parsePPElse() {
375 if (!PPStack.empty())
376 PPStack.pop_back();
377 pushPPConditional();
378 parsePPUnknown();
379}
380
381void UnwrappedLineParser::parsePPElIf() {
382 parsePPElse();
383}
384
385void UnwrappedLineParser::parsePPEndIf() {
386 if (!PPStack.empty())
387 PPStack.pop_back();
388 parsePPUnknown();
389}
390
Manuel Klimekd4397b92013-01-04 23:34:14 +0000391void UnwrappedLineParser::parsePPDefine() {
392 nextToken();
393
394 if (FormatTok.Tok.getKind() != tok::identifier) {
395 parsePPUnknown();
396 return;
397 }
398 nextToken();
Manuel Klimek7ccbc212013-01-23 14:37:36 +0000399 if (FormatTok.Tok.getKind() == tok::l_paren &&
Manuel Klimekad3094b2013-05-23 10:56:37 +0000400 FormatTok.WhitespaceRange.getBegin() ==
401 FormatTok.WhitespaceRange.getEnd()) {
Manuel Klimekd4397b92013-01-04 23:34:14 +0000402 parseParens();
403 }
404 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000405 Line->Level = 1;
Manuel Klimekc3d0c822013-01-07 09:34:28 +0000406
407 // Errors during a preprocessor directive can only affect the layout of the
408 // preprocessor directive, and thus we ignore them. An alternative approach
409 // would be to use the same approach we use on the file level (no
410 // re-indentation if there was a structural error) within the macro
411 // definition.
Manuel Klimekd4397b92013-01-04 23:34:14 +0000412 parseFile();
413}
414
415void UnwrappedLineParser::parsePPUnknown() {
Manuel Klimeka080a182013-01-02 16:30:12 +0000416 do {
Manuel Klimeka080a182013-01-02 16:30:12 +0000417 nextToken();
418 } while (!eof());
419 addUnwrappedLine();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000420}
421
Alexander Kornienko99b0e142013-04-09 16:15:19 +0000422// Here we blacklist certain tokens that are not usually the first token in an
423// unwrapped line. This is used in attempt to distinguish macro calls without
424// trailing semicolons from other constructs split to several lines.
425bool tokenCanStartNewLine(clang::Token Tok) {
426 // Semicolon can be a null-statement, l_square can be a start of a macro or
427 // a C++11 attribute, but this doesn't seem to be common.
428 return Tok.isNot(tok::semi) && Tok.isNot(tok::l_brace) &&
429 Tok.isNot(tok::l_square) &&
430 // Tokens that can only be used as binary operators and a part of
431 // overloaded operator names.
432 Tok.isNot(tok::period) && Tok.isNot(tok::periodstar) &&
433 Tok.isNot(tok::arrow) && Tok.isNot(tok::arrowstar) &&
434 Tok.isNot(tok::less) && Tok.isNot(tok::greater) &&
435 Tok.isNot(tok::slash) && Tok.isNot(tok::percent) &&
436 Tok.isNot(tok::lessless) && Tok.isNot(tok::greatergreater) &&
437 Tok.isNot(tok::equal) && Tok.isNot(tok::plusequal) &&
438 Tok.isNot(tok::minusequal) && Tok.isNot(tok::starequal) &&
439 Tok.isNot(tok::slashequal) && Tok.isNot(tok::percentequal) &&
440 Tok.isNot(tok::ampequal) && Tok.isNot(tok::pipeequal) &&
441 Tok.isNot(tok::caretequal) && Tok.isNot(tok::greatergreaterequal) &&
442 Tok.isNot(tok::lesslessequal) &&
443 // Colon is used in labels, base class lists, initializer lists,
444 // range-based for loops, ternary operator, but should never be the
445 // first token in an unwrapped line.
446 Tok.isNot(tok::colon);
447}
448
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000449void UnwrappedLineParser::parseStructuralElement() {
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000450 assert(!FormatTok.Tok.is(tok::l_brace));
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000451 switch (FormatTok.Tok.getKind()) {
Nico Weber6092d4e2013-01-07 19:05:19 +0000452 case tok::at:
453 nextToken();
Nico Weberd74fcdb2013-02-10 20:35:35 +0000454 if (FormatTok.Tok.is(tok::l_brace)) {
455 parseBracedList();
456 break;
457 }
Nico Weber6092d4e2013-01-07 19:05:19 +0000458 switch (FormatTok.Tok.getObjCKeywordID()) {
459 case tok::objc_public:
460 case tok::objc_protected:
461 case tok::objc_package:
462 case tok::objc_private:
463 return parseAccessSpecifier();
Nico Weber27d13672013-01-09 20:25:35 +0000464 case tok::objc_interface:
Nico Weber50767d82013-01-09 23:25:37 +0000465 case tok::objc_implementation:
466 return parseObjCInterfaceOrImplementation();
Nico Weber1abe6ea2013-01-09 21:15:03 +0000467 case tok::objc_protocol:
468 return parseObjCProtocol();
Nico Weber049c4472013-01-09 21:42:32 +0000469 case tok::objc_end:
470 return; // Handled by the caller.
Nico Weberb530fa32013-01-10 00:25:19 +0000471 case tok::objc_optional:
472 case tok::objc_required:
473 nextToken();
474 addUnwrappedLine();
475 return;
Nico Weber6092d4e2013-01-07 19:05:19 +0000476 default:
477 break;
478 }
479 break;
Alexander Kornienko15757312012-12-06 18:03:27 +0000480 case tok::kw_namespace:
481 parseNamespace();
482 return;
Dmitri Gribenko1f94f2b2012-12-30 21:27:25 +0000483 case tok::kw_inline:
484 nextToken();
Dmitri Gribenko1f94f2b2012-12-30 21:27:25 +0000485 if (FormatTok.Tok.is(tok::kw_namespace)) {
486 parseNamespace();
487 return;
488 }
489 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000490 case tok::kw_public:
491 case tok::kw_protected:
492 case tok::kw_private:
Daniel Jasperbac016b2012-12-03 18:12:45 +0000493 parseAccessSpecifier();
494 return;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000495 case tok::kw_if:
496 parseIfThenElse();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000497 return;
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000498 case tok::kw_for:
499 case tok::kw_while:
500 parseForOrWhileLoop();
501 return;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000502 case tok::kw_do:
503 parseDoWhile();
504 return;
505 case tok::kw_switch:
506 parseSwitch();
507 return;
508 case tok::kw_default:
509 nextToken();
510 parseLabel();
511 return;
512 case tok::kw_case:
513 parseCaseLabel();
514 return;
Manuel Klimekc44ee892013-01-21 10:07:49 +0000515 case tok::kw_return:
516 parseReturn();
517 return;
Manuel Klimekd19dc2d2013-01-21 14:32:05 +0000518 case tok::kw_extern:
519 nextToken();
520 if (FormatTok.Tok.is(tok::string_literal)) {
521 nextToken();
522 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000523 parseBlock(/*MustBeDeclaration=*/ true, 0);
Manuel Klimekd19dc2d2013-01-21 14:32:05 +0000524 addUnwrappedLine();
525 return;
526 }
527 }
528 // In all other cases, parse the declaration.
529 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000530 default:
531 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000532 }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000533 do {
Daniel Jasperbac016b2012-12-03 18:12:45 +0000534 switch (FormatTok.Tok.getKind()) {
Nico Weberd74fcdb2013-02-10 20:35:35 +0000535 case tok::at:
536 nextToken();
537 if (FormatTok.Tok.is(tok::l_brace))
538 parseBracedList();
539 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000540 case tok::kw_enum:
541 parseEnum();
Manuel Klimek308232c2013-01-21 19:17:52 +0000542 break;
Alexander Kornienkod8818752013-01-16 11:43:46 +0000543 case tok::kw_struct:
544 case tok::kw_union:
Manuel Klimekde768542013-01-07 18:10:23 +0000545 case tok::kw_class:
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000546 parseRecord();
547 // A record declaration or definition is always the start of a structural
548 // element.
549 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000550 case tok::semi:
551 nextToken();
552 addUnwrappedLine();
553 return;
Alexander Kornienkod8818752013-01-16 11:43:46 +0000554 case tok::r_brace:
555 addUnwrappedLine();
556 return;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000557 case tok::l_paren:
558 parseParens();
559 break;
560 case tok::l_brace:
Manuel Klimek80829bd2013-05-23 09:41:43 +0000561 if (!tryToParseBracedList()) {
562 // A block outside of parentheses must be the last part of a
563 // structural element.
564 // FIXME: Figure out cases where this is not true, and add projections
565 // for them (the one we know is missing are lambdas).
566 if (Style.BreakBeforeBraces == FormatStyle::BS_Linux ||
567 Style.BreakBeforeBraces == FormatStyle::BS_Stroustrup)
568 addUnwrappedLine();
569 parseBlock(/*MustBeDeclaration=*/ false);
Manuel Klimek44135b82013-05-13 12:51:40 +0000570 addUnwrappedLine();
Manuel Klimek80829bd2013-05-23 09:41:43 +0000571 return;
572 }
573 // Otherwise this was a braced init list, and the structural
574 // element continues.
575 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000576 case tok::identifier:
Daniel Jasperbac016b2012-12-03 18:12:45 +0000577 nextToken();
Alexander Kornienko3d713a72013-04-08 22:16:06 +0000578 if (Line->Tokens.size() == 1) {
579 if (FormatTok.Tok.is(tok::colon)) {
580 parseLabel();
581 return;
582 }
Alexander Kornienko99b0e142013-04-09 16:15:19 +0000583 // Recognize function-like macro usages without trailing semicolon.
Alexander Kornienko3d713a72013-04-08 22:16:06 +0000584 if (FormatTok.Tok.is(tok::l_paren)) {
585 parseParens();
Alexander Kornienko99b0e142013-04-09 16:15:19 +0000586 if (FormatTok.HasUnescapedNewline &&
587 tokenCanStartNewLine(FormatTok.Tok)) {
Alexander Kornienko3d713a72013-04-08 22:16:06 +0000588 addUnwrappedLine();
589 return;
590 }
591 }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000592 }
593 break;
Daniel Jasper05b1ac82012-12-17 11:29:41 +0000594 case tok::equal:
595 nextToken();
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000596 if (FormatTok.Tok.is(tok::l_brace)) {
597 parseBracedList();
598 }
Daniel Jasper05b1ac82012-12-17 11:29:41 +0000599 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000600 default:
601 nextToken();
602 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000603 }
604 } while (!eof());
605}
606
Manuel Klimek80829bd2013-05-23 09:41:43 +0000607bool UnwrappedLineParser::tryToParseBracedList() {
608 if (LBraces[Tokens->getPosition()] == BS_Unknown)
609 calculateBraceTypes();
610 assert(LBraces[Tokens->getPosition()] != BS_Unknown);
611 if (LBraces[Tokens->getPosition()] == BS_Block)
612 return false;
613 parseBracedList();
614 return true;
615}
616
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000617void UnwrappedLineParser::parseBracedList() {
618 nextToken();
619
Manuel Klimek423dd932013-04-10 09:52:05 +0000620 // FIXME: Once we have an expression parser in the UnwrappedLineParser,
621 // replace this by using parseAssigmentExpression() inside.
622 bool StartOfExpression = true;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000623 do {
Manuel Klimek423dd932013-04-10 09:52:05 +0000624 // FIXME: When we start to support lambdas, we'll want to parse them away
625 // here, otherwise our bail-out scenarios below break. The better solution
626 // might be to just implement a more or less complete expression parser.
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000627 switch (FormatTok.Tok.getKind()) {
628 case tok::l_brace:
Manuel Klimek423dd932013-04-10 09:52:05 +0000629 if (!StartOfExpression) {
630 // Probably a missing closing brace. Bail out.
631 addUnwrappedLine();
632 return;
633 }
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000634 parseBracedList();
Manuel Klimek423dd932013-04-10 09:52:05 +0000635 StartOfExpression = false;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000636 break;
637 case tok::r_brace:
638 nextToken();
639 return;
Manuel Klimek423dd932013-04-10 09:52:05 +0000640 case tok::semi:
641 // Probably a missing closing brace. Bail out.
642 return;
643 case tok::comma:
644 nextToken();
645 StartOfExpression = true;
646 break;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000647 default:
648 nextToken();
Manuel Klimek423dd932013-04-10 09:52:05 +0000649 StartOfExpression = false;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000650 break;
651 }
652 } while (!eof());
653}
654
Manuel Klimekc44ee892013-01-21 10:07:49 +0000655void UnwrappedLineParser::parseReturn() {
656 nextToken();
657
658 do {
659 switch (FormatTok.Tok.getKind()) {
660 case tok::l_brace:
661 parseBracedList();
Manuel Klimek423dd932013-04-10 09:52:05 +0000662 if (FormatTok.Tok.isNot(tok::semi)) {
663 // Assume missing ';'.
664 addUnwrappedLine();
665 return;
666 }
Manuel Klimekc44ee892013-01-21 10:07:49 +0000667 break;
668 case tok::l_paren:
669 parseParens();
670 break;
671 case tok::r_brace:
672 // Assume missing ';'.
673 addUnwrappedLine();
674 return;
675 case tok::semi:
676 nextToken();
677 addUnwrappedLine();
678 return;
679 default:
680 nextToken();
681 break;
682 }
683 } while (!eof());
684}
685
Daniel Jasperbac016b2012-12-03 18:12:45 +0000686void UnwrappedLineParser::parseParens() {
687 assert(FormatTok.Tok.is(tok::l_paren) && "'(' expected.");
688 nextToken();
689 do {
690 switch (FormatTok.Tok.getKind()) {
691 case tok::l_paren:
692 parseParens();
693 break;
694 case tok::r_paren:
695 nextToken();
696 return;
Nico Weber2afbe522013-02-10 04:38:23 +0000697 case tok::l_brace: {
Manuel Klimek80829bd2013-05-23 09:41:43 +0000698 if (!tryToParseBracedList()) {
699 nextToken();
700 ScopedLineState LineState(*this);
701 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
702 /*MustBeDeclaration=*/ false);
703 Line->Level += 1;
704 parseLevel(/*HasOpeningBrace=*/ true);
705 Line->Level -= 1;
706 }
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000707 break;
Nico Weber2afbe522013-02-10 04:38:23 +0000708 }
Nico Weberd74fcdb2013-02-10 20:35:35 +0000709 case tok::at:
710 nextToken();
711 if (FormatTok.Tok.is(tok::l_brace))
712 parseBracedList();
713 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000714 default:
715 nextToken();
716 break;
717 }
718 } while (!eof());
719}
720
721void UnwrappedLineParser::parseIfThenElse() {
722 assert(FormatTok.Tok.is(tok::kw_if) && "'if' expected");
723 nextToken();
Manuel Klimekd4658432013-01-11 18:28:36 +0000724 if (FormatTok.Tok.is(tok::l_paren))
725 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000726 bool NeedsUnwrappedLine = false;
727 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000728 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000729 NeedsUnwrappedLine = true;
730 } else {
731 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000732 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000733 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000734 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000735 }
736 if (FormatTok.Tok.is(tok::kw_else)) {
737 nextToken();
738 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000739 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000740 addUnwrappedLine();
741 } else if (FormatTok.Tok.is(tok::kw_if)) {
742 parseIfThenElse();
743 } else {
744 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000745 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000746 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000747 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000748 }
749 } else if (NeedsUnwrappedLine) {
750 addUnwrappedLine();
751 }
752}
753
Alexander Kornienko15757312012-12-06 18:03:27 +0000754void UnwrappedLineParser::parseNamespace() {
755 assert(FormatTok.Tok.is(tok::kw_namespace) && "'namespace' expected");
756 nextToken();
757 if (FormatTok.Tok.is(tok::identifier))
758 nextToken();
759 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek44135b82013-05-13 12:51:40 +0000760 if (Style.BreakBeforeBraces == FormatStyle::BS_Linux)
761 addUnwrappedLine();
762
Manuel Klimek70b03f42013-01-23 09:32:48 +0000763 parseBlock(/*MustBeDeclaration=*/ true, 0);
Manuel Klimek7fc2db02013-02-06 16:08:09 +0000764 // Munch the semicolon after a namespace. This is more common than one would
765 // think. Puttin the semicolon into its own line is very ugly.
766 if (FormatTok.Tok.is(tok::semi))
767 nextToken();
Alexander Kornienko15757312012-12-06 18:03:27 +0000768 addUnwrappedLine();
769 }
770 // FIXME: Add error handling.
771}
772
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000773void UnwrappedLineParser::parseForOrWhileLoop() {
774 assert((FormatTok.Tok.is(tok::kw_for) || FormatTok.Tok.is(tok::kw_while)) &&
775 "'for' or 'while' expected");
776 nextToken();
Manuel Klimek6eca03f2013-01-11 19:23:05 +0000777 if (FormatTok.Tok.is(tok::l_paren))
778 parseParens();
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000779 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000780 parseBlock(/*MustBeDeclaration=*/ false);
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000781 addUnwrappedLine();
782 } else {
783 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000784 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000785 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000786 --Line->Level;
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000787 }
788}
789
Daniel Jasperbac016b2012-12-03 18:12:45 +0000790void UnwrappedLineParser::parseDoWhile() {
791 assert(FormatTok.Tok.is(tok::kw_do) && "'do' expected");
792 nextToken();
793 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000794 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000795 } else {
796 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000797 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000798 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000799 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000800 }
801
Alexander Kornienko393b0082012-12-04 15:40:36 +0000802 // FIXME: Add error handling.
803 if (!FormatTok.Tok.is(tok::kw_while)) {
804 addUnwrappedLine();
805 return;
806 }
807
Daniel Jasperbac016b2012-12-03 18:12:45 +0000808 nextToken();
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000809 parseStructuralElement();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000810}
811
812void UnwrappedLineParser::parseLabel() {
Daniel Jasper89a0daa2013-02-12 20:17:17 +0000813 if (FormatTok.Tok.isNot(tok::colon))
814 return;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000815 nextToken();
Manuel Klimek526ed112013-01-09 15:25:02 +0000816 unsigned OldLineLevel = Line->Level;
Daniel Jasperbcca7e42013-03-20 10:23:53 +0000817 if (Line->Level > 1 || (!Line->InPPDirective && Line->Level > 0))
Manuel Klimek526ed112013-01-09 15:25:02 +0000818 --Line->Level;
Daniel Jasperc30eb512013-03-19 18:33:58 +0000819 if (CommentsBeforeNextToken.empty() && FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000820 parseBlock(/*MustBeDeclaration=*/ false);
Nico Weber94fb7292013-01-18 05:50:57 +0000821 if (FormatTok.Tok.is(tok::kw_break))
822 parseStructuralElement(); // "break;" after "}" goes on the same line.
Daniel Jasperbac016b2012-12-03 18:12:45 +0000823 }
824 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000825 Line->Level = OldLineLevel;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000826}
827
828void UnwrappedLineParser::parseCaseLabel() {
829 assert(FormatTok.Tok.is(tok::kw_case) && "'case' expected");
830 // FIXME: fix handling of complex expressions here.
831 do {
832 nextToken();
833 } while (!eof() && !FormatTok.Tok.is(tok::colon));
834 parseLabel();
835}
836
837void UnwrappedLineParser::parseSwitch() {
838 assert(FormatTok.Tok.is(tok::kw_switch) && "'switch' expected");
839 nextToken();
Manuel Klimek6eca03f2013-01-11 19:23:05 +0000840 if (FormatTok.Tok.is(tok::l_paren))
841 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000842 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000843 parseBlock(/*MustBeDeclaration=*/ false, Style.IndentCaseLabels ? 2 : 1);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000844 addUnwrappedLine();
845 } else {
846 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000847 Line->Level += (Style.IndentCaseLabels ? 2 : 1);
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000848 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000849 Line->Level -= (Style.IndentCaseLabels ? 2 : 1);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000850 }
851}
852
853void UnwrappedLineParser::parseAccessSpecifier() {
854 nextToken();
Alexander Kornienko56e49c52012-12-10 16:34:48 +0000855 // Otherwise, we don't know what it is, and we'd better keep the next token.
856 if (FormatTok.Tok.is(tok::colon))
857 nextToken();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000858 addUnwrappedLine();
859}
860
861void UnwrappedLineParser::parseEnum() {
Manuel Klimek308232c2013-01-21 19:17:52 +0000862 nextToken();
863 if (FormatTok.Tok.is(tok::identifier) ||
864 FormatTok.Tok.is(tok::kw___attribute) ||
865 FormatTok.Tok.is(tok::kw___declspec)) {
866 nextToken();
867 // We can have macros or attributes in between 'enum' and the enum name.
868 if (FormatTok.Tok.is(tok::l_paren)) {
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000869 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000870 }
Manuel Klimek308232c2013-01-21 19:17:52 +0000871 if (FormatTok.Tok.is(tok::identifier))
872 nextToken();
873 }
874 if (FormatTok.Tok.is(tok::l_brace)) {
875 nextToken();
876 addUnwrappedLine();
877 ++Line->Level;
878 do {
879 switch (FormatTok.Tok.getKind()) {
Manuel Klimek308232c2013-01-21 19:17:52 +0000880 case tok::l_paren:
881 parseParens();
882 break;
883 case tok::r_brace:
884 addUnwrappedLine();
885 nextToken();
886 --Line->Level;
887 return;
888 case tok::comma:
889 nextToken();
890 addUnwrappedLine();
891 break;
892 default:
893 nextToken();
894 break;
895 }
896 } while (!eof());
897 }
898 // We fall through to parsing a structural element afterwards, so that in
899 // enum A {} n, m;
900 // "} n, m;" will end up in one unwrapped line.
Daniel Jasperbac016b2012-12-03 18:12:45 +0000901}
902
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000903void UnwrappedLineParser::parseRecord() {
Manuel Klimekde768542013-01-07 18:10:23 +0000904 nextToken();
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000905 if (FormatTok.Tok.is(tok::identifier) ||
906 FormatTok.Tok.is(tok::kw___attribute) ||
907 FormatTok.Tok.is(tok::kw___declspec)) {
908 nextToken();
909 // We can have macros or attributes in between 'class' and the class name.
910 if (FormatTok.Tok.is(tok::l_paren)) {
911 parseParens();
Manuel Klimekde768542013-01-07 18:10:23 +0000912 }
Manuel Klimekb8b1ce12013-02-06 15:57:54 +0000913 // The actual identifier can be a nested name specifier, and in macros
914 // it is often token-pasted.
Manuel Klimek7f5b0252013-01-21 10:17:14 +0000915 while (FormatTok.Tok.is(tok::identifier) ||
Daniel Jasperf9955d32013-03-20 12:37:50 +0000916 FormatTok.Tok.is(tok::coloncolon) || FormatTok.Tok.is(tok::hashhash))
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000917 nextToken();
918
Manuel Klimek3a3408c2013-01-21 13:58:54 +0000919 // Note that parsing away template declarations here leads to incorrectly
920 // accepting function declarations as record declarations.
921 // In general, we cannot solve this problem. Consider:
922 // class A<int> B() {}
923 // which can be a function definition or a class definition when B() is a
924 // macro. If we find enough real-world cases where this is a problem, we
925 // can parse for the 'template' keyword in the beginning of the statement,
926 // and thus rule out the record production in case there is no template
927 // (this would still leave us with an ambiguity between template function
928 // and class declarations).
929 if (FormatTok.Tok.is(tok::colon) || FormatTok.Tok.is(tok::less)) {
Daniel Jasper6fe554e2013-03-20 15:12:38 +0000930 while (!eof() && FormatTok.Tok.isNot(tok::l_brace)) {
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000931 if (FormatTok.Tok.is(tok::semi))
932 return;
933 nextToken();
934 }
935 }
936 }
Manuel Klimek44135b82013-05-13 12:51:40 +0000937 if (FormatTok.Tok.is(tok::l_brace)) {
938 if (Style.BreakBeforeBraces == FormatStyle::BS_Linux)
939 addUnwrappedLine();
940
Manuel Klimek70b03f42013-01-23 09:32:48 +0000941 parseBlock(/*MustBeDeclaration=*/ true);
Manuel Klimek44135b82013-05-13 12:51:40 +0000942 }
Manuel Klimek3a3408c2013-01-21 13:58:54 +0000943 // We fall through to parsing a structural element afterwards, so
944 // class A {} n, m;
945 // will end up in one unwrapped line.
Manuel Klimekde768542013-01-07 18:10:23 +0000946}
947
Nico Weber1abe6ea2013-01-09 21:15:03 +0000948void UnwrappedLineParser::parseObjCProtocolList() {
949 assert(FormatTok.Tok.is(tok::less) && "'<' expected.");
950 do
951 nextToken();
952 while (!eof() && FormatTok.Tok.isNot(tok::greater));
953 nextToken(); // Skip '>'.
954}
955
956void UnwrappedLineParser::parseObjCUntilAtEnd() {
957 do {
958 if (FormatTok.Tok.isObjCAtKeyword(tok::objc_end)) {
959 nextToken();
960 addUnwrappedLine();
961 break;
962 }
963 parseStructuralElement();
964 } while (!eof());
965}
966
Nico Weber50767d82013-01-09 23:25:37 +0000967void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
Nico Weber27d13672013-01-09 20:25:35 +0000968 nextToken();
Daniel Jasperf9955d32013-03-20 12:37:50 +0000969 nextToken(); // interface name
Nico Weber27d13672013-01-09 20:25:35 +0000970
971 // @interface can be followed by either a base class, or a category.
972 if (FormatTok.Tok.is(tok::colon)) {
973 nextToken();
Daniel Jasperf9955d32013-03-20 12:37:50 +0000974 nextToken(); // base class name
Nico Weber27d13672013-01-09 20:25:35 +0000975 } else if (FormatTok.Tok.is(tok::l_paren))
976 // Skip category, if present.
977 parseParens();
978
Nico Weber1abe6ea2013-01-09 21:15:03 +0000979 if (FormatTok.Tok.is(tok::less))
980 parseObjCProtocolList();
Nico Weber27d13672013-01-09 20:25:35 +0000981
982 // If instance variables are present, keep the '{' on the first line too.
983 if (FormatTok.Tok.is(tok::l_brace))
Manuel Klimek70b03f42013-01-23 09:32:48 +0000984 parseBlock(/*MustBeDeclaration=*/ true);
Nico Weber27d13672013-01-09 20:25:35 +0000985
986 // With instance variables, this puts '}' on its own line. Without instance
987 // variables, this ends the @interface line.
988 addUnwrappedLine();
989
Nico Weber1abe6ea2013-01-09 21:15:03 +0000990 parseObjCUntilAtEnd();
991}
Nico Weber27d13672013-01-09 20:25:35 +0000992
Nico Weber1abe6ea2013-01-09 21:15:03 +0000993void UnwrappedLineParser::parseObjCProtocol() {
994 nextToken();
Daniel Jasperf9955d32013-03-20 12:37:50 +0000995 nextToken(); // protocol name
Nico Weber1abe6ea2013-01-09 21:15:03 +0000996
997 if (FormatTok.Tok.is(tok::less))
998 parseObjCProtocolList();
999
1000 // Check for protocol declaration.
1001 if (FormatTok.Tok.is(tok::semi)) {
1002 nextToken();
1003 return addUnwrappedLine();
1004 }
1005
1006 addUnwrappedLine();
1007 parseObjCUntilAtEnd();
Nico Weber27d13672013-01-09 20:25:35 +00001008}
1009
Daniel Jasperbac016b2012-12-03 18:12:45 +00001010void UnwrappedLineParser::addUnwrappedLine() {
Daniel Jaspercbb6c412013-01-16 09:10:19 +00001011 if (Line->Tokens.empty())
Daniel Jasper26f7e782013-01-08 14:56:18 +00001012 return;
Manuel Klimek8fa37992013-01-16 12:31:12 +00001013 DEBUG({
Manuel Klimeka28fc062013-02-11 12:33:24 +00001014 llvm::dbgs() << "Line(" << Line->Level << ")"
1015 << (Line->InPPDirective ? " MACRO" : "") << ": ";
Manuel Klimek8fa37992013-01-16 12:31:12 +00001016 for (std::list<FormatToken>::iterator I = Line->Tokens.begin(),
1017 E = Line->Tokens.end();
1018 I != E; ++I) {
1019 llvm::dbgs() << I->Tok.getName() << " ";
Daniel Jaspercbb6c412013-01-16 09:10:19 +00001020
Manuel Klimek8fa37992013-01-16 12:31:12 +00001021 }
1022 llvm::dbgs() << "\n";
1023 });
Manuel Klimek525fe162013-01-18 14:04:34 +00001024 CurrentLines->push_back(*Line);
Daniel Jaspercbb6c412013-01-16 09:10:19 +00001025 Line->Tokens.clear();
Manuel Klimek525fe162013-01-18 14:04:34 +00001026 if (CurrentLines == &Lines && !PreprocessorDirectives.empty()) {
Daniel Jasper516fb312013-03-01 18:11:39 +00001027 for (std::vector<UnwrappedLine>::iterator
1028 I = PreprocessorDirectives.begin(),
1029 E = PreprocessorDirectives.end();
Manuel Klimek525fe162013-01-18 14:04:34 +00001030 I != E; ++I) {
1031 CurrentLines->push_back(*I);
1032 }
1033 PreprocessorDirectives.clear();
1034 }
Daniel Jasperbac016b2012-12-03 18:12:45 +00001035}
1036
Daniel Jasperf9955d32013-03-20 12:37:50 +00001037bool UnwrappedLineParser::eof() const { return FormatTok.Tok.is(tok::eof); }
Daniel Jasperbac016b2012-12-03 18:12:45 +00001038
Manuel Klimek86721d22013-01-22 16:31:55 +00001039void UnwrappedLineParser::flushComments(bool NewlineBeforeNext) {
1040 bool JustComments = Line->Tokens.empty();
1041 for (SmallVectorImpl<FormatToken>::const_iterator
1042 I = CommentsBeforeNextToken.begin(),
1043 E = CommentsBeforeNextToken.end();
1044 I != E; ++I) {
Manuel Klimekb3507cd2013-02-06 16:40:56 +00001045 if (I->NewlinesBefore && JustComments) {
Manuel Klimek86721d22013-01-22 16:31:55 +00001046 addUnwrappedLine();
1047 }
1048 pushToken(*I);
1049 }
1050 if (NewlineBeforeNext && JustComments) {
1051 addUnwrappedLine();
1052 }
1053 CommentsBeforeNextToken.clear();
1054}
1055
Daniel Jasperbac016b2012-12-03 18:12:45 +00001056void UnwrappedLineParser::nextToken() {
1057 if (eof())
1058 return;
Manuel Klimekb3507cd2013-02-06 16:40:56 +00001059 flushComments(FormatTok.NewlinesBefore > 0);
Manuel Klimek86721d22013-01-22 16:31:55 +00001060 pushToken(FormatTok);
Manuel Klimekd4397b92013-01-04 23:34:14 +00001061 readToken();
1062}
1063
1064void UnwrappedLineParser::readToken() {
Manuel Klimek86721d22013-01-22 16:31:55 +00001065 bool CommentsInCurrentLine = true;
1066 do {
1067 FormatTok = Tokens->getNextToken();
1068 while (!Line->InPPDirective && FormatTok.Tok.is(tok::hash) &&
Alexander Kornienko3d713a72013-04-08 22:16:06 +00001069 (FormatTok.HasUnescapedNewline || FormatTok.IsFirst)) {
Manuel Klimek86721d22013-01-22 16:31:55 +00001070 // If there is an unfinished unwrapped line, we flush the preprocessor
1071 // directives only after that unwrapped line was finished later.
Daniel Jasperf9955d32013-03-20 12:37:50 +00001072 bool SwitchToPreprocessorLines =
1073 !Line->Tokens.empty() && CurrentLines == &Lines;
Manuel Klimek86721d22013-01-22 16:31:55 +00001074 ScopedLineState BlockState(*this, SwitchToPreprocessorLines);
Alexander Kornienko4128e192013-04-03 12:38:53 +00001075 // Comments stored before the preprocessor directive need to be output
1076 // before the preprocessor directive, at the same level as the
1077 // preprocessor directive, as we consider them to apply to the directive.
1078 flushComments(FormatTok.NewlinesBefore > 0);
Manuel Klimek86721d22013-01-22 16:31:55 +00001079 parsePPDirective();
1080 }
Alexander Kornienko6fb46b02013-05-24 18:24:24 +00001081
1082 if (!PPStack.empty() && (PPStack.back() == PP_Unreachable) &&
1083 !Line->InPPDirective) {
1084 continue;
1085 }
1086
Manuel Klimek86721d22013-01-22 16:31:55 +00001087 if (!FormatTok.Tok.is(tok::comment))
1088 return;
Manuel Klimekb3507cd2013-02-06 16:40:56 +00001089 if (FormatTok.NewlinesBefore > 0 || FormatTok.IsFirst) {
Manuel Klimek86721d22013-01-22 16:31:55 +00001090 CommentsInCurrentLine = false;
1091 }
1092 if (CommentsInCurrentLine) {
1093 pushToken(FormatTok);
1094 } else {
1095 CommentsBeforeNextToken.push_back(FormatTok);
1096 }
1097 } while (!eof());
1098}
1099
1100void UnwrappedLineParser::pushToken(const FormatToken &Tok) {
1101 Line->Tokens.push_back(Tok);
1102 if (MustBreakBeforeNextToken) {
1103 Line->Tokens.back().MustBreakBefore = true;
1104 MustBreakBeforeNextToken = false;
Manuel Klimekd4397b92013-01-04 23:34:14 +00001105 }
Daniel Jasperbac016b2012-12-03 18:12:45 +00001106}
1107
Daniel Jaspercd162382013-01-07 13:26:07 +00001108} // end namespace format
1109} // end namespace clang