blob: 081f5b933e0f77ac53ea363f4d17939ba38e4409 [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 &&
Manuel Klimekad3094b2013-05-23 10:56:37 +0000342 FormatTok.WhitespaceRange.getBegin() ==
343 FormatTok.WhitespaceRange.getEnd()) {
Manuel Klimekd4397b92013-01-04 23:34:14 +0000344 parseParens();
345 }
346 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000347 Line->Level = 1;
Manuel Klimekc3d0c822013-01-07 09:34:28 +0000348
349 // Errors during a preprocessor directive can only affect the layout of the
350 // preprocessor directive, and thus we ignore them. An alternative approach
351 // would be to use the same approach we use on the file level (no
352 // re-indentation if there was a structural error) within the macro
353 // definition.
Manuel Klimekd4397b92013-01-04 23:34:14 +0000354 parseFile();
355}
356
357void UnwrappedLineParser::parsePPUnknown() {
Manuel Klimeka080a182013-01-02 16:30:12 +0000358 do {
Manuel Klimeka080a182013-01-02 16:30:12 +0000359 nextToken();
360 } while (!eof());
361 addUnwrappedLine();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000362}
363
Alexander Kornienko99b0e142013-04-09 16:15:19 +0000364// Here we blacklist certain tokens that are not usually the first token in an
365// unwrapped line. This is used in attempt to distinguish macro calls without
366// trailing semicolons from other constructs split to several lines.
367bool tokenCanStartNewLine(clang::Token Tok) {
368 // Semicolon can be a null-statement, l_square can be a start of a macro or
369 // a C++11 attribute, but this doesn't seem to be common.
370 return Tok.isNot(tok::semi) && Tok.isNot(tok::l_brace) &&
371 Tok.isNot(tok::l_square) &&
372 // Tokens that can only be used as binary operators and a part of
373 // overloaded operator names.
374 Tok.isNot(tok::period) && Tok.isNot(tok::periodstar) &&
375 Tok.isNot(tok::arrow) && Tok.isNot(tok::arrowstar) &&
376 Tok.isNot(tok::less) && Tok.isNot(tok::greater) &&
377 Tok.isNot(tok::slash) && Tok.isNot(tok::percent) &&
378 Tok.isNot(tok::lessless) && Tok.isNot(tok::greatergreater) &&
379 Tok.isNot(tok::equal) && Tok.isNot(tok::plusequal) &&
380 Tok.isNot(tok::minusequal) && Tok.isNot(tok::starequal) &&
381 Tok.isNot(tok::slashequal) && Tok.isNot(tok::percentequal) &&
382 Tok.isNot(tok::ampequal) && Tok.isNot(tok::pipeequal) &&
383 Tok.isNot(tok::caretequal) && Tok.isNot(tok::greatergreaterequal) &&
384 Tok.isNot(tok::lesslessequal) &&
385 // Colon is used in labels, base class lists, initializer lists,
386 // range-based for loops, ternary operator, but should never be the
387 // first token in an unwrapped line.
388 Tok.isNot(tok::colon);
389}
390
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000391void UnwrappedLineParser::parseStructuralElement() {
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000392 assert(!FormatTok.Tok.is(tok::l_brace));
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000393 switch (FormatTok.Tok.getKind()) {
Nico Weber6092d4e2013-01-07 19:05:19 +0000394 case tok::at:
395 nextToken();
Nico Weberd74fcdb2013-02-10 20:35:35 +0000396 if (FormatTok.Tok.is(tok::l_brace)) {
397 parseBracedList();
398 break;
399 }
Nico Weber6092d4e2013-01-07 19:05:19 +0000400 switch (FormatTok.Tok.getObjCKeywordID()) {
401 case tok::objc_public:
402 case tok::objc_protected:
403 case tok::objc_package:
404 case tok::objc_private:
405 return parseAccessSpecifier();
Nico Weber27d13672013-01-09 20:25:35 +0000406 case tok::objc_interface:
Nico Weber50767d82013-01-09 23:25:37 +0000407 case tok::objc_implementation:
408 return parseObjCInterfaceOrImplementation();
Nico Weber1abe6ea2013-01-09 21:15:03 +0000409 case tok::objc_protocol:
410 return parseObjCProtocol();
Nico Weber049c4472013-01-09 21:42:32 +0000411 case tok::objc_end:
412 return; // Handled by the caller.
Nico Weberb530fa32013-01-10 00:25:19 +0000413 case tok::objc_optional:
414 case tok::objc_required:
415 nextToken();
416 addUnwrappedLine();
417 return;
Nico Weber6092d4e2013-01-07 19:05:19 +0000418 default:
419 break;
420 }
421 break;
Alexander Kornienko15757312012-12-06 18:03:27 +0000422 case tok::kw_namespace:
423 parseNamespace();
424 return;
Dmitri Gribenko1f94f2b2012-12-30 21:27:25 +0000425 case tok::kw_inline:
426 nextToken();
Dmitri Gribenko1f94f2b2012-12-30 21:27:25 +0000427 if (FormatTok.Tok.is(tok::kw_namespace)) {
428 parseNamespace();
429 return;
430 }
431 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000432 case tok::kw_public:
433 case tok::kw_protected:
434 case tok::kw_private:
Daniel Jasperbac016b2012-12-03 18:12:45 +0000435 parseAccessSpecifier();
436 return;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000437 case tok::kw_if:
438 parseIfThenElse();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000439 return;
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000440 case tok::kw_for:
441 case tok::kw_while:
442 parseForOrWhileLoop();
443 return;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000444 case tok::kw_do:
445 parseDoWhile();
446 return;
447 case tok::kw_switch:
448 parseSwitch();
449 return;
450 case tok::kw_default:
451 nextToken();
452 parseLabel();
453 return;
454 case tok::kw_case:
455 parseCaseLabel();
456 return;
Manuel Klimekc44ee892013-01-21 10:07:49 +0000457 case tok::kw_return:
458 parseReturn();
459 return;
Manuel Klimekd19dc2d2013-01-21 14:32:05 +0000460 case tok::kw_extern:
461 nextToken();
462 if (FormatTok.Tok.is(tok::string_literal)) {
463 nextToken();
464 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000465 parseBlock(/*MustBeDeclaration=*/ true, 0);
Manuel Klimekd19dc2d2013-01-21 14:32:05 +0000466 addUnwrappedLine();
467 return;
468 }
469 }
470 // In all other cases, parse the declaration.
471 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000472 default:
473 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000474 }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000475 do {
Daniel Jasperbac016b2012-12-03 18:12:45 +0000476 switch (FormatTok.Tok.getKind()) {
Nico Weberd74fcdb2013-02-10 20:35:35 +0000477 case tok::at:
478 nextToken();
479 if (FormatTok.Tok.is(tok::l_brace))
480 parseBracedList();
481 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000482 case tok::kw_enum:
483 parseEnum();
Manuel Klimek308232c2013-01-21 19:17:52 +0000484 break;
Alexander Kornienkod8818752013-01-16 11:43:46 +0000485 case tok::kw_struct:
486 case tok::kw_union:
Manuel Klimekde768542013-01-07 18:10:23 +0000487 case tok::kw_class:
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000488 parseRecord();
489 // A record declaration or definition is always the start of a structural
490 // element.
491 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000492 case tok::semi:
493 nextToken();
494 addUnwrappedLine();
495 return;
Alexander Kornienkod8818752013-01-16 11:43:46 +0000496 case tok::r_brace:
497 addUnwrappedLine();
498 return;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000499 case tok::l_paren:
500 parseParens();
501 break;
502 case tok::l_brace:
Manuel Klimek80829bd2013-05-23 09:41:43 +0000503 if (!tryToParseBracedList()) {
504 // A block outside of parentheses must be the last part of a
505 // structural element.
506 // FIXME: Figure out cases where this is not true, and add projections
507 // for them (the one we know is missing are lambdas).
508 if (Style.BreakBeforeBraces == FormatStyle::BS_Linux ||
509 Style.BreakBeforeBraces == FormatStyle::BS_Stroustrup)
510 addUnwrappedLine();
511 parseBlock(/*MustBeDeclaration=*/ false);
Manuel Klimek44135b82013-05-13 12:51:40 +0000512 addUnwrappedLine();
Manuel Klimek80829bd2013-05-23 09:41:43 +0000513 return;
514 }
515 // Otherwise this was a braced init list, and the structural
516 // element continues.
517 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000518 case tok::identifier:
Daniel Jasperbac016b2012-12-03 18:12:45 +0000519 nextToken();
Alexander Kornienko3d713a72013-04-08 22:16:06 +0000520 if (Line->Tokens.size() == 1) {
521 if (FormatTok.Tok.is(tok::colon)) {
522 parseLabel();
523 return;
524 }
Alexander Kornienko99b0e142013-04-09 16:15:19 +0000525 // Recognize function-like macro usages without trailing semicolon.
Alexander Kornienko3d713a72013-04-08 22:16:06 +0000526 if (FormatTok.Tok.is(tok::l_paren)) {
527 parseParens();
Alexander Kornienko99b0e142013-04-09 16:15:19 +0000528 if (FormatTok.HasUnescapedNewline &&
529 tokenCanStartNewLine(FormatTok.Tok)) {
Alexander Kornienko3d713a72013-04-08 22:16:06 +0000530 addUnwrappedLine();
531 return;
532 }
533 }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000534 }
535 break;
Daniel Jasper05b1ac82012-12-17 11:29:41 +0000536 case tok::equal:
537 nextToken();
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000538 if (FormatTok.Tok.is(tok::l_brace)) {
539 parseBracedList();
540 }
Daniel Jasper05b1ac82012-12-17 11:29:41 +0000541 break;
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000542 default:
543 nextToken();
544 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000545 }
546 } while (!eof());
547}
548
Manuel Klimek80829bd2013-05-23 09:41:43 +0000549bool UnwrappedLineParser::tryToParseBracedList() {
550 if (LBraces[Tokens->getPosition()] == BS_Unknown)
551 calculateBraceTypes();
552 assert(LBraces[Tokens->getPosition()] != BS_Unknown);
553 if (LBraces[Tokens->getPosition()] == BS_Block)
554 return false;
555 parseBracedList();
556 return true;
557}
558
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000559void UnwrappedLineParser::parseBracedList() {
560 nextToken();
561
Manuel Klimek423dd932013-04-10 09:52:05 +0000562 // FIXME: Once we have an expression parser in the UnwrappedLineParser,
563 // replace this by using parseAssigmentExpression() inside.
564 bool StartOfExpression = true;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000565 do {
Manuel Klimek423dd932013-04-10 09:52:05 +0000566 // FIXME: When we start to support lambdas, we'll want to parse them away
567 // here, otherwise our bail-out scenarios below break. The better solution
568 // might be to just implement a more or less complete expression parser.
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000569 switch (FormatTok.Tok.getKind()) {
570 case tok::l_brace:
Manuel Klimek423dd932013-04-10 09:52:05 +0000571 if (!StartOfExpression) {
572 // Probably a missing closing brace. Bail out.
573 addUnwrappedLine();
574 return;
575 }
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000576 parseBracedList();
Manuel Klimek423dd932013-04-10 09:52:05 +0000577 StartOfExpression = false;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000578 break;
579 case tok::r_brace:
580 nextToken();
581 return;
Manuel Klimek423dd932013-04-10 09:52:05 +0000582 case tok::semi:
583 // Probably a missing closing brace. Bail out.
584 return;
585 case tok::comma:
586 nextToken();
587 StartOfExpression = true;
588 break;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000589 default:
590 nextToken();
Manuel Klimek423dd932013-04-10 09:52:05 +0000591 StartOfExpression = false;
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000592 break;
593 }
594 } while (!eof());
595}
596
Manuel Klimekc44ee892013-01-21 10:07:49 +0000597void UnwrappedLineParser::parseReturn() {
598 nextToken();
599
600 do {
601 switch (FormatTok.Tok.getKind()) {
602 case tok::l_brace:
603 parseBracedList();
Manuel Klimek423dd932013-04-10 09:52:05 +0000604 if (FormatTok.Tok.isNot(tok::semi)) {
605 // Assume missing ';'.
606 addUnwrappedLine();
607 return;
608 }
Manuel Klimekc44ee892013-01-21 10:07:49 +0000609 break;
610 case tok::l_paren:
611 parseParens();
612 break;
613 case tok::r_brace:
614 // Assume missing ';'.
615 addUnwrappedLine();
616 return;
617 case tok::semi:
618 nextToken();
619 addUnwrappedLine();
620 return;
621 default:
622 nextToken();
623 break;
624 }
625 } while (!eof());
626}
627
Daniel Jasperbac016b2012-12-03 18:12:45 +0000628void UnwrappedLineParser::parseParens() {
629 assert(FormatTok.Tok.is(tok::l_paren) && "'(' expected.");
630 nextToken();
631 do {
632 switch (FormatTok.Tok.getKind()) {
633 case tok::l_paren:
634 parseParens();
635 break;
636 case tok::r_paren:
637 nextToken();
638 return;
Nico Weber2afbe522013-02-10 04:38:23 +0000639 case tok::l_brace: {
Manuel Klimek80829bd2013-05-23 09:41:43 +0000640 if (!tryToParseBracedList()) {
641 nextToken();
642 ScopedLineState LineState(*this);
643 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
644 /*MustBeDeclaration=*/ false);
645 Line->Level += 1;
646 parseLevel(/*HasOpeningBrace=*/ true);
647 Line->Level -= 1;
648 }
Manuel Klimekbb42bf12013-01-10 11:52:21 +0000649 break;
Nico Weber2afbe522013-02-10 04:38:23 +0000650 }
Nico Weberd74fcdb2013-02-10 20:35:35 +0000651 case tok::at:
652 nextToken();
653 if (FormatTok.Tok.is(tok::l_brace))
654 parseBracedList();
655 break;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000656 default:
657 nextToken();
658 break;
659 }
660 } while (!eof());
661}
662
663void UnwrappedLineParser::parseIfThenElse() {
664 assert(FormatTok.Tok.is(tok::kw_if) && "'if' expected");
665 nextToken();
Manuel Klimekd4658432013-01-11 18:28:36 +0000666 if (FormatTok.Tok.is(tok::l_paren))
667 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000668 bool NeedsUnwrappedLine = false;
669 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000670 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000671 NeedsUnwrappedLine = true;
672 } else {
673 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000674 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000675 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000676 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000677 }
678 if (FormatTok.Tok.is(tok::kw_else)) {
679 nextToken();
680 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000681 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000682 addUnwrappedLine();
683 } else if (FormatTok.Tok.is(tok::kw_if)) {
684 parseIfThenElse();
685 } else {
686 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000687 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000688 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000689 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000690 }
691 } else if (NeedsUnwrappedLine) {
692 addUnwrappedLine();
693 }
694}
695
Alexander Kornienko15757312012-12-06 18:03:27 +0000696void UnwrappedLineParser::parseNamespace() {
697 assert(FormatTok.Tok.is(tok::kw_namespace) && "'namespace' expected");
698 nextToken();
699 if (FormatTok.Tok.is(tok::identifier))
700 nextToken();
701 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek44135b82013-05-13 12:51:40 +0000702 if (Style.BreakBeforeBraces == FormatStyle::BS_Linux)
703 addUnwrappedLine();
704
Manuel Klimek70b03f42013-01-23 09:32:48 +0000705 parseBlock(/*MustBeDeclaration=*/ true, 0);
Manuel Klimek7fc2db02013-02-06 16:08:09 +0000706 // Munch the semicolon after a namespace. This is more common than one would
707 // think. Puttin the semicolon into its own line is very ugly.
708 if (FormatTok.Tok.is(tok::semi))
709 nextToken();
Alexander Kornienko15757312012-12-06 18:03:27 +0000710 addUnwrappedLine();
711 }
712 // FIXME: Add error handling.
713}
714
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000715void UnwrappedLineParser::parseForOrWhileLoop() {
716 assert((FormatTok.Tok.is(tok::kw_for) || FormatTok.Tok.is(tok::kw_while)) &&
717 "'for' or 'while' expected");
718 nextToken();
Manuel Klimek6eca03f2013-01-11 19:23:05 +0000719 if (FormatTok.Tok.is(tok::l_paren))
720 parseParens();
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000721 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000722 parseBlock(/*MustBeDeclaration=*/ false);
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000723 addUnwrappedLine();
724 } else {
725 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000726 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000727 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000728 --Line->Level;
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000729 }
730}
731
Daniel Jasperbac016b2012-12-03 18:12:45 +0000732void UnwrappedLineParser::parseDoWhile() {
733 assert(FormatTok.Tok.is(tok::kw_do) && "'do' expected");
734 nextToken();
735 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000736 parseBlock(/*MustBeDeclaration=*/ false);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000737 } else {
738 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000739 ++Line->Level;
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000740 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000741 --Line->Level;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000742 }
743
Alexander Kornienko393b0082012-12-04 15:40:36 +0000744 // FIXME: Add error handling.
745 if (!FormatTok.Tok.is(tok::kw_while)) {
746 addUnwrappedLine();
747 return;
748 }
749
Daniel Jasperbac016b2012-12-03 18:12:45 +0000750 nextToken();
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000751 parseStructuralElement();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000752}
753
754void UnwrappedLineParser::parseLabel() {
Daniel Jasper89a0daa2013-02-12 20:17:17 +0000755 if (FormatTok.Tok.isNot(tok::colon))
756 return;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000757 nextToken();
Manuel Klimek526ed112013-01-09 15:25:02 +0000758 unsigned OldLineLevel = Line->Level;
Daniel Jasperbcca7e42013-03-20 10:23:53 +0000759 if (Line->Level > 1 || (!Line->InPPDirective && Line->Level > 0))
Manuel Klimek526ed112013-01-09 15:25:02 +0000760 --Line->Level;
Daniel Jasperc30eb512013-03-19 18:33:58 +0000761 if (CommentsBeforeNextToken.empty() && FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000762 parseBlock(/*MustBeDeclaration=*/ false);
Nico Weber94fb7292013-01-18 05:50:57 +0000763 if (FormatTok.Tok.is(tok::kw_break))
764 parseStructuralElement(); // "break;" after "}" goes on the same line.
Daniel Jasperbac016b2012-12-03 18:12:45 +0000765 }
766 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000767 Line->Level = OldLineLevel;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000768}
769
770void UnwrappedLineParser::parseCaseLabel() {
771 assert(FormatTok.Tok.is(tok::kw_case) && "'case' expected");
772 // FIXME: fix handling of complex expressions here.
773 do {
774 nextToken();
775 } while (!eof() && !FormatTok.Tok.is(tok::colon));
776 parseLabel();
777}
778
779void UnwrappedLineParser::parseSwitch() {
780 assert(FormatTok.Tok.is(tok::kw_switch) && "'switch' expected");
781 nextToken();
Manuel Klimek6eca03f2013-01-11 19:23:05 +0000782 if (FormatTok.Tok.is(tok::l_paren))
783 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000784 if (FormatTok.Tok.is(tok::l_brace)) {
Manuel Klimek70b03f42013-01-23 09:32:48 +0000785 parseBlock(/*MustBeDeclaration=*/ false, Style.IndentCaseLabels ? 2 : 1);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000786 addUnwrappedLine();
787 } else {
788 addUnwrappedLine();
Manuel Klimek526ed112013-01-09 15:25:02 +0000789 Line->Level += (Style.IndentCaseLabels ? 2 : 1);
Manuel Klimekf0ab0a32013-01-07 14:56:16 +0000790 parseStructuralElement();
Manuel Klimek526ed112013-01-09 15:25:02 +0000791 Line->Level -= (Style.IndentCaseLabels ? 2 : 1);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000792 }
793}
794
795void UnwrappedLineParser::parseAccessSpecifier() {
796 nextToken();
Alexander Kornienko56e49c52012-12-10 16:34:48 +0000797 // Otherwise, we don't know what it is, and we'd better keep the next token.
798 if (FormatTok.Tok.is(tok::colon))
799 nextToken();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000800 addUnwrappedLine();
801}
802
803void UnwrappedLineParser::parseEnum() {
Manuel Klimek308232c2013-01-21 19:17:52 +0000804 nextToken();
805 if (FormatTok.Tok.is(tok::identifier) ||
806 FormatTok.Tok.is(tok::kw___attribute) ||
807 FormatTok.Tok.is(tok::kw___declspec)) {
808 nextToken();
809 // We can have macros or attributes in between 'enum' and the enum name.
810 if (FormatTok.Tok.is(tok::l_paren)) {
Alexander Kornienkoa166e732012-12-04 14:46:19 +0000811 parseParens();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000812 }
Manuel Klimek308232c2013-01-21 19:17:52 +0000813 if (FormatTok.Tok.is(tok::identifier))
814 nextToken();
815 }
816 if (FormatTok.Tok.is(tok::l_brace)) {
817 nextToken();
818 addUnwrappedLine();
819 ++Line->Level;
820 do {
821 switch (FormatTok.Tok.getKind()) {
Manuel Klimek308232c2013-01-21 19:17:52 +0000822 case tok::l_paren:
823 parseParens();
824 break;
825 case tok::r_brace:
826 addUnwrappedLine();
827 nextToken();
828 --Line->Level;
829 return;
830 case tok::comma:
831 nextToken();
832 addUnwrappedLine();
833 break;
834 default:
835 nextToken();
836 break;
837 }
838 } while (!eof());
839 }
840 // We fall through to parsing a structural element afterwards, so that in
841 // enum A {} n, m;
842 // "} n, m;" will end up in one unwrapped line.
Daniel Jasperbac016b2012-12-03 18:12:45 +0000843}
844
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000845void UnwrappedLineParser::parseRecord() {
Manuel Klimekde768542013-01-07 18:10:23 +0000846 nextToken();
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000847 if (FormatTok.Tok.is(tok::identifier) ||
848 FormatTok.Tok.is(tok::kw___attribute) ||
849 FormatTok.Tok.is(tok::kw___declspec)) {
850 nextToken();
851 // We can have macros or attributes in between 'class' and the class name.
852 if (FormatTok.Tok.is(tok::l_paren)) {
853 parseParens();
Manuel Klimekde768542013-01-07 18:10:23 +0000854 }
Manuel Klimekb8b1ce12013-02-06 15:57:54 +0000855 // The actual identifier can be a nested name specifier, and in macros
856 // it is often token-pasted.
Manuel Klimek7f5b0252013-01-21 10:17:14 +0000857 while (FormatTok.Tok.is(tok::identifier) ||
Daniel Jasperf9955d32013-03-20 12:37:50 +0000858 FormatTok.Tok.is(tok::coloncolon) || FormatTok.Tok.is(tok::hashhash))
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000859 nextToken();
860
Manuel Klimek3a3408c2013-01-21 13:58:54 +0000861 // Note that parsing away template declarations here leads to incorrectly
862 // accepting function declarations as record declarations.
863 // In general, we cannot solve this problem. Consider:
864 // class A<int> B() {}
865 // which can be a function definition or a class definition when B() is a
866 // macro. If we find enough real-world cases where this is a problem, we
867 // can parse for the 'template' keyword in the beginning of the statement,
868 // and thus rule out the record production in case there is no template
869 // (this would still leave us with an ambiguity between template function
870 // and class declarations).
871 if (FormatTok.Tok.is(tok::colon) || FormatTok.Tok.is(tok::less)) {
Daniel Jasper6fe554e2013-03-20 15:12:38 +0000872 while (!eof() && FormatTok.Tok.isNot(tok::l_brace)) {
Manuel Klimek47ea7f62013-01-15 13:38:33 +0000873 if (FormatTok.Tok.is(tok::semi))
874 return;
875 nextToken();
876 }
877 }
878 }
Manuel Klimek44135b82013-05-13 12:51:40 +0000879 if (FormatTok.Tok.is(tok::l_brace)) {
880 if (Style.BreakBeforeBraces == FormatStyle::BS_Linux)
881 addUnwrappedLine();
882
Manuel Klimek70b03f42013-01-23 09:32:48 +0000883 parseBlock(/*MustBeDeclaration=*/ true);
Manuel Klimek44135b82013-05-13 12:51:40 +0000884 }
Manuel Klimek3a3408c2013-01-21 13:58:54 +0000885 // We fall through to parsing a structural element afterwards, so
886 // class A {} n, m;
887 // will end up in one unwrapped line.
Manuel Klimekde768542013-01-07 18:10:23 +0000888}
889
Nico Weber1abe6ea2013-01-09 21:15:03 +0000890void UnwrappedLineParser::parseObjCProtocolList() {
891 assert(FormatTok.Tok.is(tok::less) && "'<' expected.");
892 do
893 nextToken();
894 while (!eof() && FormatTok.Tok.isNot(tok::greater));
895 nextToken(); // Skip '>'.
896}
897
898void UnwrappedLineParser::parseObjCUntilAtEnd() {
899 do {
900 if (FormatTok.Tok.isObjCAtKeyword(tok::objc_end)) {
901 nextToken();
902 addUnwrappedLine();
903 break;
904 }
905 parseStructuralElement();
906 } while (!eof());
907}
908
Nico Weber50767d82013-01-09 23:25:37 +0000909void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
Nico Weber27d13672013-01-09 20:25:35 +0000910 nextToken();
Daniel Jasperf9955d32013-03-20 12:37:50 +0000911 nextToken(); // interface name
Nico Weber27d13672013-01-09 20:25:35 +0000912
913 // @interface can be followed by either a base class, or a category.
914 if (FormatTok.Tok.is(tok::colon)) {
915 nextToken();
Daniel Jasperf9955d32013-03-20 12:37:50 +0000916 nextToken(); // base class name
Nico Weber27d13672013-01-09 20:25:35 +0000917 } else if (FormatTok.Tok.is(tok::l_paren))
918 // Skip category, if present.
919 parseParens();
920
Nico Weber1abe6ea2013-01-09 21:15:03 +0000921 if (FormatTok.Tok.is(tok::less))
922 parseObjCProtocolList();
Nico Weber27d13672013-01-09 20:25:35 +0000923
924 // If instance variables are present, keep the '{' on the first line too.
925 if (FormatTok.Tok.is(tok::l_brace))
Manuel Klimek70b03f42013-01-23 09:32:48 +0000926 parseBlock(/*MustBeDeclaration=*/ true);
Nico Weber27d13672013-01-09 20:25:35 +0000927
928 // With instance variables, this puts '}' on its own line. Without instance
929 // variables, this ends the @interface line.
930 addUnwrappedLine();
931
Nico Weber1abe6ea2013-01-09 21:15:03 +0000932 parseObjCUntilAtEnd();
933}
Nico Weber27d13672013-01-09 20:25:35 +0000934
Nico Weber1abe6ea2013-01-09 21:15:03 +0000935void UnwrappedLineParser::parseObjCProtocol() {
936 nextToken();
Daniel Jasperf9955d32013-03-20 12:37:50 +0000937 nextToken(); // protocol name
Nico Weber1abe6ea2013-01-09 21:15:03 +0000938
939 if (FormatTok.Tok.is(tok::less))
940 parseObjCProtocolList();
941
942 // Check for protocol declaration.
943 if (FormatTok.Tok.is(tok::semi)) {
944 nextToken();
945 return addUnwrappedLine();
946 }
947
948 addUnwrappedLine();
949 parseObjCUntilAtEnd();
Nico Weber27d13672013-01-09 20:25:35 +0000950}
951
Daniel Jasperbac016b2012-12-03 18:12:45 +0000952void UnwrappedLineParser::addUnwrappedLine() {
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000953 if (Line->Tokens.empty())
Daniel Jasper26f7e782013-01-08 14:56:18 +0000954 return;
Manuel Klimek8fa37992013-01-16 12:31:12 +0000955 DEBUG({
Manuel Klimeka28fc062013-02-11 12:33:24 +0000956 llvm::dbgs() << "Line(" << Line->Level << ")"
957 << (Line->InPPDirective ? " MACRO" : "") << ": ";
Manuel Klimek8fa37992013-01-16 12:31:12 +0000958 for (std::list<FormatToken>::iterator I = Line->Tokens.begin(),
959 E = Line->Tokens.end();
960 I != E; ++I) {
961 llvm::dbgs() << I->Tok.getName() << " ";
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000962
Manuel Klimek8fa37992013-01-16 12:31:12 +0000963 }
964 llvm::dbgs() << "\n";
965 });
Manuel Klimek525fe162013-01-18 14:04:34 +0000966 CurrentLines->push_back(*Line);
Daniel Jaspercbb6c412013-01-16 09:10:19 +0000967 Line->Tokens.clear();
Manuel Klimek525fe162013-01-18 14:04:34 +0000968 if (CurrentLines == &Lines && !PreprocessorDirectives.empty()) {
Daniel Jasper516fb312013-03-01 18:11:39 +0000969 for (std::vector<UnwrappedLine>::iterator
970 I = PreprocessorDirectives.begin(),
971 E = PreprocessorDirectives.end();
Manuel Klimek525fe162013-01-18 14:04:34 +0000972 I != E; ++I) {
973 CurrentLines->push_back(*I);
974 }
975 PreprocessorDirectives.clear();
976 }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000977}
978
Daniel Jasperf9955d32013-03-20 12:37:50 +0000979bool UnwrappedLineParser::eof() const { return FormatTok.Tok.is(tok::eof); }
Daniel Jasperbac016b2012-12-03 18:12:45 +0000980
Manuel Klimek86721d22013-01-22 16:31:55 +0000981void UnwrappedLineParser::flushComments(bool NewlineBeforeNext) {
982 bool JustComments = Line->Tokens.empty();
983 for (SmallVectorImpl<FormatToken>::const_iterator
984 I = CommentsBeforeNextToken.begin(),
985 E = CommentsBeforeNextToken.end();
986 I != E; ++I) {
Manuel Klimekb3507cd2013-02-06 16:40:56 +0000987 if (I->NewlinesBefore && JustComments) {
Manuel Klimek86721d22013-01-22 16:31:55 +0000988 addUnwrappedLine();
989 }
990 pushToken(*I);
991 }
992 if (NewlineBeforeNext && JustComments) {
993 addUnwrappedLine();
994 }
995 CommentsBeforeNextToken.clear();
996}
997
Daniel Jasperbac016b2012-12-03 18:12:45 +0000998void UnwrappedLineParser::nextToken() {
999 if (eof())
1000 return;
Manuel Klimekb3507cd2013-02-06 16:40:56 +00001001 flushComments(FormatTok.NewlinesBefore > 0);
Manuel Klimek86721d22013-01-22 16:31:55 +00001002 pushToken(FormatTok);
Manuel Klimekd4397b92013-01-04 23:34:14 +00001003 readToken();
1004}
1005
1006void UnwrappedLineParser::readToken() {
Manuel Klimek86721d22013-01-22 16:31:55 +00001007 bool CommentsInCurrentLine = true;
1008 do {
1009 FormatTok = Tokens->getNextToken();
1010 while (!Line->InPPDirective && FormatTok.Tok.is(tok::hash) &&
Alexander Kornienko3d713a72013-04-08 22:16:06 +00001011 (FormatTok.HasUnescapedNewline || FormatTok.IsFirst)) {
Manuel Klimek86721d22013-01-22 16:31:55 +00001012 // If there is an unfinished unwrapped line, we flush the preprocessor
1013 // directives only after that unwrapped line was finished later.
Daniel Jasperf9955d32013-03-20 12:37:50 +00001014 bool SwitchToPreprocessorLines =
1015 !Line->Tokens.empty() && CurrentLines == &Lines;
Manuel Klimek86721d22013-01-22 16:31:55 +00001016 ScopedLineState BlockState(*this, SwitchToPreprocessorLines);
Alexander Kornienko4128e192013-04-03 12:38:53 +00001017 // Comments stored before the preprocessor directive need to be output
1018 // before the preprocessor directive, at the same level as the
1019 // preprocessor directive, as we consider them to apply to the directive.
1020 flushComments(FormatTok.NewlinesBefore > 0);
Manuel Klimek86721d22013-01-22 16:31:55 +00001021 parsePPDirective();
1022 }
1023 if (!FormatTok.Tok.is(tok::comment))
1024 return;
Manuel Klimekb3507cd2013-02-06 16:40:56 +00001025 if (FormatTok.NewlinesBefore > 0 || FormatTok.IsFirst) {
Manuel Klimek86721d22013-01-22 16:31:55 +00001026 CommentsInCurrentLine = false;
1027 }
1028 if (CommentsInCurrentLine) {
1029 pushToken(FormatTok);
1030 } else {
1031 CommentsBeforeNextToken.push_back(FormatTok);
1032 }
1033 } while (!eof());
1034}
1035
1036void UnwrappedLineParser::pushToken(const FormatToken &Tok) {
1037 Line->Tokens.push_back(Tok);
1038 if (MustBreakBeforeNextToken) {
1039 Line->Tokens.back().MustBreakBefore = true;
1040 MustBreakBeforeNextToken = false;
Manuel Klimekd4397b92013-01-04 23:34:14 +00001041 }
Daniel Jasperbac016b2012-12-03 18:12:45 +00001042}
1043
Daniel Jaspercd162382013-01-07 13:26:07 +00001044} // end namespace format
1045} // end namespace clang