blob: f6d7ec42f3fefb186472e550a437c04079eaa151 [file] [log] [blame]
Daniel Jasperf7935112012-12-03 18:12:45 +00001//===--- Format.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 implements functions declared in Format.h. This will be
12/// split into separate files as we go.
13///
14/// This is EXPERIMENTAL code under heavy development. It is not in a state yet,
15/// where it can be used to format real code.
16///
17//===----------------------------------------------------------------------===//
18
Manuel Klimek24998102013-01-16 14:55:28 +000019#define DEBUG_TYPE "format-formatter"
20
Chandler Carruth3a022472012-12-04 09:13:33 +000021#include "UnwrappedLineParser.h"
Alexander Kornienko5b7157a2013-01-10 15:05:09 +000022#include "clang/Basic/Diagnostic.h"
Daniel Jasperab7654e2012-12-21 10:20:02 +000023#include "clang/Basic/OperatorPrecedence.h"
Chandler Carruth44eb4f62013-01-02 10:28:36 +000024#include "clang/Basic/SourceManager.h"
Manuel Klimek24998102013-01-16 14:55:28 +000025#include "clang/Format/Format.h"
Alexander Kornienko5b7157a2013-01-10 15:05:09 +000026#include "clang/Frontend/TextDiagnosticPrinter.h"
Daniel Jasperf7935112012-12-03 18:12:45 +000027#include "clang/Lex/Lexer.h"
Manuel Klimek24998102013-01-16 14:55:28 +000028#include "llvm/Support/Debug.h"
Daniel Jasper8b529712012-12-04 13:02:32 +000029#include <string>
30
Manuel Klimek24998102013-01-16 14:55:28 +000031// Uncomment to get debug output from tests:
32// #define DEBUG_WITH_TYPE(T, X) do { X; } while(0)
33
Daniel Jasperf7935112012-12-03 18:12:45 +000034namespace clang {
35namespace format {
36
Daniel Jasperda16db32013-01-07 10:48:50 +000037enum TokenType {
Daniel Jasperda16db32013-01-07 10:48:50 +000038 TT_BinaryOperator,
Daniel Jasper7194e182013-01-10 11:14:08 +000039 TT_BlockComment,
40 TT_CastRParen,
Daniel Jasperda16db32013-01-07 10:48:50 +000041 TT_ConditionalExpr,
42 TT_CtorInitializerColon,
Manuel Klimek99c7baa2013-01-15 15:50:27 +000043 TT_ImplicitStringLiteral,
Daniel Jasper7194e182013-01-10 11:14:08 +000044 TT_LineComment,
Daniel Jasperc1fa2812013-01-10 13:08:12 +000045 TT_ObjCBlockLParen,
Nico Weber2bb00742013-01-10 19:19:14 +000046 TT_ObjCDecl,
Daniel Jasper7194e182013-01-10 11:14:08 +000047 TT_ObjCMethodSpecifier,
Nico Webera7252d82013-01-12 06:18:40 +000048 TT_ObjCMethodExpr,
Nico Webera2a84952013-01-10 21:30:42 +000049 TT_ObjCProperty,
Daniel Jasper7194e182013-01-10 11:14:08 +000050 TT_OverloadedOperator,
51 TT_PointerOrReference,
Daniel Jasperda16db32013-01-07 10:48:50 +000052 TT_PureVirtualSpecifier,
Daniel Jasperd2639ef2013-01-28 15:16:31 +000053 TT_RangeBasedForLoopColon,
54 TT_StartOfName,
Daniel Jasper7194e182013-01-10 11:14:08 +000055 TT_TemplateCloser,
56 TT_TemplateOpener,
57 TT_TrailingUnaryOperator,
58 TT_UnaryOperator,
59 TT_Unknown
Daniel Jasperda16db32013-01-07 10:48:50 +000060};
61
62enum LineType {
63 LT_Invalid,
64 LT_Other,
Daniel Jasper50e7ab72013-01-22 14:28:24 +000065 LT_BuilderTypeCall,
Daniel Jasperda16db32013-01-07 10:48:50 +000066 LT_PreprocessorDirective,
67 LT_VirtualFunctionDecl,
Nico Weber2bb00742013-01-10 19:19:14 +000068 LT_ObjCDecl, // An @interface, @implementation, or @protocol line.
Nico Webera2a84952013-01-10 21:30:42 +000069 LT_ObjCMethodDecl,
70 LT_ObjCProperty // An @property line.
Daniel Jasperda16db32013-01-07 10:48:50 +000071};
72
Daniel Jasper7c85fde2013-01-08 14:56:18 +000073class AnnotatedToken {
74public:
Daniel Jasperaa701fa2013-01-18 08:44:07 +000075 explicit AnnotatedToken(const FormatToken &FormatTok)
Manuel Klimekb2c6dbe2013-01-10 19:17:33 +000076 : FormatTok(FormatTok), Type(TT_Unknown), SpaceRequiredBefore(false),
77 CanBreakBefore(false), MustBreakBefore(false),
Daniel Jasper7b5773e92013-01-28 07:35:34 +000078 ClosesTemplateDeclaration(false), MatchingParen(NULL),
79 ParameterCount(1), Parent(NULL) {
80 }
Daniel Jasper7c85fde2013-01-08 14:56:18 +000081
Daniel Jasper25837aa2013-01-14 14:14:23 +000082 bool is(tok::TokenKind Kind) const { return FormatTok.Tok.is(Kind); }
83 bool isNot(tok::TokenKind Kind) const { return FormatTok.Tok.isNot(Kind); }
84
Daniel Jasper7c85fde2013-01-08 14:56:18 +000085 bool isObjCAtKeyword(tok::ObjCKeywordKind Kind) const {
86 return FormatTok.Tok.isObjCAtKeyword(Kind);
87 }
88
89 FormatToken FormatTok;
90
Daniel Jasperf7935112012-12-03 18:12:45 +000091 TokenType Type;
92
Daniel Jasperf7935112012-12-03 18:12:45 +000093 bool SpaceRequiredBefore;
94 bool CanBreakBefore;
95 bool MustBreakBefore;
Daniel Jasperac5c1c22013-01-02 15:08:56 +000096
97 bool ClosesTemplateDeclaration;
Daniel Jasper7c85fde2013-01-08 14:56:18 +000098
Daniel Jasper9278eb92013-01-16 14:59:02 +000099 AnnotatedToken *MatchingParen;
100
Daniel Jasper7b5773e92013-01-28 07:35:34 +0000101 /// \brief Number of parameters, if this is "(", "[" or "<".
102 ///
103 /// This is initialized to 1 as we don't need to distinguish functions with
104 /// 0 parameters from functions with 1 parameter. Thus, we can simply count
105 /// the number of commas.
106 unsigned ParameterCount;
107
Daniel Jaspera67a8f02013-01-16 10:41:46 +0000108 /// \brief The total length of the line up to and including this token.
109 unsigned TotalLength;
110
Daniel Jaspercf330002013-01-29 15:03:01 +0000111 /// \brief Penalty for inserting a line break before this token.
112 unsigned SplitPenalty;
113
Daniel Jasper7c85fde2013-01-08 14:56:18 +0000114 std::vector<AnnotatedToken> Children;
115 AnnotatedToken *Parent;
Daniel Jasper11cb81c2013-01-17 12:53:34 +0000116
117 const AnnotatedToken *getPreviousNoneComment() const {
118 AnnotatedToken *Tok = Parent;
119 while (Tok != NULL && Tok->is(tok::comment))
120 Tok = Tok->Parent;
121 return Tok;
122 }
Daniel Jasperf7935112012-12-03 18:12:45 +0000123};
124
Daniel Jasperf1e4b7d2013-01-14 13:08:07 +0000125class AnnotatedLine {
126public:
Daniel Jasperdaffc0d2013-01-16 09:10:19 +0000127 AnnotatedLine(const UnwrappedLine &Line)
128 : First(Line.Tokens.front()), Level(Line.Level),
Manuel Klimek0a3a3c92013-01-23 09:32:48 +0000129 InPPDirective(Line.InPPDirective),
130 MustBeDeclaration(Line.MustBeDeclaration) {
Daniel Jasperdaffc0d2013-01-16 09:10:19 +0000131 assert(!Line.Tokens.empty());
132 AnnotatedToken *Current = &First;
133 for (std::list<FormatToken>::const_iterator I = ++Line.Tokens.begin(),
134 E = Line.Tokens.end();
135 I != E; ++I) {
Daniel Jasperaa701fa2013-01-18 08:44:07 +0000136 Current->Children.push_back(AnnotatedToken(*I));
Daniel Jasperdaffc0d2013-01-16 09:10:19 +0000137 Current->Children[0].Parent = Current;
138 Current = &Current->Children[0];
139 }
140 Last = Current;
141 }
142 AnnotatedLine(const AnnotatedLine &Other)
143 : First(Other.First), Type(Other.Type), Level(Other.Level),
Manuel Klimek0a3a3c92013-01-23 09:32:48 +0000144 InPPDirective(Other.InPPDirective),
145 MustBeDeclaration(Other.MustBeDeclaration) {
Daniel Jasperdaffc0d2013-01-16 09:10:19 +0000146 Last = &First;
147 while (!Last->Children.empty()) {
148 Last->Children[0].Parent = Last;
149 Last = &Last->Children[0];
150 }
151 }
152
Daniel Jasperf1e4b7d2013-01-14 13:08:07 +0000153 AnnotatedToken First;
154 AnnotatedToken *Last;
155
156 LineType Type;
157 unsigned Level;
158 bool InPPDirective;
Manuel Klimek0a3a3c92013-01-23 09:32:48 +0000159 bool MustBeDeclaration;
Daniel Jasperf1e4b7d2013-01-14 13:08:07 +0000160};
161
Daniel Jasper7c85fde2013-01-08 14:56:18 +0000162static prec::Level getPrecedence(const AnnotatedToken &Tok) {
163 return getBinOpPrecedence(Tok.FormatTok.Tok.getKind(), true, true);
Daniel Jasper2eda23e2012-12-24 13:43:52 +0000164}
165
Daniel Jasper20b09ef2013-01-28 09:35:24 +0000166bool isBinaryOperator(const AnnotatedToken &Tok) {
167 // Comma is a binary operator, but does not behave as such wrt. formatting.
168 return getPrecedence(Tok) > prec::Comma;
169}
170
Daniel Jasperf7935112012-12-03 18:12:45 +0000171FormatStyle getLLVMStyle() {
172 FormatStyle LLVMStyle;
173 LLVMStyle.ColumnLimit = 80;
174 LLVMStyle.MaxEmptyLinesToKeep = 1;
175 LLVMStyle.PointerAndReferenceBindToType = false;
176 LLVMStyle.AccessModifierOffset = -2;
177 LLVMStyle.SplitTemplateClosingGreater = true;
Alexander Kornienko578fdd82012-12-06 18:03:27 +0000178 LLVMStyle.IndentCaseLabels = false;
Daniel Jasper5ad1e192013-01-07 11:09:06 +0000179 LLVMStyle.SpacesBeforeTrailingComments = 1;
Daniel Jasper9278eb92013-01-16 14:59:02 +0000180 LLVMStyle.BinPackParameters = true;
Daniel Jaspere941b162013-01-23 10:08:28 +0000181 LLVMStyle.AllowAllParametersOnNextLine = true;
Daniel Jasperd36ef5e2013-01-28 15:40:20 +0000182 LLVMStyle.AllowReturnTypeOnItsOwnLine = true;
Daniel Jasper2408a8c2013-01-11 11:37:55 +0000183 LLVMStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = false;
Daniel Jasper1b750ed2013-01-14 16:24:39 +0000184 LLVMStyle.AllowShortIfStatementsOnASingleLine = false;
Nico Webera6087752013-01-10 20:12:55 +0000185 LLVMStyle.ObjCSpaceBeforeProtocolList = true;
Daniel Jasperf7935112012-12-03 18:12:45 +0000186 return LLVMStyle;
187}
188
189FormatStyle getGoogleStyle() {
190 FormatStyle GoogleStyle;
191 GoogleStyle.ColumnLimit = 80;
192 GoogleStyle.MaxEmptyLinesToKeep = 1;
193 GoogleStyle.PointerAndReferenceBindToType = true;
194 GoogleStyle.AccessModifierOffset = -1;
195 GoogleStyle.SplitTemplateClosingGreater = false;
Alexander Kornienko578fdd82012-12-06 18:03:27 +0000196 GoogleStyle.IndentCaseLabels = true;
Daniel Jasper5ad1e192013-01-07 11:09:06 +0000197 GoogleStyle.SpacesBeforeTrailingComments = 2;
Daniel Jasper9278eb92013-01-16 14:59:02 +0000198 GoogleStyle.BinPackParameters = false;
Daniel Jaspere941b162013-01-23 10:08:28 +0000199 GoogleStyle.AllowAllParametersOnNextLine = true;
Daniel Jasperd36ef5e2013-01-28 15:40:20 +0000200 GoogleStyle.AllowReturnTypeOnItsOwnLine = false;
Daniel Jasper2408a8c2013-01-11 11:37:55 +0000201 GoogleStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = true;
Daniel Jasperced17f82013-01-16 15:44:34 +0000202 GoogleStyle.AllowShortIfStatementsOnASingleLine = false;
Nico Webera6087752013-01-10 20:12:55 +0000203 GoogleStyle.ObjCSpaceBeforeProtocolList = false;
Daniel Jasperf7935112012-12-03 18:12:45 +0000204 return GoogleStyle;
205}
206
Daniel Jasper1b750ed2013-01-14 16:24:39 +0000207FormatStyle getChromiumStyle() {
208 FormatStyle ChromiumStyle = getGoogleStyle();
Daniel Jaspere941b162013-01-23 10:08:28 +0000209 ChromiumStyle.AllowAllParametersOnNextLine = false;
Daniel Jasper1b750ed2013-01-14 16:24:39 +0000210 return ChromiumStyle;
211}
212
Daniel Jasperf7935112012-12-03 18:12:45 +0000213struct OptimizationParameters {
Daniel Jasperf7935112012-12-03 18:12:45 +0000214 unsigned PenaltyIndentLevel;
Daniel Jasper2df93312013-01-09 10:16:05 +0000215 unsigned PenaltyExcessCharacter;
Daniel Jasperf7935112012-12-03 18:12:45 +0000216};
217
Daniel Jasperaa701fa2013-01-18 08:44:07 +0000218/// \brief Manages the whitespaces around tokens and their replacements.
Manuel Klimek0b689fd2013-01-10 18:45:26 +0000219///
Daniel Jasperaa701fa2013-01-18 08:44:07 +0000220/// This includes special handling for certain constructs, e.g. the alignment of
221/// trailing line comments.
222class WhitespaceManager {
223public:
224 WhitespaceManager(SourceManager &SourceMgr) : SourceMgr(SourceMgr) {}
225
226 /// \brief Replaces the whitespace in front of \p Tok. Only call once for
227 /// each \c AnnotatedToken.
228 void replaceWhitespace(const AnnotatedToken &Tok, unsigned NewLines,
229 unsigned Spaces, unsigned WhitespaceStartColumn,
230 const FormatStyle &Style) {
Daniel Jasper304a9862013-01-21 22:49:20 +0000231 // 2+ newlines mean an empty line separating logic scopes.
232 if (NewLines >= 2)
233 alignComments();
234
235 // Align line comments if they are trailing or if they continue other
236 // trailing comments.
237 if (Tok.Type == TT_LineComment &&
Daniel Jasperaa701fa2013-01-18 08:44:07 +0000238 (Tok.Parent != NULL || !Comments.empty())) {
239 if (Style.ColumnLimit >=
240 Spaces + WhitespaceStartColumn + Tok.FormatTok.TokenLength) {
241 Comments.push_back(StoredComment());
242 Comments.back().Tok = Tok.FormatTok;
243 Comments.back().Spaces = Spaces;
244 Comments.back().NewLines = NewLines;
245 Comments.back().MinColumn = WhitespaceStartColumn + Spaces;
Daniel Jasperbbc84152013-01-29 11:27:30 +0000246 Comments.back().MaxColumn =
247 Style.ColumnLimit - Spaces - Tok.FormatTok.TokenLength;
Daniel Jasperaa701fa2013-01-18 08:44:07 +0000248 return;
249 }
Daniel Jasperaa701fa2013-01-18 08:44:07 +0000250 }
Daniel Jasper304a9862013-01-21 22:49:20 +0000251
252 // If this line does not have a trailing comment, align the stored comments.
253 if (Tok.Children.empty() && Tok.Type != TT_LineComment)
254 alignComments();
Daniel Jasperaa701fa2013-01-18 08:44:07 +0000255 storeReplacement(Tok.FormatTok,
256 std::string(NewLines, '\n') + std::string(Spaces, ' '));
257 }
258
259 /// \brief Like \c replaceWhitespace, but additionally adds right-aligned
260 /// backslashes to escape newlines inside a preprocessor directive.
261 ///
262 /// This function and \c replaceWhitespace have the same behavior if
263 /// \c Newlines == 0.
264 void replacePPWhitespace(const AnnotatedToken &Tok, unsigned NewLines,
265 unsigned Spaces, unsigned WhitespaceStartColumn,
266 const FormatStyle &Style) {
267 std::string NewLineText;
268 if (NewLines > 0) {
Daniel Jasperbbc84152013-01-29 11:27:30 +0000269 unsigned Offset =
270 std::min<int>(Style.ColumnLimit - 1, WhitespaceStartColumn);
Daniel Jasperaa701fa2013-01-18 08:44:07 +0000271 for (unsigned i = 0; i < NewLines; ++i) {
272 NewLineText += std::string(Style.ColumnLimit - Offset - 1, ' ');
273 NewLineText += "\\\n";
274 Offset = 0;
275 }
276 }
277 storeReplacement(Tok.FormatTok, NewLineText + std::string(Spaces, ' '));
278 }
279
280 /// \brief Returns all the \c Replacements created during formatting.
281 const tooling::Replacements &generateReplacements() {
282 alignComments();
283 return Replaces;
284 }
285
286private:
287 /// \brief Structure to store a comment for later layout and alignment.
288 struct StoredComment {
289 FormatToken Tok;
290 unsigned MinColumn;
291 unsigned MaxColumn;
292 unsigned NewLines;
293 unsigned Spaces;
294 };
295 SmallVector<StoredComment, 16> Comments;
296 typedef SmallVector<StoredComment, 16>::iterator comment_iterator;
297
298 /// \brief Try to align all stashed comments.
299 void alignComments() {
300 unsigned MinColumn = 0;
301 unsigned MaxColumn = UINT_MAX;
302 comment_iterator Start = Comments.begin();
303 for (comment_iterator I = Comments.begin(), E = Comments.end(); I != E;
304 ++I) {
305 if (I->MinColumn > MaxColumn || I->MaxColumn < MinColumn) {
306 alignComments(Start, I, MinColumn);
307 MinColumn = I->MinColumn;
308 MaxColumn = I->MaxColumn;
309 Start = I;
310 } else {
311 MinColumn = std::max(MinColumn, I->MinColumn);
312 MaxColumn = std::min(MaxColumn, I->MaxColumn);
313 }
314 }
315 alignComments(Start, Comments.end(), MinColumn);
316 Comments.clear();
317 }
318
319 /// \brief Put all the comments between \p I and \p E into \p Column.
320 void alignComments(comment_iterator I, comment_iterator E, unsigned Column) {
321 while (I != E) {
322 unsigned Spaces = I->Spaces + Column - I->MinColumn;
323 storeReplacement(I->Tok, std::string(I->NewLines, '\n') +
324 std::string(Spaces, ' '));
325 ++I;
Manuel Klimek0b689fd2013-01-10 18:45:26 +0000326 }
327 }
Daniel Jasperaa701fa2013-01-18 08:44:07 +0000328
329 /// \brief Stores \p Text as the replacement for the whitespace in front of
330 /// \p Tok.
331 void storeReplacement(const FormatToken &Tok, const std::string Text) {
332 Replaces.insert(tooling::Replacement(SourceMgr, Tok.WhiteSpaceStart,
333 Tok.WhiteSpaceLength, Text));
334 }
335
336 SourceManager &SourceMgr;
337 tooling::Replacements Replaces;
338};
Manuel Klimek0b689fd2013-01-10 18:45:26 +0000339
Nico Weberc9d73612013-01-12 22:48:47 +0000340/// \brief Returns if a token is an Objective-C selector name.
341///
Nico Weber92c05392013-01-12 22:51:13 +0000342/// For example, "bar" is a selector name in [foo bar:(4 + 5)].
Nico Weberc9d73612013-01-12 22:48:47 +0000343static bool isObjCSelectorName(const AnnotatedToken &Tok) {
344 return Tok.is(tok::identifier) && !Tok.Children.empty() &&
345 Tok.Children[0].is(tok::colon) &&
346 Tok.Children[0].Type == TT_ObjCMethodExpr;
347}
348
Daniel Jasperf7935112012-12-03 18:12:45 +0000349class UnwrappedLineFormatter {
350public:
Manuel Klimekb2c6dbe2013-01-10 19:17:33 +0000351 UnwrappedLineFormatter(const FormatStyle &Style, SourceManager &SourceMgr,
Daniel Jasperf1e4b7d2013-01-14 13:08:07 +0000352 const AnnotatedLine &Line, unsigned FirstIndent,
Daniel Jaspera67a8f02013-01-16 10:41:46 +0000353 const AnnotatedToken &RootToken,
Daniel Jasperaa701fa2013-01-18 08:44:07 +0000354 WhitespaceManager &Whitespaces, bool StructuralError)
Daniel Jasper2af6bbe2012-12-18 21:05:13 +0000355 : Style(Style), SourceMgr(SourceMgr), Line(Line),
Daniel Jasperaa701fa2013-01-18 08:44:07 +0000356 FirstIndent(FirstIndent), RootToken(RootToken),
357 Whitespaces(Whitespaces) {
Daniel Jasper04468962013-01-18 10:56:38 +0000358 Parameters.PenaltyIndentLevel = 20;
Daniel Jasper2df93312013-01-09 10:16:05 +0000359 Parameters.PenaltyExcessCharacter = 1000000;
Daniel Jasperf7935112012-12-03 18:12:45 +0000360 }
361
Manuel Klimek1abf7892013-01-04 23:34:14 +0000362 /// \brief Formats an \c UnwrappedLine.
363 ///
364 /// \returns The column after the last token in the last line of the
365 /// \c UnwrappedLine.
366 unsigned format() {
Daniel Jaspere9de2602012-12-06 09:56:08 +0000367 // Initialize state dependent on indent.
Daniel Jasper337816e2013-01-11 10:22:12 +0000368 LineState State;
Manuel Klimek0b689fd2013-01-10 18:45:26 +0000369 State.Column = FirstIndent;
Daniel Jasper7c85fde2013-01-08 14:56:18 +0000370 State.NextToken = &RootToken;
Daniel Jasper2408a8c2013-01-11 11:37:55 +0000371 State.Stack.push_back(ParenState(FirstIndent + 4, FirstIndent));
Daniel Jasper38c11ce2013-01-29 11:21:01 +0000372 State.VariablePos = 0;
Daniel Jasperfbde69e2012-12-21 14:37:20 +0000373 State.LineContainsContinuedForLoopSection = false;
Daniel Jaspere9de2602012-12-06 09:56:08 +0000374
Manuel Klimek24998102013-01-16 14:55:28 +0000375 DEBUG({
376 DebugTokenState(*State.NextToken);
377 });
378
Daniel Jaspere9de2602012-12-06 09:56:08 +0000379 // The first token has already been indented and thus consumed.
380 moveStateToNextToken(State);
Daniel Jasperf7935112012-12-03 18:12:45 +0000381
382 // Start iterating at 1 as we have correctly formatted of Token #0 above.
Daniel Jasper7c85fde2013-01-08 14:56:18 +0000383 while (State.NextToken != NULL) {
Daniel Jasper997b08c2013-01-18 09:19:33 +0000384 if (State.NextToken->Type == TT_ImplicitStringLiteral) {
385 // Calculating the column is important for aligning trailing comments.
386 // FIXME: This does not seem to happen in conjunction with escaped
387 // newlines. If it does, fix!
388 State.Column += State.NextToken->FormatTok.WhiteSpaceLength +
389 State.NextToken->FormatTok.TokenLength;
Daniel Jasperbbc84152013-01-29 11:27:30 +0000390 State.NextToken = State.NextToken->Children.empty()
391 ? NULL : &State.NextToken->Children[0];
Daniel Jasper997b08c2013-01-18 09:19:33 +0000392 } else if (Line.Last->TotalLength <= getColumnLimit() - FirstIndent) {
Daniel Jasper2af6bbe2012-12-18 21:05:13 +0000393 addTokenToState(false, false, State);
394 } else {
395 unsigned NoBreak = calcPenalty(State, false, UINT_MAX);
396 unsigned Break = calcPenalty(State, true, NoBreak);
Manuel Klimek24998102013-01-16 14:55:28 +0000397 DEBUG({
398 if (Break < NoBreak)
399 llvm::errs() << "\n";
400 else
401 llvm::errs() << " ";
402 llvm::errs() << "<";
403 DebugPenalty(Break, Break < NoBreak);
404 llvm::errs() << "/";
405 DebugPenalty(NoBreak, !(Break < NoBreak));
406 llvm::errs() << "> ";
407 DebugTokenState(*State.NextToken);
408 });
Daniel Jasper2af6bbe2012-12-18 21:05:13 +0000409 addTokenToState(Break < NoBreak, false, State);
Daniel Jasper2408a8c2013-01-11 11:37:55 +0000410 if (State.NextToken != NULL &&
411 State.NextToken->Parent->Type == TT_CtorInitializerColon) {
412 if (Style.ConstructorInitializerAllOnOneLineOrOnePerLine &&
Daniel Jaspera67a8f02013-01-16 10:41:46 +0000413 Line.Last->TotalLength > getColumnLimit() - State.Column - 1)
Daniel Jasper2408a8c2013-01-11 11:37:55 +0000414 State.Stack.back().BreakAfterComma = true;
415 }
Daniel Jasper2af6bbe2012-12-18 21:05:13 +0000416 }
Daniel Jasperf7935112012-12-03 18:12:45 +0000417 }
Manuel Klimek24998102013-01-16 14:55:28 +0000418 DEBUG(llvm::errs() << "\n");
Manuel Klimek1abf7892013-01-04 23:34:14 +0000419 return State.Column;
Daniel Jasperf7935112012-12-03 18:12:45 +0000420 }
421
422private:
Manuel Klimek24998102013-01-16 14:55:28 +0000423 void DebugTokenState(const AnnotatedToken &AnnotatedTok) {
424 const Token &Tok = AnnotatedTok.FormatTok.Tok;
Daniel Jasperbbc84152013-01-29 11:27:30 +0000425 llvm::errs() << StringRef(SourceMgr.getCharacterData(Tok.getLocation()),
426 Tok.getLength());
Manuel Klimek24998102013-01-16 14:55:28 +0000427 llvm::errs();
428 }
429
430 void DebugPenalty(unsigned Penalty, bool Winner) {
431 llvm::errs().changeColor(Winner ? raw_ostream::GREEN : raw_ostream::RED);
432 if (Penalty == UINT_MAX)
433 llvm::errs() << "MAX";
434 else
435 llvm::errs() << Penalty;
436 llvm::errs().resetColor();
437 }
438
Daniel Jasper337816e2013-01-11 10:22:12 +0000439 struct ParenState {
Daniel Jasper2408a8c2013-01-11 11:37:55 +0000440 ParenState(unsigned Indent, unsigned LastSpace)
Daniel Jaspera836b902013-01-23 16:58:21 +0000441 : Indent(Indent), LastSpace(LastSpace), AssignmentColumn(0),
Daniel Jasperca6623b2013-01-28 12:45:14 +0000442 FirstLessLess(0), BreakBeforeClosingBrace(false), QuestionColumn(0),
Daniel Jasperbbc84152013-01-29 11:27:30 +0000443 BreakAfterComma(false), HasMultiParameterLine(false) {
444 }
Daniel Jasper6d822722012-12-24 16:43:00 +0000445
Daniel Jasperf7935112012-12-03 18:12:45 +0000446 /// \brief The position to which a specific parenthesis level needs to be
447 /// indented.
Daniel Jasper337816e2013-01-11 10:22:12 +0000448 unsigned Indent;
Daniel Jasperf7935112012-12-03 18:12:45 +0000449
Daniel Jaspere9de2602012-12-06 09:56:08 +0000450 /// \brief The position of the last space on each level.
451 ///
452 /// Used e.g. to break like:
453 /// functionCall(Parameter, otherCall(
454 /// OtherParameter));
Daniel Jasper337816e2013-01-11 10:22:12 +0000455 unsigned LastSpace;
Daniel Jasperf7935112012-12-03 18:12:45 +0000456
Daniel Jaspera836b902013-01-23 16:58:21 +0000457 /// \brief This is the column of the first token after an assignment.
458 unsigned AssignmentColumn;
459
Daniel Jaspere9de2602012-12-06 09:56:08 +0000460 /// \brief The position the first "<<" operator encountered on each level.
461 ///
462 /// Used to align "<<" operators. 0 if no such operator has been encountered
463 /// on a level.
Daniel Jasper337816e2013-01-11 10:22:12 +0000464 unsigned FirstLessLess;
Daniel Jaspere9de2602012-12-06 09:56:08 +0000465
Manuel Klimek0ddd57a2013-01-10 15:58:26 +0000466 /// \brief Whether a newline needs to be inserted before the block's closing
467 /// brace.
468 ///
469 /// We only want to insert a newline before the closing brace if there also
470 /// was a newline after the beginning left brace.
Daniel Jasper337816e2013-01-11 10:22:12 +0000471 bool BreakBeforeClosingBrace;
472
Daniel Jasperca6623b2013-01-28 12:45:14 +0000473 /// \brief The column of a \c ? in a conditional expression;
474 unsigned QuestionColumn;
475
Daniel Jasper2408a8c2013-01-11 11:37:55 +0000476 bool BreakAfterComma;
Daniel Jasper9278eb92013-01-16 14:59:02 +0000477 bool HasMultiParameterLine;
Daniel Jasper2408a8c2013-01-11 11:37:55 +0000478
Daniel Jasper337816e2013-01-11 10:22:12 +0000479 bool operator<(const ParenState &Other) const {
480 if (Indent != Other.Indent)
Daniel Jasperfd8c4b12013-01-11 14:23:32 +0000481 return Indent < Other.Indent;
Daniel Jasper337816e2013-01-11 10:22:12 +0000482 if (LastSpace != Other.LastSpace)
483 return LastSpace < Other.LastSpace;
Daniel Jaspera836b902013-01-23 16:58:21 +0000484 if (AssignmentColumn != Other.AssignmentColumn)
485 return AssignmentColumn < Other.AssignmentColumn;
Daniel Jasper337816e2013-01-11 10:22:12 +0000486 if (FirstLessLess != Other.FirstLessLess)
487 return FirstLessLess < Other.FirstLessLess;
Daniel Jasper2408a8c2013-01-11 11:37:55 +0000488 if (BreakBeforeClosingBrace != Other.BreakBeforeClosingBrace)
489 return BreakBeforeClosingBrace;
Daniel Jasperca6623b2013-01-28 12:45:14 +0000490 if (QuestionColumn != Other.QuestionColumn)
491 return QuestionColumn < Other.QuestionColumn;
Daniel Jasper7b7877a2013-01-12 07:36:22 +0000492 if (BreakAfterComma != Other.BreakAfterComma)
493 return BreakAfterComma;
Daniel Jasper9278eb92013-01-16 14:59:02 +0000494 if (HasMultiParameterLine != Other.HasMultiParameterLine)
495 return HasMultiParameterLine;
Daniel Jasper7b7877a2013-01-12 07:36:22 +0000496 return false;
Daniel Jasper337816e2013-01-11 10:22:12 +0000497 }
498 };
499
500 /// \brief The current state when indenting a unwrapped line.
501 ///
502 /// As the indenting tries different combinations this is copied by value.
503 struct LineState {
504 /// \brief The number of used columns in the current line.
505 unsigned Column;
506
507 /// \brief The token that needs to be next formatted.
508 const AnnotatedToken *NextToken;
509
Daniel Jasperbbc84152013-01-29 11:27:30 +0000510 /// \brief The column of the first variable name in a variable declaration.
Daniel Jasperfbde69e2012-12-21 14:37:20 +0000511 ///
Daniel Jasperbbc84152013-01-29 11:27:30 +0000512 /// Used to align further variables if necessary.
Daniel Jasper38c11ce2013-01-29 11:21:01 +0000513 unsigned VariablePos;
Daniel Jasperfbde69e2012-12-21 14:37:20 +0000514
515 /// \brief \c true if this line contains a continued for-loop section.
516 bool LineContainsContinuedForLoopSection;
517
Daniel Jasper337816e2013-01-11 10:22:12 +0000518 /// \brief A stack keeping track of properties applying to parenthesis
519 /// levels.
520 std::vector<ParenState> Stack;
521
522 /// \brief Comparison operator to be able to used \c LineState in \c map.
523 bool operator<(const LineState &Other) const {
Daniel Jasper7c85fde2013-01-08 14:56:18 +0000524 if (Other.NextToken != NextToken)
525 return Other.NextToken > NextToken;
Daniel Jasperf7935112012-12-03 18:12:45 +0000526 if (Other.Column != Column)
527 return Other.Column > Column;
Daniel Jasper38c11ce2013-01-29 11:21:01 +0000528 if (Other.VariablePos != VariablePos)
529 return Other.VariablePos < VariablePos;
Daniel Jasperfbde69e2012-12-21 14:37:20 +0000530 if (Other.LineContainsContinuedForLoopSection !=
531 LineContainsContinuedForLoopSection)
532 return LineContainsContinuedForLoopSection;
Daniel Jasper337816e2013-01-11 10:22:12 +0000533 return Other.Stack < Stack;
Daniel Jasperf7935112012-12-03 18:12:45 +0000534 }
535 };
536
Daniel Jasper6021c4a2012-12-04 14:54:30 +0000537 /// \brief Appends the next token to \p State and updates information
538 /// necessary for indentation.
539 ///
540 /// Puts the token on the current line if \p Newline is \c true and adds a
541 /// line break and necessary indentation otherwise.
542 ///
543 /// If \p DryRun is \c false, also creates and stores the required
544 /// \c Replacement.
Daniel Jasper337816e2013-01-11 10:22:12 +0000545 void addTokenToState(bool Newline, bool DryRun, LineState &State) {
Daniel Jasper399d24b2013-01-09 07:06:56 +0000546 const AnnotatedToken &Current = *State.NextToken;
547 const AnnotatedToken &Previous = *State.NextToken->Parent;
Daniel Jasper337816e2013-01-11 10:22:12 +0000548 assert(State.Stack.size());
549 unsigned ParenLevel = State.Stack.size() - 1;
Daniel Jasperf7935112012-12-03 18:12:45 +0000550
551 if (Newline) {
Manuel Klimekb69e3c62013-01-02 18:33:23 +0000552 unsigned WhitespaceStartColumn = State.Column;
Manuel Klimek8e07a1b2013-01-10 11:52:21 +0000553 if (Current.is(tok::r_brace)) {
554 State.Column = Line.Level * 2;
Daniel Jasper399d24b2013-01-09 07:06:56 +0000555 } else if (Current.is(tok::string_literal) &&
556 Previous.is(tok::string_literal)) {
557 State.Column = State.Column - Previous.FormatTok.TokenLength;
558 } else if (Current.is(tok::lessless) &&
Daniel Jasper337816e2013-01-11 10:22:12 +0000559 State.Stack[ParenLevel].FirstLessLess != 0) {
560 State.Column = State.Stack[ParenLevel].FirstLessLess;
Daniel Jasperfbde69e2012-12-21 14:37:20 +0000561 } else if (ParenLevel != 0 &&
Daniel Jasper4ad42352013-01-28 07:43:15 +0000562 (Previous.is(tok::equal) || Previous.is(tok::coloncolon) ||
Daniel Jasperca6623b2013-01-28 12:45:14 +0000563 Current.is(tok::period) || Current.is(tok::arrow) ||
564 Current.is(tok::question))) {
Daniel Jasper399d24b2013-01-09 07:06:56 +0000565 // Indent and extra 4 spaces after if we know the current expression is
566 // continued. Don't do that on the top level, as we already indent 4
567 // there.
Daniel Jasperca6623b2013-01-28 12:45:14 +0000568 State.Column = std::max(State.Stack.back().LastSpace,
569 State.Stack.back().Indent) + 4;
570 } else if (Current.Type == TT_ConditionalExpr) {
571 State.Column = State.Stack.back().QuestionColumn;
Daniel Jasper38c11ce2013-01-29 11:21:01 +0000572 } else if (Previous.is(tok::comma) && State.VariablePos != 0 &&
573 ((RootToken.is(tok::kw_for) && ParenLevel == 1) ||
574 ParenLevel == 0)) {
575 State.Column = State.VariablePos;
Daniel Jasperd2639ef2013-01-28 15:16:31 +0000576 } else if (State.NextToken->Parent->ClosesTemplateDeclaration ||
577 Current.Type == TT_StartOfName) {
Daniel Jasper337816e2013-01-11 10:22:12 +0000578 State.Column = State.Stack[ParenLevel].Indent - 4;
Daniel Jaspera836b902013-01-23 16:58:21 +0000579 } else if (Previous.Type == TT_BinaryOperator &&
580 State.Stack.back().AssignmentColumn != 0) {
581 State.Column = State.Stack.back().AssignmentColumn;
Daniel Jasperfbde69e2012-12-21 14:37:20 +0000582 } else {
Daniel Jasper337816e2013-01-11 10:22:12 +0000583 State.Column = State.Stack[ParenLevel].Indent;
Daniel Jasperfbde69e2012-12-21 14:37:20 +0000584 }
585
Daniel Jasper7c85fde2013-01-08 14:56:18 +0000586 if (RootToken.is(tok::kw_for))
Daniel Jasper399d24b2013-01-09 07:06:56 +0000587 State.LineContainsContinuedForLoopSection = Previous.isNot(tok::semi);
Daniel Jasper6021c4a2012-12-04 14:54:30 +0000588
Manuel Klimekb69e3c62013-01-02 18:33:23 +0000589 if (!DryRun) {
590 if (!Line.InPPDirective)
Daniel Jasperaa701fa2013-01-18 08:44:07 +0000591 Whitespaces.replaceWhitespace(Current, 1, State.Column,
592 WhitespaceStartColumn, Style);
Manuel Klimekb69e3c62013-01-02 18:33:23 +0000593 else
Daniel Jasperaa701fa2013-01-18 08:44:07 +0000594 Whitespaces.replacePPWhitespace(Current, 1, State.Column,
595 WhitespaceStartColumn, Style);
Manuel Klimekb69e3c62013-01-02 18:33:23 +0000596 }
Daniel Jasperf7935112012-12-03 18:12:45 +0000597
Daniel Jasper337816e2013-01-11 10:22:12 +0000598 State.Stack[ParenLevel].LastSpace = State.Column;
Daniel Jasperca6623b2013-01-28 12:45:14 +0000599 if (Current.is(tok::colon) && Current.Type != TT_ConditionalExpr)
Daniel Jasper337816e2013-01-11 10:22:12 +0000600 State.Stack[ParenLevel].Indent += 2;
Daniel Jasperf7935112012-12-03 18:12:45 +0000601 } else {
Daniel Jasper38c11ce2013-01-29 11:21:01 +0000602 if (Current.is(tok::equal) &&
603 (RootToken.is(tok::kw_for) || ParenLevel == 0))
604 State.VariablePos = State.Column - Previous.FormatTok.TokenLength;
Daniel Jasperfbde69e2012-12-21 14:37:20 +0000605
Daniel Jasper7c85fde2013-01-08 14:56:18 +0000606 unsigned Spaces = State.NextToken->SpaceRequiredBefore ? 1 : 0;
607 if (State.NextToken->Type == TT_LineComment)
Daniel Jasper5ad1e192013-01-07 11:09:06 +0000608 Spaces = Style.SpacesBeforeTrailingComments;
Daniel Jasper6021c4a2012-12-04 14:54:30 +0000609
Daniel Jasperf7935112012-12-03 18:12:45 +0000610 if (!DryRun)
Daniel Jasperaa701fa2013-01-18 08:44:07 +0000611 Whitespaces.replaceWhitespace(Current, 0, Spaces, State.Column, Style);
Daniel Jasper6021c4a2012-12-04 14:54:30 +0000612
Daniel Jasperbcab4302013-01-09 10:40:23 +0000613 // FIXME: Do we need to do this for assignments nested in other
614 // expressions?
615 if (RootToken.isNot(tok::kw_for) && ParenLevel == 0 &&
Daniel Jasper206df732013-01-07 13:08:40 +0000616 (getPrecedence(Previous) == prec::Assignment ||
Daniel Jasper399d24b2013-01-09 07:06:56 +0000617 Previous.is(tok::kw_return)))
Daniel Jaspera836b902013-01-23 16:58:21 +0000618 State.Stack.back().AssignmentColumn = State.Column + Spaces;
Daniel Jasperfd8c4b12013-01-11 14:23:32 +0000619 if (Previous.is(tok::l_paren) || Previous.is(tok::l_brace) ||
Daniel Jasper7c85fde2013-01-08 14:56:18 +0000620 State.NextToken->Parent->Type == TT_TemplateOpener)
Daniel Jasper337816e2013-01-11 10:22:12 +0000621 State.Stack[ParenLevel].Indent = State.Column + Spaces;
Manuel Klimekf92f7bc2013-01-22 16:31:55 +0000622 if (Current.getPreviousNoneComment() != NULL &&
623 Current.getPreviousNoneComment()->is(tok::comma) &&
Daniel Jasper11cb81c2013-01-17 12:53:34 +0000624 Current.isNot(tok::comment))
Daniel Jasper9278eb92013-01-16 14:59:02 +0000625 State.Stack[ParenLevel].HasMultiParameterLine = true;
626
Daniel Jaspere9de2602012-12-06 09:56:08 +0000627 State.Column += Spaces;
Daniel Jasper39e27382013-01-23 20:41:06 +0000628 if (Current.is(tok::l_paren) && Previous.is(tok::kw_if))
629 // Treat the condition inside an if as if it was a second function
630 // parameter, i.e. let nested calls have an indent of 4.
631 State.Stack.back().LastSpace = State.Column + 1; // 1 is length of "(".
Daniel Jasper7a31af12013-01-25 15:43:32 +0000632 else if (Previous.is(tok::comma) && ParenLevel != 0)
Daniel Jasper39e27382013-01-23 20:41:06 +0000633 // Top-level spaces are exempt as that mostly leads to better results.
634 State.Stack.back().LastSpace = State.Column;
Daniel Jasperca6623b2013-01-28 12:45:14 +0000635 else if ((Previous.Type == TT_BinaryOperator ||
Daniel Jasper65585ed2013-01-28 13:31:35 +0000636 Previous.Type == TT_ConditionalExpr ||
637 Previous.Type == TT_CtorInitializerColon) &&
Daniel Jasper20b09ef2013-01-28 09:35:24 +0000638 getPrecedence(Previous) != prec::Assignment)
639 State.Stack.back().LastSpace = State.Column;
Daniel Jasper7b5773e92013-01-28 07:35:34 +0000640 else if (Previous.ParameterCount > 1 &&
641 (Previous.is(tok::l_paren) || Previous.is(tok::l_square) ||
642 Previous.Type == TT_TemplateOpener))
643 // If this function has multiple parameters, indent nested calls from
644 // the start of the first parameter.
645 State.Stack.back().LastSpace = State.Column;
Daniel Jasperf7935112012-12-03 18:12:45 +0000646 }
Daniel Jasper9278eb92013-01-16 14:59:02 +0000647
648 // If we break after an {, we should also break before the corresponding }.
649 if (Newline && Previous.is(tok::l_brace))
Daniel Jasper337816e2013-01-11 10:22:12 +0000650 State.Stack.back().BreakBeforeClosingBrace = true;
Daniel Jasper9278eb92013-01-16 14:59:02 +0000651
Daniel Jaspere941b162013-01-23 10:08:28 +0000652 if (!Style.BinPackParameters && Newline) {
653 // If we are breaking after '(', '{', '<', this is not bin packing unless
654 // AllowAllParametersOnNextLine is false.
655 if ((Previous.isNot(tok::l_paren) && Previous.isNot(tok::l_brace) &&
656 Previous.Type != TT_TemplateOpener) ||
657 !Style.AllowAllParametersOnNextLine)
658 State.Stack.back().BreakAfterComma = true;
Daniel Jasper38c11ce2013-01-29 11:21:01 +0000659
Daniel Jaspere941b162013-01-23 10:08:28 +0000660 // Any break on this level means that the parent level has been broken
661 // and we need to avoid bin packing there.
662 for (unsigned i = 0, e = State.Stack.size() - 1; i != e; ++i) {
663 State.Stack[i].BreakAfterComma = true;
664 }
665 }
Daniel Jasper9278eb92013-01-16 14:59:02 +0000666
Manuel Klimeka54d1a92013-01-14 16:41:43 +0000667 moveStateToNextToken(State);
Daniel Jasper6021c4a2012-12-04 14:54:30 +0000668 }
Daniel Jasperf7935112012-12-03 18:12:45 +0000669
Daniel Jasper6021c4a2012-12-04 14:54:30 +0000670 /// \brief Mark the next token as consumed in \p State and modify its stacks
671 /// accordingly.
Daniel Jasper337816e2013-01-11 10:22:12 +0000672 void moveStateToNextToken(LineState &State) {
Daniel Jasper7c85fde2013-01-08 14:56:18 +0000673 const AnnotatedToken &Current = *State.NextToken;
Daniel Jasper337816e2013-01-11 10:22:12 +0000674 assert(State.Stack.size());
Daniel Jaspere9de2602012-12-06 09:56:08 +0000675
Daniel Jasper337816e2013-01-11 10:22:12 +0000676 if (Current.is(tok::lessless) && State.Stack.back().FirstLessLess == 0)
677 State.Stack.back().FirstLessLess = State.Column;
Daniel Jasperca6623b2013-01-28 12:45:14 +0000678 if (Current.is(tok::question))
679 State.Stack.back().QuestionColumn = State.Column;
Daniel Jaspere9de2602012-12-06 09:56:08 +0000680
Daniel Jasper2eda23e2012-12-24 13:43:52 +0000681 // If we encounter an opening (, [, { or <, we add a level to our stacks to
Daniel Jasper6021c4a2012-12-04 14:54:30 +0000682 // prepare for the following tokens.
Daniel Jasper7c85fde2013-01-08 14:56:18 +0000683 if (Current.is(tok::l_paren) || Current.is(tok::l_square) ||
684 Current.is(tok::l_brace) ||
685 State.NextToken->Type == TT_TemplateOpener) {
Daniel Jasper337816e2013-01-11 10:22:12 +0000686 unsigned NewIndent;
Manuel Klimek73a2fdf2013-01-10 14:36:46 +0000687 if (Current.is(tok::l_brace)) {
688 // FIXME: This does not work with nested static initializers.
689 // Implement a better handling for static initializers and similar
690 // constructs.
Daniel Jasper337816e2013-01-11 10:22:12 +0000691 NewIndent = Line.Level * 2 + 2;
Manuel Klimek73a2fdf2013-01-10 14:36:46 +0000692 } else {
Daniel Jasper337816e2013-01-11 10:22:12 +0000693 NewIndent = 4 + State.Stack.back().LastSpace;
Manuel Klimek73a2fdf2013-01-10 14:36:46 +0000694 }
Daniel Jasperbbc84152013-01-29 11:27:30 +0000695 State.Stack.push_back(ParenState(NewIndent,
696 State.Stack.back().LastSpace));
Daniel Jasper6021c4a2012-12-04 14:54:30 +0000697 }
698
Daniel Jasper2eda23e2012-12-24 13:43:52 +0000699 // If we encounter a closing ), ], } or >, we can remove a level from our
Daniel Jasper6021c4a2012-12-04 14:54:30 +0000700 // stacks.
Daniel Jasper7c85fde2013-01-08 14:56:18 +0000701 if (Current.is(tok::r_paren) || Current.is(tok::r_square) ||
702 (Current.is(tok::r_brace) && State.NextToken != &RootToken) ||
703 State.NextToken->Type == TT_TemplateCloser) {
Daniel Jasper337816e2013-01-11 10:22:12 +0000704 State.Stack.pop_back();
Daniel Jasperf7935112012-12-03 18:12:45 +0000705 }
Manuel Klimek73a2fdf2013-01-10 14:36:46 +0000706
Daniel Jasper7c85fde2013-01-08 14:56:18 +0000707 if (State.NextToken->Children.empty())
708 State.NextToken = NULL;
709 else
710 State.NextToken = &State.NextToken->Children[0];
Manuel Klimek73a2fdf2013-01-10 14:36:46 +0000711
712 State.Column += Current.FormatTok.TokenLength;
Daniel Jasperf7935112012-12-03 18:12:45 +0000713 }
714
Daniel Jasper2df93312013-01-09 10:16:05 +0000715 unsigned getColumnLimit() {
716 return Style.ColumnLimit - (Line.InPPDirective ? 1 : 0);
717 }
718
Daniel Jasperf7935112012-12-03 18:12:45 +0000719 /// \brief Calculate the number of lines needed to format the remaining part
720 /// of the unwrapped line.
721 ///
722 /// Assumes the formatting so far has led to
Daniel Jasper337816e2013-01-11 10:22:12 +0000723 /// the \c LineSta \p State. If \p NewLine is set, a new line will be
Daniel Jasperf7935112012-12-03 18:12:45 +0000724 /// added after the previous token.
725 ///
726 /// \param StopAt is used for optimization. If we can determine that we'll
727 /// definitely need at least \p StopAt additional lines, we already know of a
728 /// better solution.
Daniel Jasper337816e2013-01-11 10:22:12 +0000729 unsigned calcPenalty(LineState State, bool NewLine, unsigned StopAt) {
Daniel Jasperf7935112012-12-03 18:12:45 +0000730 // We are at the end of the unwrapped line, so we don't need any more lines.
Daniel Jasper7c85fde2013-01-08 14:56:18 +0000731 if (State.NextToken == NULL)
Daniel Jasperf7935112012-12-03 18:12:45 +0000732 return 0;
733
Daniel Jasper7c85fde2013-01-08 14:56:18 +0000734 if (!NewLine && State.NextToken->MustBreakBefore)
Daniel Jasperf7935112012-12-03 18:12:45 +0000735 return UINT_MAX;
Manuel Klimeka54d1a92013-01-14 16:41:43 +0000736 if (NewLine && !State.NextToken->CanBreakBefore &&
737 !(State.NextToken->is(tok::r_brace) &&
738 State.Stack.back().BreakBeforeClosingBrace))
Daniel Jasperf7935112012-12-03 18:12:45 +0000739 return UINT_MAX;
Manuel Klimek0ddd57a2013-01-10 15:58:26 +0000740 if (!NewLine && State.NextToken->is(tok::r_brace) &&
Daniel Jasper337816e2013-01-11 10:22:12 +0000741 State.Stack.back().BreakBeforeClosingBrace)
Manuel Klimek0ddd57a2013-01-10 15:58:26 +0000742 return UINT_MAX;
Daniel Jasper7c85fde2013-01-08 14:56:18 +0000743 if (!NewLine && State.NextToken->Parent->is(tok::semi) &&
Daniel Jasperfbde69e2012-12-21 14:37:20 +0000744 State.LineContainsContinuedForLoopSection)
745 return UINT_MAX;
Daniel Jasper2408a8c2013-01-11 11:37:55 +0000746 if (!NewLine && State.NextToken->Parent->is(tok::comma) &&
Daniel Jasper11cb81c2013-01-17 12:53:34 +0000747 State.NextToken->isNot(tok::comment) &&
Daniel Jasper2408a8c2013-01-11 11:37:55 +0000748 State.Stack.back().BreakAfterComma)
749 return UINT_MAX;
Daniel Jasper9278eb92013-01-16 14:59:02 +0000750 // Trying to insert a parameter on a new line if there are already more than
751 // one parameter on the current line is bin packing.
752 if (NewLine && State.NextToken->Parent->is(tok::comma) &&
753 State.Stack.back().HasMultiParameterLine && !Style.BinPackParameters)
754 return UINT_MAX;
Daniel Jasper04468962013-01-18 10:56:38 +0000755 if (!NewLine && (State.NextToken->Type == TT_CtorInitializerColon ||
756 (State.NextToken->Parent->ClosesTemplateDeclaration &&
757 State.Stack.size() == 1)))
Daniel Jaspera67a8f02013-01-16 10:41:46 +0000758 return UINT_MAX;
Daniel Jasperf7935112012-12-03 18:12:45 +0000759
Daniel Jasperaa1c9202012-12-05 14:57:28 +0000760 unsigned CurrentPenalty = 0;
Daniel Jasper20b09ef2013-01-28 09:35:24 +0000761 if (NewLine)
Daniel Jasper337816e2013-01-11 10:22:12 +0000762 CurrentPenalty += Parameters.PenaltyIndentLevel * State.Stack.size() +
Daniel Jaspercf330002013-01-29 15:03:01 +0000763 State.NextToken->SplitPenalty;
Daniel Jasperaa1c9202012-12-05 14:57:28 +0000764
Daniel Jasper6021c4a2012-12-04 14:54:30 +0000765 addTokenToState(NewLine, true, State);
Daniel Jasperf7935112012-12-03 18:12:45 +0000766
Daniel Jasper2df93312013-01-09 10:16:05 +0000767 // Exceeding column limit is bad, assign penalty.
768 if (State.Column > getColumnLimit()) {
769 unsigned ExcessCharacters = State.Column - getColumnLimit();
770 CurrentPenalty += Parameters.PenaltyExcessCharacter * ExcessCharacters;
771 }
Daniel Jasperf7935112012-12-03 18:12:45 +0000772
Daniel Jasperf7935112012-12-03 18:12:45 +0000773 if (StopAt <= CurrentPenalty)
774 return UINT_MAX;
775 StopAt -= CurrentPenalty;
Daniel Jasperf7935112012-12-03 18:12:45 +0000776 StateMap::iterator I = Memory.find(State);
Daniel Jasperaa1c9202012-12-05 14:57:28 +0000777 if (I != Memory.end()) {
778 // If this state has already been examined, we can safely return the
779 // previous result if we
780 // - have not hit the optimatization (and thus returned UINT_MAX) OR
781 // - are now computing for a smaller or equal StopAt.
782 unsigned SavedResult = I->second.first;
783 unsigned SavedStopAt = I->second.second;
Daniel Jasper5485d0c2012-12-17 14:34:14 +0000784 if (SavedResult != UINT_MAX)
785 return SavedResult + CurrentPenalty;
786 else if (StopAt <= SavedStopAt)
787 return UINT_MAX;
Daniel Jasperaa1c9202012-12-05 14:57:28 +0000788 }
Daniel Jasperf7935112012-12-03 18:12:45 +0000789
790 unsigned NoBreak = calcPenalty(State, false, StopAt);
791 unsigned WithBreak = calcPenalty(State, true, std::min(StopAt, NoBreak));
792 unsigned Result = std::min(NoBreak, WithBreak);
Daniel Jasper5485d0c2012-12-17 14:34:14 +0000793
794 // We have to store 'Result' without adding 'CurrentPenalty' as the latter
795 // can depend on 'NewLine'.
Daniel Jasperaa1c9202012-12-05 14:57:28 +0000796 Memory[State] = std::pair<unsigned, unsigned>(Result, StopAt);
Daniel Jasper5485d0c2012-12-17 14:34:14 +0000797
798 return Result == UINT_MAX ? UINT_MAX : Result + CurrentPenalty;
Daniel Jasperf7935112012-12-03 18:12:45 +0000799 }
800
Daniel Jasperf7935112012-12-03 18:12:45 +0000801 FormatStyle Style;
802 SourceManager &SourceMgr;
Daniel Jasperf1e4b7d2013-01-14 13:08:07 +0000803 const AnnotatedLine &Line;
Manuel Klimek0b689fd2013-01-10 18:45:26 +0000804 const unsigned FirstIndent;
Daniel Jasper7c85fde2013-01-08 14:56:18 +0000805 const AnnotatedToken &RootToken;
Daniel Jasperaa701fa2013-01-18 08:44:07 +0000806 WhitespaceManager &Whitespaces;
Daniel Jasperf7935112012-12-03 18:12:45 +0000807
Daniel Jasperaa1c9202012-12-05 14:57:28 +0000808 // A map from an indent state to a pair (Result, Used-StopAt).
Daniel Jasper337816e2013-01-11 10:22:12 +0000809 typedef std::map<LineState, std::pair<unsigned, unsigned> > StateMap;
Daniel Jasperaa1c9202012-12-05 14:57:28 +0000810 StateMap Memory;
811
Daniel Jasperf7935112012-12-03 18:12:45 +0000812 OptimizationParameters Parameters;
813};
814
815/// \brief Determines extra information about the tokens comprising an
816/// \c UnwrappedLine.
817class TokenAnnotator {
818public:
Daniel Jasperf1e4b7d2013-01-14 13:08:07 +0000819 TokenAnnotator(const FormatStyle &Style, SourceManager &SourceMgr, Lexer &Lex,
820 AnnotatedLine &Line)
Daniel Jasperbbc84152013-01-29 11:27:30 +0000821 : Style(Style), SourceMgr(SourceMgr), Lex(Lex), Line(Line) {
822 }
Daniel Jasperf7935112012-12-03 18:12:45 +0000823
824 /// \brief A parser that gathers additional information about tokens.
825 ///
826 /// The \c TokenAnnotator tries to matches parenthesis and square brakets and
827 /// store a parenthesis levels. It also tries to resolve matching "<" and ">"
828 /// into template parameter lists.
829 class AnnotatingParser {
830 public:
Daniel Jasper7c85fde2013-01-08 14:56:18 +0000831 AnnotatingParser(AnnotatedToken &RootToken)
Nico Webera7252d82013-01-12 06:18:40 +0000832 : CurrentToken(&RootToken), KeywordVirtualFound(false),
Daniel Jasperbbc84152013-01-29 11:27:30 +0000833 ColonIsObjCMethodExpr(false), ColonIsForRangeExpr(false) {
834 }
Daniel Jasperf7935112012-12-03 18:12:45 +0000835
Nico Weber250fe712013-01-18 02:43:57 +0000836 /// \brief A helper class to manage AnnotatingParser::ColonIsObjCMethodExpr.
837 struct ObjCSelectorRAII {
838 AnnotatingParser &P;
839 bool ColonWasObjCMethodExpr;
840
841 ObjCSelectorRAII(AnnotatingParser &P)
Daniel Jasperbbc84152013-01-29 11:27:30 +0000842 : P(P), ColonWasObjCMethodExpr(P.ColonIsObjCMethodExpr) {
843 }
Nico Weber250fe712013-01-18 02:43:57 +0000844
845 ~ObjCSelectorRAII() { P.ColonIsObjCMethodExpr = ColonWasObjCMethodExpr; }
846
847 void markStart(AnnotatedToken &Left) {
848 P.ColonIsObjCMethodExpr = true;
849 Left.Type = TT_ObjCMethodExpr;
850 }
851
852 void markEnd(AnnotatedToken &Right) { Right.Type = TT_ObjCMethodExpr; }
853 };
854
Daniel Jasper6021c4a2012-12-04 14:54:30 +0000855 bool parseAngle() {
Daniel Jasper9278eb92013-01-16 14:59:02 +0000856 if (CurrentToken == NULL)
857 return false;
858 AnnotatedToken *Left = CurrentToken->Parent;
Daniel Jasper7c85fde2013-01-08 14:56:18 +0000859 while (CurrentToken != NULL) {
860 if (CurrentToken->is(tok::greater)) {
Daniel Jasper9278eb92013-01-16 14:59:02 +0000861 Left->MatchingParen = CurrentToken;
862 CurrentToken->MatchingParen = Left;
Daniel Jasper7c85fde2013-01-08 14:56:18 +0000863 CurrentToken->Type = TT_TemplateCloser;
Daniel Jasperf7935112012-12-03 18:12:45 +0000864 next();
865 return true;
866 }
Daniel Jasper7c85fde2013-01-08 14:56:18 +0000867 if (CurrentToken->is(tok::r_paren) || CurrentToken->is(tok::r_square) ||
868 CurrentToken->is(tok::r_brace))
Daniel Jasperf7935112012-12-03 18:12:45 +0000869 return false;
Daniel Jasper7c85fde2013-01-08 14:56:18 +0000870 if (CurrentToken->is(tok::pipepipe) || CurrentToken->is(tok::ampamp) ||
871 CurrentToken->is(tok::question) || CurrentToken->is(tok::colon))
Daniel Jasperf7935112012-12-03 18:12:45 +0000872 return false;
Daniel Jasper7b5773e92013-01-28 07:35:34 +0000873 if (CurrentToken->is(tok::comma))
874 ++Left->ParameterCount;
Daniel Jasperc0880a92013-01-04 18:52:56 +0000875 if (!consumeToken())
876 return false;
Daniel Jasperf7935112012-12-03 18:12:45 +0000877 }
878 return false;
879 }
880
Nico Weber80a82762013-01-17 17:17:19 +0000881 bool parseParens(bool LookForDecls = false) {
Daniel Jasper9278eb92013-01-16 14:59:02 +0000882 if (CurrentToken == NULL)
883 return false;
Nico Weber250fe712013-01-18 02:43:57 +0000884 bool StartsObjCMethodExpr = false;
Daniel Jasper9278eb92013-01-16 14:59:02 +0000885 AnnotatedToken *Left = CurrentToken->Parent;
Nico Weber250fe712013-01-18 02:43:57 +0000886 if (CurrentToken->is(tok::caret)) {
887 // ^( starts a block.
Daniel Jasper9278eb92013-01-16 14:59:02 +0000888 Left->Type = TT_ObjCBlockLParen;
Nico Weber250fe712013-01-18 02:43:57 +0000889 } else if (AnnotatedToken *MaybeSel = Left->Parent) {
890 // @selector( starts a selector.
891 if (MaybeSel->isObjCAtKeyword(tok::objc_selector) && MaybeSel->Parent &&
892 MaybeSel->Parent->is(tok::at)) {
893 StartsObjCMethodExpr = true;
894 }
895 }
896
897 ObjCSelectorRAII objCSelector(*this);
898 if (StartsObjCMethodExpr)
899 objCSelector.markStart(*Left);
900
Daniel Jasper7c85fde2013-01-08 14:56:18 +0000901 while (CurrentToken != NULL) {
Nico Weber80a82762013-01-17 17:17:19 +0000902 // LookForDecls is set when "if (" has been seen. Check for
903 // 'identifier' '*' 'identifier' followed by not '=' -- this
904 // '*' has to be a binary operator but determineStarAmpUsage() will
905 // categorize it as an unary operator, so set the right type here.
906 if (LookForDecls && !CurrentToken->Children.empty()) {
907 AnnotatedToken &Prev = *CurrentToken->Parent;
908 AnnotatedToken &Next = CurrentToken->Children[0];
909 if (Prev.Parent->is(tok::identifier) &&
910 (Prev.is(tok::star) || Prev.is(tok::amp)) &&
911 CurrentToken->is(tok::identifier) && Next.isNot(tok::equal)) {
912 Prev.Type = TT_BinaryOperator;
913 LookForDecls = false;
914 }
915 }
916
Daniel Jasper7c85fde2013-01-08 14:56:18 +0000917 if (CurrentToken->is(tok::r_paren)) {
Daniel Jasper9278eb92013-01-16 14:59:02 +0000918 Left->MatchingParen = CurrentToken;
919 CurrentToken->MatchingParen = Left;
Nico Weber250fe712013-01-18 02:43:57 +0000920
921 if (StartsObjCMethodExpr)
922 objCSelector.markEnd(*CurrentToken);
923
Daniel Jasperf7935112012-12-03 18:12:45 +0000924 next();
925 return true;
926 }
Daniel Jasper7c85fde2013-01-08 14:56:18 +0000927 if (CurrentToken->is(tok::r_square) || CurrentToken->is(tok::r_brace))
Daniel Jasperf7935112012-12-03 18:12:45 +0000928 return false;
Daniel Jasper7b5773e92013-01-28 07:35:34 +0000929 if (CurrentToken->is(tok::comma))
930 ++Left->ParameterCount;
Daniel Jasperc0880a92013-01-04 18:52:56 +0000931 if (!consumeToken())
932 return false;
Daniel Jasperf7935112012-12-03 18:12:45 +0000933 }
934 return false;
935 }
936
Daniel Jasper6021c4a2012-12-04 14:54:30 +0000937 bool parseSquare() {
Nico Webera7252d82013-01-12 06:18:40 +0000938 if (!CurrentToken)
939 return false;
940
941 // A '[' could be an index subscript (after an indentifier or after
942 // ')' or ']'), or it could be the start of an Objective-C method
943 // expression.
Nico Webered272de2013-01-21 19:29:31 +0000944 AnnotatedToken *Left = CurrentToken->Parent;
Nico Webera7252d82013-01-12 06:18:40 +0000945 bool StartsObjCMethodExpr =
Nico Webered272de2013-01-21 19:29:31 +0000946 !Left->Parent || Left->Parent->is(tok::colon) ||
947 Left->Parent->is(tok::l_square) || Left->Parent->is(tok::l_paren) ||
948 Left->Parent->is(tok::kw_return) || Left->Parent->is(tok::kw_throw) ||
Daniel Jasperbbc84152013-01-29 11:27:30 +0000949 getBinOpPrecedence(Left->Parent->FormatTok.Tok.getKind(), true,
950 true) > prec::Unknown;
Nico Webera7252d82013-01-12 06:18:40 +0000951
Nico Weber250fe712013-01-18 02:43:57 +0000952 ObjCSelectorRAII objCSelector(*this);
953 if (StartsObjCMethodExpr)
Nico Webered272de2013-01-21 19:29:31 +0000954 objCSelector.markStart(*Left);
Nico Webera7252d82013-01-12 06:18:40 +0000955
Daniel Jasper7c85fde2013-01-08 14:56:18 +0000956 while (CurrentToken != NULL) {
957 if (CurrentToken->is(tok::r_square)) {
Daniel Jasper0b820602013-01-22 11:46:26 +0000958 if (!CurrentToken->Children.empty() &&
959 CurrentToken->Children[0].is(tok::l_paren)) {
960 // An ObjC method call can't be followed by an open parenthesis.
961 // FIXME: Do we incorrectly label ":" with this?
962 StartsObjCMethodExpr = false;
963 Left->Type = TT_Unknown;
Daniel Jasper38c11ce2013-01-29 11:21:01 +0000964 }
Nico Weber250fe712013-01-18 02:43:57 +0000965 if (StartsObjCMethodExpr)
966 objCSelector.markEnd(*CurrentToken);
Nico Weber767c8d32013-01-21 19:35:06 +0000967 Left->MatchingParen = CurrentToken;
968 CurrentToken->MatchingParen = Left;
Daniel Jasperf7935112012-12-03 18:12:45 +0000969 next();
970 return true;
971 }
Daniel Jasper7c85fde2013-01-08 14:56:18 +0000972 if (CurrentToken->is(tok::r_paren) || CurrentToken->is(tok::r_brace))
Daniel Jasperf7935112012-12-03 18:12:45 +0000973 return false;
Daniel Jasper7b5773e92013-01-28 07:35:34 +0000974 if (CurrentToken->is(tok::comma))
975 ++Left->ParameterCount;
Daniel Jasperc0880a92013-01-04 18:52:56 +0000976 if (!consumeToken())
977 return false;
Daniel Jasperf7935112012-12-03 18:12:45 +0000978 }
979 return false;
980 }
981
Daniel Jasper83a54d22013-01-10 09:26:47 +0000982 bool parseBrace() {
Daniel Jasper9278eb92013-01-16 14:59:02 +0000983 // Lines are fine to end with '{'.
984 if (CurrentToken == NULL)
985 return true;
986 AnnotatedToken *Left = CurrentToken->Parent;
Daniel Jasper83a54d22013-01-10 09:26:47 +0000987 while (CurrentToken != NULL) {
988 if (CurrentToken->is(tok::r_brace)) {
Daniel Jasper9278eb92013-01-16 14:59:02 +0000989 Left->MatchingParen = CurrentToken;
990 CurrentToken->MatchingParen = Left;
Daniel Jasper83a54d22013-01-10 09:26:47 +0000991 next();
992 return true;
993 }
994 if (CurrentToken->is(tok::r_paren) || CurrentToken->is(tok::r_square))
995 return false;
996 if (!consumeToken())
997 return false;
998 }
Daniel Jasper83a54d22013-01-10 09:26:47 +0000999 return true;
1000 }
1001
Daniel Jasper6021c4a2012-12-04 14:54:30 +00001002 bool parseConditional() {
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001003 while (CurrentToken != NULL) {
1004 if (CurrentToken->is(tok::colon)) {
1005 CurrentToken->Type = TT_ConditionalExpr;
Daniel Jasperf7935112012-12-03 18:12:45 +00001006 next();
1007 return true;
1008 }
Daniel Jasperc0880a92013-01-04 18:52:56 +00001009 if (!consumeToken())
1010 return false;
Daniel Jasperf7935112012-12-03 18:12:45 +00001011 }
1012 return false;
1013 }
1014
Daniel Jasperac5c1c22013-01-02 15:08:56 +00001015 bool parseTemplateDeclaration() {
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001016 if (CurrentToken != NULL && CurrentToken->is(tok::less)) {
1017 CurrentToken->Type = TT_TemplateOpener;
Daniel Jasperac5c1c22013-01-02 15:08:56 +00001018 next();
1019 if (!parseAngle())
1020 return false;
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001021 CurrentToken->Parent->ClosesTemplateDeclaration = true;
Daniel Jasperac5c1c22013-01-02 15:08:56 +00001022 return true;
1023 }
1024 return false;
1025 }
1026
Daniel Jasperc0880a92013-01-04 18:52:56 +00001027 bool consumeToken() {
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001028 AnnotatedToken *Tok = CurrentToken;
Daniel Jasperf7935112012-12-03 18:12:45 +00001029 next();
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001030 switch (Tok->FormatTok.Tok.getKind()) {
Nico Weber9efe2912013-01-10 23:11:41 +00001031 case tok::plus:
1032 case tok::minus:
1033 // At the start of the line, +/- specific ObjectiveC method
1034 // declarations.
1035 if (Tok->Parent == NULL)
1036 Tok->Type = TT_ObjCMethodSpecifier;
1037 break;
Nico Webera7252d82013-01-12 06:18:40 +00001038 case tok::colon:
1039 // Colons from ?: are handled in parseConditional().
Daniel Jasper8c5fba92013-01-16 16:23:19 +00001040 if (Tok->Parent->is(tok::r_paren))
1041 Tok->Type = TT_CtorInitializerColon;
Daniel Jasper0b41cbb2013-01-28 13:21:16 +00001042 else if (ColonIsObjCMethodExpr)
Nico Webera7252d82013-01-12 06:18:40 +00001043 Tok->Type = TT_ObjCMethodExpr;
Daniel Jasper0b41cbb2013-01-28 13:21:16 +00001044 else if (ColonIsForRangeExpr)
1045 Tok->Type = TT_RangeBasedForLoopColon;
Nico Webera7252d82013-01-12 06:18:40 +00001046 break;
Nico Weber80a82762013-01-17 17:17:19 +00001047 case tok::kw_if:
1048 case tok::kw_while:
Manuel Klimekd33516e2013-01-23 10:09:28 +00001049 if (CurrentToken != NULL && CurrentToken->is(tok::l_paren)) {
Nico Weber80a82762013-01-17 17:17:19 +00001050 next();
Daniel Jasperbbc84152013-01-29 11:27:30 +00001051 if (!parseParens(/*LookForDecls=*/ true))
Nico Weber80a82762013-01-17 17:17:19 +00001052 return false;
1053 }
1054 break;
Daniel Jasper0b41cbb2013-01-28 13:21:16 +00001055 case tok::kw_for:
1056 ColonIsForRangeExpr = true;
1057 next();
1058 if (!parseParens())
1059 return false;
1060 break;
Nico Webera5510af2013-01-18 05:50:57 +00001061 case tok::l_paren:
Daniel Jasperc0880a92013-01-04 18:52:56 +00001062 if (!parseParens())
1063 return false;
Nico Webera5510af2013-01-18 05:50:57 +00001064 break;
Daniel Jasperf7935112012-12-03 18:12:45 +00001065 case tok::l_square:
Daniel Jasperc0880a92013-01-04 18:52:56 +00001066 if (!parseSquare())
1067 return false;
Daniel Jasperf7935112012-12-03 18:12:45 +00001068 break;
Daniel Jasper83a54d22013-01-10 09:26:47 +00001069 case tok::l_brace:
1070 if (!parseBrace())
1071 return false;
1072 break;
Daniel Jasperf7935112012-12-03 18:12:45 +00001073 case tok::less:
Daniel Jasper6021c4a2012-12-04 14:54:30 +00001074 if (parseAngle())
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001075 Tok->Type = TT_TemplateOpener;
Daniel Jasperf7935112012-12-03 18:12:45 +00001076 else {
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001077 Tok->Type = TT_BinaryOperator;
1078 CurrentToken = Tok;
1079 next();
Daniel Jasperf7935112012-12-03 18:12:45 +00001080 }
1081 break;
Daniel Jasperc0880a92013-01-04 18:52:56 +00001082 case tok::r_paren:
1083 case tok::r_square:
1084 return false;
Daniel Jasper83a54d22013-01-10 09:26:47 +00001085 case tok::r_brace:
1086 // Lines can start with '}'.
1087 if (Tok->Parent != NULL)
1088 return false;
1089 break;
Daniel Jasperf7935112012-12-03 18:12:45 +00001090 case tok::greater:
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001091 Tok->Type = TT_BinaryOperator;
Daniel Jasperf7935112012-12-03 18:12:45 +00001092 break;
1093 case tok::kw_operator:
Manuel Klimekd33516e2013-01-23 10:09:28 +00001094 if (CurrentToken != NULL && CurrentToken->is(tok::l_paren)) {
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001095 CurrentToken->Type = TT_OverloadedOperator;
Daniel Jasper537a2962012-12-24 10:56:04 +00001096 next();
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001097 if (CurrentToken != NULL && CurrentToken->is(tok::r_paren)) {
1098 CurrentToken->Type = TT_OverloadedOperator;
Daniel Jasper537a2962012-12-24 10:56:04 +00001099 next();
1100 }
1101 } else {
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001102 while (CurrentToken != NULL && CurrentToken->isNot(tok::l_paren)) {
1103 CurrentToken->Type = TT_OverloadedOperator;
Daniel Jasper537a2962012-12-24 10:56:04 +00001104 next();
1105 }
1106 }
Daniel Jasperf7935112012-12-03 18:12:45 +00001107 break;
1108 case tok::question:
Daniel Jasper6021c4a2012-12-04 14:54:30 +00001109 parseConditional();
Daniel Jasperf7935112012-12-03 18:12:45 +00001110 break;
Daniel Jasperac5c1c22013-01-02 15:08:56 +00001111 case tok::kw_template:
1112 parseTemplateDeclaration();
1113 break;
Daniel Jasperf7935112012-12-03 18:12:45 +00001114 default:
1115 break;
1116 }
Daniel Jasperc0880a92013-01-04 18:52:56 +00001117 return true;
Daniel Jasperf7935112012-12-03 18:12:45 +00001118 }
1119
Daniel Jasper050948a52012-12-21 17:58:39 +00001120 void parseIncludeDirective() {
Manuel Klimek99c7baa2013-01-15 15:50:27 +00001121 next();
1122 if (CurrentToken != NULL && CurrentToken->is(tok::less)) {
1123 next();
1124 while (CurrentToken != NULL) {
Daniel Jasper997b08c2013-01-18 09:19:33 +00001125 if (CurrentToken->isNot(tok::comment) ||
1126 !CurrentToken->Children.empty())
1127 CurrentToken->Type = TT_ImplicitStringLiteral;
Manuel Klimek99c7baa2013-01-15 15:50:27 +00001128 next();
1129 }
1130 } else {
1131 while (CurrentToken != NULL) {
1132 next();
1133 }
1134 }
1135 }
1136
1137 void parseWarningOrError() {
1138 next();
1139 // We still want to format the whitespace left of the first token of the
1140 // warning or error.
1141 next();
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001142 while (CurrentToken != NULL) {
Manuel Klimek99c7baa2013-01-15 15:50:27 +00001143 CurrentToken->Type = TT_ImplicitStringLiteral;
Daniel Jasper050948a52012-12-21 17:58:39 +00001144 next();
1145 }
1146 }
1147
1148 void parsePreprocessorDirective() {
1149 next();
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001150 if (CurrentToken == NULL)
Daniel Jasper050948a52012-12-21 17:58:39 +00001151 return;
Manuel Klimek52d0fd82013-01-05 22:56:06 +00001152 // Hashes in the middle of a line can lead to any strange token
1153 // sequence.
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001154 if (CurrentToken->FormatTok.Tok.getIdentifierInfo() == NULL)
Manuel Klimek52d0fd82013-01-05 22:56:06 +00001155 return;
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001156 switch (
1157 CurrentToken->FormatTok.Tok.getIdentifierInfo()->getPPKeywordID()) {
Daniel Jasper050948a52012-12-21 17:58:39 +00001158 case tok::pp_include:
Nico Weber8f83ee42012-12-21 18:21:56 +00001159 case tok::pp_import:
Daniel Jasper050948a52012-12-21 17:58:39 +00001160 parseIncludeDirective();
1161 break;
Manuel Klimek99c7baa2013-01-15 15:50:27 +00001162 case tok::pp_error:
1163 case tok::pp_warning:
1164 parseWarningOrError();
1165 break;
Daniel Jasper050948a52012-12-21 17:58:39 +00001166 default:
1167 break;
1168 }
1169 }
1170
Daniel Jasperda16db32013-01-07 10:48:50 +00001171 LineType parseLine() {
Daniel Jasper50e7ab72013-01-22 14:28:24 +00001172 int PeriodsAndArrows = 0;
Daniel Jasper20b09ef2013-01-28 09:35:24 +00001173 bool CanBeBuilderTypeStmt = true;
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001174 if (CurrentToken->is(tok::hash)) {
Daniel Jasper050948a52012-12-21 17:58:39 +00001175 parsePreprocessorDirective();
Daniel Jasperda16db32013-01-07 10:48:50 +00001176 return LT_PreprocessorDirective;
Daniel Jasper050948a52012-12-21 17:58:39 +00001177 }
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001178 while (CurrentToken != NULL) {
1179 if (CurrentToken->is(tok::kw_virtual))
Daniel Jasperda16db32013-01-07 10:48:50 +00001180 KeywordVirtualFound = true;
Daniel Jasper50e7ab72013-01-22 14:28:24 +00001181 if (CurrentToken->is(tok::period) || CurrentToken->is(tok::arrow))
1182 ++PeriodsAndArrows;
Daniel Jasper20b09ef2013-01-28 09:35:24 +00001183 if (getPrecedence(*CurrentToken) > prec::Assignment &&
1184 CurrentToken->isNot(tok::less) && CurrentToken->isNot(tok::greater))
1185 CanBeBuilderTypeStmt = false;
Daniel Jasperc0880a92013-01-04 18:52:56 +00001186 if (!consumeToken())
Daniel Jasperda16db32013-01-07 10:48:50 +00001187 return LT_Invalid;
Daniel Jasperf7935112012-12-03 18:12:45 +00001188 }
Daniel Jasperda16db32013-01-07 10:48:50 +00001189 if (KeywordVirtualFound)
1190 return LT_VirtualFunctionDecl;
Daniel Jasper50e7ab72013-01-22 14:28:24 +00001191
1192 // Assume a builder-type call if there are 2 or more "." and "->".
Daniel Jasper20b09ef2013-01-28 09:35:24 +00001193 if (PeriodsAndArrows >= 2 && CanBeBuilderTypeStmt)
Daniel Jasper50e7ab72013-01-22 14:28:24 +00001194 return LT_BuilderTypeCall;
1195
Daniel Jasperda16db32013-01-07 10:48:50 +00001196 return LT_Other;
Daniel Jasperf7935112012-12-03 18:12:45 +00001197 }
1198
1199 void next() {
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001200 if (CurrentToken != NULL && !CurrentToken->Children.empty())
1201 CurrentToken = &CurrentToken->Children[0];
1202 else
1203 CurrentToken = NULL;
Daniel Jasperf7935112012-12-03 18:12:45 +00001204 }
1205
1206 private:
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001207 AnnotatedToken *CurrentToken;
Daniel Jasperda16db32013-01-07 10:48:50 +00001208 bool KeywordVirtualFound;
Nico Webera7252d82013-01-12 06:18:40 +00001209 bool ColonIsObjCMethodExpr;
Daniel Jasper0b41cbb2013-01-28 13:21:16 +00001210 bool ColonIsForRangeExpr;
Daniel Jasperf7935112012-12-03 18:12:45 +00001211 };
1212
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001213 void calculateExtraInformation(AnnotatedToken &Current) {
1214 Current.SpaceRequiredBefore = spaceRequiredBefore(Current);
1215
Manuel Klimek52b15152013-01-09 15:25:02 +00001216 if (Current.FormatTok.MustBreakBefore) {
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001217 Current.MustBreakBefore = true;
1218 } else {
Daniel Jasper942ee722013-01-13 16:10:20 +00001219 if (Current.Type == TT_LineComment) {
1220 Current.MustBreakBefore = Current.FormatTok.NewlinesBefore > 0;
Daniel Jasper11cb81c2013-01-17 12:53:34 +00001221 } else if ((Current.Parent->is(tok::comment) &&
1222 Current.FormatTok.NewlinesBefore > 0) ||
Daniel Jasper942ee722013-01-13 16:10:20 +00001223 (Current.is(tok::string_literal) &&
1224 Current.Parent->is(tok::string_literal))) {
Manuel Klimek52b15152013-01-09 15:25:02 +00001225 Current.MustBreakBefore = true;
Manuel Klimek52b15152013-01-09 15:25:02 +00001226 } else {
1227 Current.MustBreakBefore = false;
1228 }
Daniel Jasperf7935112012-12-03 18:12:45 +00001229 }
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001230 Current.CanBreakBefore = Current.MustBreakBefore || canBreakBefore(Current);
Daniel Jaspera67a8f02013-01-16 10:41:46 +00001231 if (Current.MustBreakBefore)
1232 Current.TotalLength = Current.Parent->TotalLength + Style.ColumnLimit;
1233 else
Daniel Jasperbbc84152013-01-29 11:27:30 +00001234 Current.TotalLength =
1235 Current.Parent->TotalLength + Current.FormatTok.TokenLength +
1236 (Current.SpaceRequiredBefore ? 1 : 0);
Daniel Jaspercf330002013-01-29 15:03:01 +00001237 if (Current.CanBreakBefore)
1238 Current.SplitPenalty = splitPenalty(Current);
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001239 if (!Current.Children.empty())
1240 calculateExtraInformation(Current.Children[0]);
1241 }
1242
Daniel Jasperf1e4b7d2013-01-14 13:08:07 +00001243 void annotate() {
Daniel Jasperf1e4b7d2013-01-14 13:08:07 +00001244 AnnotatingParser Parser(Line.First);
1245 Line.Type = Parser.parseLine();
1246 if (Line.Type == LT_Invalid)
1247 return;
Daniel Jasperf7935112012-12-03 18:12:45 +00001248
Daniel Jasperd2639ef2013-01-28 15:16:31 +00001249 bool LookForFunctionName = Line.MustBeDeclaration;
1250 determineTokenTypes(Line.First, /*IsExpression=*/ false,
1251 LookForFunctionName);
Daniel Jasperda16db32013-01-07 10:48:50 +00001252
Daniel Jasperf1e4b7d2013-01-14 13:08:07 +00001253 if (Line.First.Type == TT_ObjCMethodSpecifier)
1254 Line.Type = LT_ObjCMethodDecl;
1255 else if (Line.First.Type == TT_ObjCDecl)
1256 Line.Type = LT_ObjCDecl;
1257 else if (Line.First.Type == TT_ObjCProperty)
1258 Line.Type = LT_ObjCProperty;
Daniel Jasperda16db32013-01-07 10:48:50 +00001259
Daniel Jasperf1e4b7d2013-01-14 13:08:07 +00001260 Line.First.SpaceRequiredBefore = true;
1261 Line.First.MustBreakBefore = Line.First.FormatTok.MustBreakBefore;
1262 Line.First.CanBreakBefore = Line.First.MustBreakBefore;
Daniel Jasperf7935112012-12-03 18:12:45 +00001263
Daniel Jaspera67a8f02013-01-16 10:41:46 +00001264 Line.First.TotalLength = Line.First.FormatTok.TokenLength;
Daniel Jasperf1e4b7d2013-01-14 13:08:07 +00001265 if (!Line.First.Children.empty())
1266 calculateExtraInformation(Line.First.Children[0]);
Daniel Jasperf7935112012-12-03 18:12:45 +00001267 }
1268
1269private:
Daniel Jaspercf330002013-01-29 15:03:01 +00001270 /// \brief Calculate the penalty for splitting before \c Tok.
1271 unsigned splitPenalty(const AnnotatedToken &Tok) {
1272 const AnnotatedToken &Left = *Tok.Parent;
1273 const AnnotatedToken &Right = Tok;
1274
1275 if (Left.is(tok::l_brace) && Right.isNot(tok::l_brace))
1276 return 50;
1277 if (Left.is(tok::equal) && Right.is(tok::l_brace))
1278 return 150;
1279 if (Left.is(tok::coloncolon))
1280 return 500;
1281
1282 if (Left.Type == TT_RangeBasedForLoopColon)
1283 return 5;
1284
1285 if (Right.is(tok::arrow) || Right.is(tok::period)) {
1286 if (Left.is(tok::r_paren) && Line.Type == LT_BuilderTypeCall)
1287 return 5; // Should be smaller than breaking at a nested comma.
1288 return 150;
1289 }
1290
1291 // In for-loops, prefer breaking at ',' and ';'.
1292 if (Line.First.is(tok::kw_for) &&
1293 (Left.isNot(tok::comma) && Left.isNot(tok::semi)))
1294 return 20;
1295
1296 if (Left.is(tok::semi) || Left.is(tok::comma))
1297 return 0;
1298
1299 // In Objective-C method expressions, prefer breaking before "param:" over
1300 // breaking after it.
1301 if (isObjCSelectorName(Right))
1302 return 0;
1303 if (Right.is(tok::colon) && Right.Type == TT_ObjCMethodExpr)
1304 return 20;
1305
1306 if (Left.is(tok::l_paren))
1307 return 20;
1308 // FIXME: The penalty for a trailing "<" or "[" being higher than the
1309 // penalty for a trainling "(" is a temporary workaround until we can
1310 // properly avoid breaking in array subscripts or template parameters.
1311 if (Left.is(tok::l_square) || Left.Type == TT_TemplateOpener)
1312 return 50;
1313
1314 if (Left.Type == TT_ConditionalExpr)
1315 return prec::Assignment;
1316 prec::Level Level = getPrecedence(Left);
1317
1318 if (Level != prec::Unknown)
1319 return Level;
1320
1321 return 3;
1322 }
1323
Daniel Jasperd2639ef2013-01-28 15:16:31 +00001324 void determineTokenTypes(AnnotatedToken &Current, bool IsExpression,
1325 bool LookForFunctionName) {
Daniel Jasper5b49f472013-01-23 12:10:53 +00001326 if (getPrecedence(Current) == prec::Assignment) {
1327 IsExpression = true;
1328 AnnotatedToken *Previous = Current.Parent;
1329 while (Previous != NULL) {
Manuel Klimekc1237a82013-01-23 14:08:21 +00001330 if (Previous->Type == TT_BinaryOperator &&
1331 (Previous->is(tok::star) || Previous->is(tok::amp))) {
Daniel Jasper5b49f472013-01-23 12:10:53 +00001332 Previous->Type = TT_PointerOrReference;
Manuel Klimekc1237a82013-01-23 14:08:21 +00001333 }
Daniel Jasper5b49f472013-01-23 12:10:53 +00001334 Previous = Previous->Parent;
1335 }
1336 }
1337 if (Current.is(tok::kw_return) || Current.is(tok::kw_throw) ||
Daniel Jasper420d7d32013-01-23 12:58:14 +00001338 (Current.is(tok::l_paren) && !Line.MustBeDeclaration &&
1339 (Current.Parent == NULL || Current.Parent->isNot(tok::kw_for))))
Daniel Jasper5b49f472013-01-23 12:10:53 +00001340 IsExpression = true;
Daniel Jasperf7935112012-12-03 18:12:45 +00001341
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001342 if (Current.Type == TT_Unknown) {
Daniel Jasperd2639ef2013-01-28 15:16:31 +00001343 if (LookForFunctionName && Current.is(tok::l_paren)) {
1344 findFunctionName(&Current);
1345 LookForFunctionName = false;
1346 } else if (Current.is(tok::star) || Current.is(tok::amp)) {
Daniel Jasper5b49f472013-01-23 12:10:53 +00001347 Current.Type = determineStarAmpUsage(Current, IsExpression);
Daniel Jasperfb3f2482013-01-09 08:36:49 +00001348 } else if (Current.is(tok::minus) || Current.is(tok::plus) ||
1349 Current.is(tok::caret)) {
1350 Current.Type = determinePlusMinusCaretUsage(Current);
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001351 } else if (Current.is(tok::minusminus) || Current.is(tok::plusplus)) {
1352 Current.Type = determineIncrementUsage(Current);
1353 } else if (Current.is(tok::exclaim)) {
1354 Current.Type = TT_UnaryOperator;
1355 } else if (isBinaryOperator(Current)) {
1356 Current.Type = TT_BinaryOperator;
1357 } else if (Current.is(tok::comment)) {
1358 std::string Data(Lexer::getSpelling(Current.FormatTok.Tok, SourceMgr,
1359 Lex.getLangOpts()));
Manuel Klimekc74d2922013-01-07 08:54:53 +00001360 if (StringRef(Data).startswith("//"))
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001361 Current.Type = TT_LineComment;
Daniel Jasperf7935112012-12-03 18:12:45 +00001362 else
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001363 Current.Type = TT_BlockComment;
Daniel Jasper7194e182013-01-10 11:14:08 +00001364 } else if (Current.is(tok::r_paren) &&
1365 (Current.Parent->Type == TT_PointerOrReference ||
Daniel Jasperef906a92013-01-13 08:01:36 +00001366 Current.Parent->Type == TT_TemplateCloser) &&
1367 (Current.Children.empty() ||
1368 (Current.Children[0].isNot(tok::equal) &&
1369 Current.Children[0].isNot(tok::semi) &&
1370 Current.Children[0].isNot(tok::l_brace)))) {
Daniel Jasper7194e182013-01-10 11:14:08 +00001371 // FIXME: We need to get smarter and understand more cases of casts.
1372 Current.Type = TT_CastRParen;
Nico Weber2bb00742013-01-10 19:19:14 +00001373 } else if (Current.is(tok::at) && Current.Children.size()) {
1374 switch (Current.Children[0].FormatTok.Tok.getObjCKeywordID()) {
1375 case tok::objc_interface:
1376 case tok::objc_implementation:
1377 case tok::objc_protocol:
1378 Current.Type = TT_ObjCDecl;
Nico Webera2a84952013-01-10 21:30:42 +00001379 break;
1380 case tok::objc_property:
1381 Current.Type = TT_ObjCProperty;
1382 break;
Nico Weber2bb00742013-01-10 19:19:14 +00001383 default:
1384 break;
1385 }
Daniel Jasperf7935112012-12-03 18:12:45 +00001386 }
1387 }
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001388
1389 if (!Current.Children.empty())
Daniel Jasperd2639ef2013-01-28 15:16:31 +00001390 determineTokenTypes(Current.Children[0], IsExpression,
1391 LookForFunctionName);
1392 }
1393
1394 /// \brief Starting from \p Current, this searches backwards for an
1395 /// identifier which could be the start of a function name and marks it.
1396 void findFunctionName(AnnotatedToken *Current) {
1397 AnnotatedToken *Parent = Current->Parent;
1398 while (Parent != NULL && Parent->Parent != NULL) {
1399 if (Parent->is(tok::identifier) &&
1400 (Parent->Parent->is(tok::identifier) ||
1401 Parent->Parent->Type == TT_PointerOrReference ||
1402 Parent->Parent->Type == TT_TemplateCloser)) {
1403 Parent->Type = TT_StartOfName;
1404 break;
1405 }
1406 Parent = Parent->Parent;
1407 }
Daniel Jasperf7935112012-12-03 18:12:45 +00001408 }
1409
Daniel Jasper71945272013-01-15 14:27:39 +00001410 /// \brief Returns the previous token ignoring comments.
1411 const AnnotatedToken *getPreviousToken(const AnnotatedToken &Tok) {
1412 const AnnotatedToken *PrevToken = Tok.Parent;
1413 while (PrevToken != NULL && PrevToken->is(tok::comment))
1414 PrevToken = PrevToken->Parent;
1415 return PrevToken;
1416 }
1417
1418 /// \brief Returns the next token ignoring comments.
1419 const AnnotatedToken *getNextToken(const AnnotatedToken &Tok) {
1420 if (Tok.Children.empty())
1421 return NULL;
1422 const AnnotatedToken *NextToken = &Tok.Children[0];
1423 while (NextToken->is(tok::comment)) {
1424 if (NextToken->Children.empty())
1425 return NULL;
1426 NextToken = &NextToken->Children[0];
1427 }
1428 return NextToken;
1429 }
1430
1431 /// \brief Return the type of the given token assuming it is * or &.
Daniel Jasperbbc84152013-01-29 11:27:30 +00001432 TokenType
1433 determineStarAmpUsage(const AnnotatedToken &Tok, bool IsExpression) {
Daniel Jasper71945272013-01-15 14:27:39 +00001434 const AnnotatedToken *PrevToken = getPreviousToken(Tok);
1435 if (PrevToken == NULL)
Daniel Jasperda16db32013-01-07 10:48:50 +00001436 return TT_UnaryOperator;
Daniel Jasper71945272013-01-15 14:27:39 +00001437
1438 const AnnotatedToken *NextToken = getNextToken(Tok);
1439 if (NextToken == NULL)
Daniel Jasperda16db32013-01-07 10:48:50 +00001440 return TT_Unknown;
Daniel Jasperf7935112012-12-03 18:12:45 +00001441
Daniel Jasper0b820602013-01-22 11:46:26 +00001442 if (NextToken->is(tok::l_square) && NextToken->Type != TT_ObjCMethodExpr)
1443 return TT_PointerOrReference;
1444
Daniel Jasper71945272013-01-15 14:27:39 +00001445 if (PrevToken->is(tok::l_paren) || PrevToken->is(tok::l_square) ||
1446 PrevToken->is(tok::l_brace) || PrevToken->is(tok::comma) ||
1447 PrevToken->is(tok::kw_return) || PrevToken->is(tok::colon) ||
1448 PrevToken->Type == TT_BinaryOperator ||
Daniel Jaspera1dc93a2013-01-16 16:04:06 +00001449 PrevToken->Type == TT_UnaryOperator || PrevToken->Type == TT_CastRParen)
Daniel Jasperda16db32013-01-07 10:48:50 +00001450 return TT_UnaryOperator;
Daniel Jasperf7935112012-12-03 18:12:45 +00001451
Daniel Jasper71945272013-01-15 14:27:39 +00001452 if (PrevToken->FormatTok.Tok.isLiteral() || PrevToken->is(tok::r_paren) ||
1453 PrevToken->is(tok::r_square) || NextToken->FormatTok.Tok.isLiteral() ||
1454 NextToken->is(tok::plus) || NextToken->is(tok::minus) ||
1455 NextToken->is(tok::plusplus) || NextToken->is(tok::minusminus) ||
1456 NextToken->is(tok::tilde) || NextToken->is(tok::exclaim) ||
1457 NextToken->is(tok::l_paren) || NextToken->is(tok::l_square) ||
1458 NextToken->is(tok::kw_alignof) || NextToken->is(tok::kw_sizeof))
Daniel Jasperda16db32013-01-07 10:48:50 +00001459 return TT_BinaryOperator;
Daniel Jasperf7935112012-12-03 18:12:45 +00001460
Daniel Jasper71945272013-01-15 14:27:39 +00001461 if (NextToken->is(tok::comma) || NextToken->is(tok::r_paren) ||
1462 NextToken->is(tok::greater))
Daniel Jasperda16db32013-01-07 10:48:50 +00001463 return TT_PointerOrReference;
Daniel Jasper542de162013-01-02 15:46:59 +00001464
Daniel Jasper426702d2012-12-05 07:51:39 +00001465 // It is very unlikely that we are going to find a pointer or reference type
1466 // definition on the RHS of an assignment.
Daniel Jasper5b49f472013-01-23 12:10:53 +00001467 if (IsExpression)
Daniel Jasperda16db32013-01-07 10:48:50 +00001468 return TT_BinaryOperator;
Daniel Jasper426702d2012-12-05 07:51:39 +00001469
Daniel Jasperda16db32013-01-07 10:48:50 +00001470 return TT_PointerOrReference;
Daniel Jasperf7935112012-12-03 18:12:45 +00001471 }
1472
Daniel Jasperfb3f2482013-01-09 08:36:49 +00001473 TokenType determinePlusMinusCaretUsage(const AnnotatedToken &Tok) {
Daniel Jasper71945272013-01-15 14:27:39 +00001474 const AnnotatedToken *PrevToken = getPreviousToken(Tok);
1475 if (PrevToken == NULL)
1476 return TT_UnaryOperator;
1477
Daniel Jasper8dd40472012-12-21 09:41:31 +00001478 // Use heuristics to recognize unary operators.
Daniel Jasper71945272013-01-15 14:27:39 +00001479 if (PrevToken->is(tok::equal) || PrevToken->is(tok::l_paren) ||
1480 PrevToken->is(tok::comma) || PrevToken->is(tok::l_square) ||
1481 PrevToken->is(tok::question) || PrevToken->is(tok::colon) ||
1482 PrevToken->is(tok::kw_return) || PrevToken->is(tok::kw_case) ||
1483 PrevToken->is(tok::at) || PrevToken->is(tok::l_brace))
Daniel Jasperda16db32013-01-07 10:48:50 +00001484 return TT_UnaryOperator;
Daniel Jasper8dd40472012-12-21 09:41:31 +00001485
1486 // There can't be to consecutive binary operators.
Daniel Jasper71945272013-01-15 14:27:39 +00001487 if (PrevToken->Type == TT_BinaryOperator)
Daniel Jasperda16db32013-01-07 10:48:50 +00001488 return TT_UnaryOperator;
Daniel Jasper8dd40472012-12-21 09:41:31 +00001489
1490 // Fall back to marking the token as binary operator.
Daniel Jasperda16db32013-01-07 10:48:50 +00001491 return TT_BinaryOperator;
Daniel Jasper8dd40472012-12-21 09:41:31 +00001492 }
1493
1494 /// \brief Determine whether ++/-- are pre- or post-increments/-decrements.
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001495 TokenType determineIncrementUsage(const AnnotatedToken &Tok) {
Daniel Jasper71945272013-01-15 14:27:39 +00001496 const AnnotatedToken *PrevToken = getPreviousToken(Tok);
1497 if (PrevToken == NULL)
Daniel Jasper13f23e12013-01-14 12:18:19 +00001498 return TT_UnaryOperator;
Daniel Jasper71945272013-01-15 14:27:39 +00001499 if (PrevToken->is(tok::r_paren) || PrevToken->is(tok::r_square) ||
1500 PrevToken->is(tok::identifier))
Daniel Jasperda16db32013-01-07 10:48:50 +00001501 return TT_TrailingUnaryOperator;
Daniel Jasper8dd40472012-12-21 09:41:31 +00001502
Daniel Jasperda16db32013-01-07 10:48:50 +00001503 return TT_UnaryOperator;
Daniel Jasperf7935112012-12-03 18:12:45 +00001504 }
1505
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001506 bool spaceRequiredBetween(const AnnotatedToken &Left,
1507 const AnnotatedToken &Right) {
Daniel Jasper4f397152013-01-08 16:17:54 +00001508 if (Right.is(tok::hashhash))
1509 return Left.is(tok::hash);
1510 if (Left.is(tok::hashhash) || Left.is(tok::hash))
1511 return Right.is(tok::hash);
Daniel Jaspera4396862012-12-10 18:59:13 +00001512 if (Right.is(tok::r_paren) || Right.is(tok::semi) || Right.is(tok::comma))
1513 return false;
Nico Webera6087752013-01-10 20:12:55 +00001514 if (Right.is(tok::less) &&
1515 (Left.is(tok::kw_template) ||
Daniel Jasperf1e4b7d2013-01-14 13:08:07 +00001516 (Line.Type == LT_ObjCDecl && Style.ObjCSpaceBeforeProtocolList)))
Daniel Jasperf7935112012-12-03 18:12:45 +00001517 return true;
1518 if (Left.is(tok::arrow) || Right.is(tok::arrow))
1519 return false;
1520 if (Left.is(tok::exclaim) || Left.is(tok::tilde))
1521 return false;
Nico Weber77aa2502013-01-08 19:40:21 +00001522 if (Left.is(tok::at) &&
1523 (Right.is(tok::identifier) || Right.is(tok::string_literal) ||
1524 Right.is(tok::char_constant) || Right.is(tok::numeric_constant) ||
Daniel Jasperc1fa2812013-01-10 13:08:12 +00001525 Right.is(tok::l_paren) || Right.is(tok::l_brace) ||
1526 Right.is(tok::kw_true) || Right.is(tok::kw_false)))
Fariborz Jahanian68a542a2012-12-20 19:54:13 +00001527 return false;
Daniel Jasper736c14f2013-01-16 07:19:28 +00001528 if (Left.is(tok::coloncolon))
1529 return false;
1530 if (Right.is(tok::coloncolon))
1531 return Left.isNot(tok::identifier) && Left.isNot(tok::greater);
Daniel Jasperf7935112012-12-03 18:12:45 +00001532 if (Left.is(tok::less) || Right.is(tok::greater) || Right.is(tok::less))
1533 return false;
Daniel Jasper27234032012-12-07 09:52:15 +00001534 if (Right.is(tok::amp) || Right.is(tok::star))
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001535 return Left.FormatTok.Tok.isLiteral() ||
Daniel Jasper8fbd9682012-12-24 16:51:15 +00001536 (Left.isNot(tok::star) && Left.isNot(tok::amp) &&
1537 !Style.PointerAndReferenceBindToType);
Daniel Jasperf7935112012-12-03 18:12:45 +00001538 if (Left.is(tok::amp) || Left.is(tok::star))
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001539 return Right.FormatTok.Tok.isLiteral() ||
1540 Style.PointerAndReferenceBindToType;
Daniel Jasperf7935112012-12-03 18:12:45 +00001541 if (Right.is(tok::star) && Left.is(tok::l_paren))
1542 return false;
Nico Webera7252d82013-01-12 06:18:40 +00001543 if (Left.is(tok::l_square) || Right.is(tok::r_square))
1544 return false;
1545 if (Right.is(tok::l_square) && Right.Type != TT_ObjCMethodExpr)
Daniel Jasperf7935112012-12-03 18:12:45 +00001546 return false;
Daniel Jasperf7935112012-12-03 18:12:45 +00001547 if (Left.is(tok::period) || Right.is(tok::period))
1548 return false;
Nico Webera7252d82013-01-12 06:18:40 +00001549 if (Left.is(tok::colon))
1550 return Left.Type != TT_ObjCMethodExpr;
1551 if (Right.is(tok::colon))
1552 return Right.Type != TT_ObjCMethodExpr;
Daniel Jasperf7935112012-12-03 18:12:45 +00001553 if (Left.is(tok::l_paren))
1554 return false;
Daniel Jasperf7935112012-12-03 18:12:45 +00001555 if (Right.is(tok::l_paren)) {
Daniel Jasperf1e4b7d2013-01-14 13:08:07 +00001556 return Line.Type == LT_ObjCDecl || Left.is(tok::kw_if) ||
Nico Weber2bb00742013-01-10 19:19:14 +00001557 Left.is(tok::kw_for) || Left.is(tok::kw_while) ||
Daniel Jasperfd8c4b12013-01-11 14:23:32 +00001558 Left.is(tok::kw_switch) || Left.is(tok::kw_return) ||
Daniel Jasperd6a947f2013-01-11 16:09:04 +00001559 Left.is(tok::kw_catch) || Left.is(tok::kw_new) ||
1560 Left.is(tok::kw_delete);
Daniel Jasperf7935112012-12-03 18:12:45 +00001561 }
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001562 if (Left.is(tok::at) &&
1563 Right.FormatTok.Tok.getObjCKeywordID() != tok::objc_not_keyword)
Nico Webere89c42f2013-01-07 16:14:28 +00001564 return false;
Manuel Klimeke7d10a12013-01-10 13:24:24 +00001565 if (Left.is(tok::l_brace) && Right.is(tok::r_brace))
1566 return false;
Daniel Jasperf7935112012-12-03 18:12:45 +00001567 return true;
1568 }
1569
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001570 bool spaceRequiredBefore(const AnnotatedToken &Tok) {
Daniel Jasperf1e4b7d2013-01-14 13:08:07 +00001571 if (Line.Type == LT_ObjCMethodDecl) {
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001572 if (Tok.is(tok::identifier) && !Tok.Children.empty() &&
1573 Tok.Children[0].is(tok::colon) && Tok.Parent->is(tok::identifier))
Daniel Jasperf8673bc2013-01-07 15:36:15 +00001574 return true;
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001575 if (Tok.is(tok::colon))
Daniel Jasperf8673bc2013-01-07 15:36:15 +00001576 return false;
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001577 if (Tok.Parent->Type == TT_ObjCMethodSpecifier)
Nico Weber772fbfd2013-01-17 06:14:50 +00001578 return true;
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001579 if (Tok.Parent->is(tok::r_paren) && Tok.is(tok::identifier))
Daniel Jasperf8673bc2013-01-07 15:36:15 +00001580 // Don't space between ')' and <id>
1581 return false;
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001582 if (Tok.Parent->is(tok::colon) && Tok.is(tok::l_paren))
Daniel Jasperf8673bc2013-01-07 15:36:15 +00001583 // Don't space between ':' and '('
1584 return false;
1585 }
Daniel Jasperf1e4b7d2013-01-14 13:08:07 +00001586 if (Line.Type == LT_ObjCProperty &&
Nico Webera2a84952013-01-10 21:30:42 +00001587 (Tok.is(tok::equal) || Tok.Parent->is(tok::equal)))
1588 return false;
Daniel Jasperf8673bc2013-01-07 15:36:15 +00001589
Daniel Jasper48cb3b92013-01-13 08:19:51 +00001590 if (Tok.Parent->is(tok::comma))
1591 return true;
Daniel Jasperc1fa2812013-01-10 13:08:12 +00001592 if (Tok.Type == TT_CtorInitializerColon || Tok.Type == TT_ObjCBlockLParen)
Daniel Jasperf8673bc2013-01-07 15:36:15 +00001593 return true;
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001594 if (Tok.Type == TT_OverloadedOperator)
1595 return Tok.is(tok::identifier) || Tok.is(tok::kw_new) ||
Daniel Jasperc1fa2812013-01-10 13:08:12 +00001596 Tok.is(tok::kw_delete) || Tok.is(tok::kw_bool);
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001597 if (Tok.Parent->Type == TT_OverloadedOperator)
Daniel Jasperf8673bc2013-01-07 15:36:15 +00001598 return false;
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001599 if (Tok.is(tok::colon))
Daniel Jasperf1e4b7d2013-01-14 13:08:07 +00001600 return Line.First.isNot(tok::kw_case) && !Tok.Children.empty() &&
Nico Webera7252d82013-01-12 06:18:40 +00001601 Tok.Type != TT_ObjCMethodExpr;
Daniel Jasper7194e182013-01-10 11:14:08 +00001602 if (Tok.Parent->Type == TT_UnaryOperator ||
1603 Tok.Parent->Type == TT_CastRParen)
Daniel Jasperf8673bc2013-01-07 15:36:15 +00001604 return false;
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001605 if (Tok.Type == TT_UnaryOperator)
1606 return Tok.Parent->isNot(tok::l_paren) &&
Nico Weber2827a7e2013-01-12 23:48:49 +00001607 Tok.Parent->isNot(tok::l_square) && Tok.Parent->isNot(tok::at) &&
1608 (Tok.Parent->isNot(tok::colon) ||
1609 Tok.Parent->Type != TT_ObjCMethodExpr);
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001610 if (Tok.Parent->is(tok::greater) && Tok.is(tok::greater)) {
1611 return Tok.Type == TT_TemplateCloser && Tok.Parent->Type ==
Daniel Jasperf8673bc2013-01-07 15:36:15 +00001612 TT_TemplateCloser && Style.SplitTemplateClosingGreater;
1613 }
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001614 if (Tok.Type == TT_BinaryOperator || Tok.Parent->Type == TT_BinaryOperator)
Daniel Jasperf8673bc2013-01-07 15:36:15 +00001615 return true;
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001616 if (Tok.Parent->Type == TT_TemplateCloser && Tok.is(tok::l_paren))
Daniel Jasperf8673bc2013-01-07 15:36:15 +00001617 return false;
Daniel Jasperf1e4b7d2013-01-14 13:08:07 +00001618 if (Tok.is(tok::less) && Line.First.is(tok::hash))
Daniel Jasperf8673bc2013-01-07 15:36:15 +00001619 return true;
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001620 if (Tok.Type == TT_TrailingUnaryOperator)
Daniel Jasperf8673bc2013-01-07 15:36:15 +00001621 return false;
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001622 return spaceRequiredBetween(*Tok.Parent, Tok);
Daniel Jasperf8673bc2013-01-07 15:36:15 +00001623 }
1624
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001625 bool canBreakBefore(const AnnotatedToken &Right) {
1626 const AnnotatedToken &Left = *Right.Parent;
Daniel Jasperf1e4b7d2013-01-14 13:08:07 +00001627 if (Line.Type == LT_ObjCMethodDecl) {
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001628 if (Right.is(tok::identifier) && !Right.Children.empty() &&
1629 Right.Children[0].is(tok::colon) && Left.is(tok::identifier))
Daniel Jasperf8673bc2013-01-07 15:36:15 +00001630 return true;
Nico Weberc7a56342013-01-12 07:00:16 +00001631 if (Right.is(tok::identifier) && Left.is(tok::l_paren) &&
1632 Left.Parent->is(tok::colon))
Daniel Jasperf8673bc2013-01-07 15:36:15 +00001633 // Don't break this identifier as ':' or identifier
1634 // before it will break.
1635 return false;
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001636 if (Right.is(tok::colon) && Left.is(tok::identifier) &&
1637 Left.CanBreakBefore)
Daniel Jasperf8673bc2013-01-07 15:36:15 +00001638 // Don't break at ':' if identifier before it can beak.
1639 return false;
1640 }
Daniel Jasperd36ef5e2013-01-28 15:40:20 +00001641 if (Right.Type == TT_StartOfName && Style.AllowReturnTypeOnItsOwnLine)
Daniel Jasperd2639ef2013-01-28 15:16:31 +00001642 return true;
Nico Webera7252d82013-01-12 06:18:40 +00001643 if (Right.is(tok::colon) && Right.Type == TT_ObjCMethodExpr)
1644 return false;
1645 if (Left.is(tok::colon) && Left.Type == TT_ObjCMethodExpr)
1646 return true;
Nico Weberc9d73612013-01-12 22:48:47 +00001647 if (isObjCSelectorName(Right))
1648 return true;
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001649 if (Left.ClosesTemplateDeclaration)
Daniel Jasper90e51fd2013-01-02 18:30:06 +00001650 return true;
Daniel Jasperca6623b2013-01-28 12:45:14 +00001651 if (Right.Type == TT_ConditionalExpr || Right.is(tok::question))
1652 return true;
Daniel Jasper0b41cbb2013-01-28 13:21:16 +00001653 if (Left.Type == TT_RangeBasedForLoopColon)
1654 return true;
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001655 if (Left.Type == TT_PointerOrReference || Left.Type == TT_TemplateCloser ||
Daniel Jasperca6623b2013-01-28 12:45:14 +00001656 Left.Type == TT_UnaryOperator || Left.Type == TT_ConditionalExpr ||
1657 Left.is(tok::question))
Daniel Jasperd1926a32013-01-02 08:44:14 +00001658 return false;
Daniel Jasperf1e4b7d2013-01-14 13:08:07 +00001659 if (Left.is(tok::equal) && Line.Type == LT_VirtualFunctionDecl)
Daniel Jasperda16db32013-01-07 10:48:50 +00001660 return false;
1661
Daniel Jasper11cb81c2013-01-17 12:53:34 +00001662 if (Right.Type == TT_LineComment)
Daniel Jasper942ee722013-01-13 16:10:20 +00001663 // We rely on MustBreakBefore being set correctly here as we should not
1664 // change the "binding" behavior of a comment.
1665 return false;
1666
Daniel Jasperfefb1e62013-01-17 13:31:52 +00001667 // Allow breaking after a trailing 'const', e.g. after a method declaration,
1668 // unless it is follow by ';', '{' or '='.
1669 if (Left.is(tok::kw_const) && Left.Parent != NULL &&
1670 Left.Parent->is(tok::r_paren))
1671 return Right.isNot(tok::l_brace) && Right.isNot(tok::semi) &&
1672 Right.isNot(tok::equal);
1673
Manuel Klimeka54d1a92013-01-14 16:41:43 +00001674 // We only break before r_brace if there was a corresponding break before
1675 // the l_brace, which is tracked by BreakBeforeClosingBrace.
1676 if (Right.is(tok::r_brace))
1677 return false;
1678
Daniel Jasper71945272013-01-15 14:27:39 +00001679 if (Right.is(tok::r_paren) || Right.is(tok::greater))
Daniel Jasperf7935112012-12-03 18:12:45 +00001680 return false;
Daniel Jasper7c85fde2013-01-08 14:56:18 +00001681 return (isBinaryOperator(Left) && Left.isNot(tok::lessless)) ||
1682 Left.is(tok::comma) || Right.is(tok::lessless) ||
1683 Right.is(tok::arrow) || Right.is(tok::period) ||
Daniel Jasper45797022013-01-25 10:57:27 +00001684 Right.is(tok::colon) || Left.is(tok::coloncolon) ||
1685 Left.is(tok::semi) || Left.is(tok::l_brace) ||
Daniel Jasper45797022013-01-25 10:57:27 +00001686 (Left.is(tok::r_paren) && Left.Type != TT_CastRParen &&
1687 Right.is(tok::identifier)) ||
Daniel Jasper7b5773e92013-01-28 07:35:34 +00001688 (Left.is(tok::l_paren) && !Right.is(tok::r_paren)) ||
1689 (Left.is(tok::l_square) && !Right.is(tok::r_square));
Daniel Jasperf7935112012-12-03 18:12:45 +00001690 }
1691
Daniel Jasperf7935112012-12-03 18:12:45 +00001692 FormatStyle Style;
1693 SourceManager &SourceMgr;
Manuel Klimekc74d2922013-01-07 08:54:53 +00001694 Lexer &Lex;
Daniel Jasperf1e4b7d2013-01-14 13:08:07 +00001695 AnnotatedLine &Line;
Daniel Jasperf7935112012-12-03 18:12:45 +00001696};
1697
Alexander Kornienkoe3276842012-12-07 16:15:44 +00001698class LexerBasedFormatTokenSource : public FormatTokenSource {
1699public:
1700 LexerBasedFormatTokenSource(Lexer &Lex, SourceManager &SourceMgr)
Daniel Jasper2af6bbe2012-12-18 21:05:13 +00001701 : GreaterStashed(false), Lex(Lex), SourceMgr(SourceMgr),
Alexander Kornienkoe3276842012-12-07 16:15:44 +00001702 IdentTable(Lex.getLangOpts()) {
1703 Lex.SetKeepWhitespaceMode(true);
1704 }
1705
1706 virtual FormatToken getNextToken() {
1707 if (GreaterStashed) {
1708 FormatTok.NewlinesBefore = 0;
1709 FormatTok.WhiteSpaceStart =
1710 FormatTok.Tok.getLocation().getLocWithOffset(1);
1711 FormatTok.WhiteSpaceLength = 0;
1712 GreaterStashed = false;
1713 return FormatTok;
1714 }
1715
1716 FormatTok = FormatToken();
1717 Lex.LexFromRawLexer(FormatTok.Tok);
Manuel Klimekef920692013-01-07 07:56:50 +00001718 StringRef Text = rawTokenText(FormatTok.Tok);
Alexander Kornienkoe3276842012-12-07 16:15:44 +00001719 FormatTok.WhiteSpaceStart = FormatTok.Tok.getLocation();
Manuel Klimek52d0fd82013-01-05 22:56:06 +00001720 if (SourceMgr.getFileOffset(FormatTok.WhiteSpaceStart) == 0)
1721 FormatTok.IsFirst = true;
Alexander Kornienkoe3276842012-12-07 16:15:44 +00001722
1723 // Consume and record whitespace until we find a significant token.
1724 while (FormatTok.Tok.is(tok::unknown)) {
Manuel Klimeka71e5d82013-01-02 16:30:12 +00001725 FormatTok.NewlinesBefore += Text.count('\n');
Daniel Jasperbbc84152013-01-29 11:27:30 +00001726 FormatTok.HasUnescapedNewline =
1727 Text.count("\\\n") != FormatTok.NewlinesBefore;
Alexander Kornienkoe3276842012-12-07 16:15:44 +00001728 FormatTok.WhiteSpaceLength += FormatTok.Tok.getLength();
1729
1730 if (FormatTok.Tok.is(tok::eof))
1731 return FormatTok;
1732 Lex.LexFromRawLexer(FormatTok.Tok);
Manuel Klimekef920692013-01-07 07:56:50 +00001733 Text = rawTokenText(FormatTok.Tok);
Manuel Klimek1abf7892013-01-04 23:34:14 +00001734 }
Manuel Klimekef920692013-01-07 07:56:50 +00001735
1736 // Now FormatTok is the next non-whitespace token.
1737 FormatTok.TokenLength = Text.size();
1738
Manuel Klimek1abf7892013-01-04 23:34:14 +00001739 // In case the token starts with escaped newlines, we want to
1740 // take them into account as whitespace - this pattern is quite frequent
1741 // in macro definitions.
1742 // FIXME: What do we want to do with other escaped spaces, and escaped
1743 // spaces or newlines in the middle of tokens?
1744 // FIXME: Add a more explicit test.
1745 unsigned i = 0;
Daniel Jasperda16db32013-01-07 10:48:50 +00001746 while (i + 1 < Text.size() && Text[i] == '\\' && Text[i + 1] == '\n') {
Manuel Klimekf92f7bc2013-01-22 16:31:55 +00001747 // FIXME: ++FormatTok.NewlinesBefore is missing...
Manuel Klimek1abf7892013-01-04 23:34:14 +00001748 FormatTok.WhiteSpaceLength += 2;
Manuel Klimekef920692013-01-07 07:56:50 +00001749 FormatTok.TokenLength -= 2;
Manuel Klimek1abf7892013-01-04 23:34:14 +00001750 i += 2;
Alexander Kornienkoe3276842012-12-07 16:15:44 +00001751 }
1752
1753 if (FormatTok.Tok.is(tok::raw_identifier)) {
Manuel Klimek1abf7892013-01-04 23:34:14 +00001754 IdentifierInfo &Info = IdentTable.get(Text);
Daniel Jasper050948a52012-12-21 17:58:39 +00001755 FormatTok.Tok.setIdentifierInfo(&Info);
Alexander Kornienkoe3276842012-12-07 16:15:44 +00001756 FormatTok.Tok.setKind(Info.getTokenID());
1757 }
1758
1759 if (FormatTok.Tok.is(tok::greatergreater)) {
1760 FormatTok.Tok.setKind(tok::greater);
1761 GreaterStashed = true;
1762 }
1763
1764 return FormatTok;
1765 }
1766
1767private:
1768 FormatToken FormatTok;
1769 bool GreaterStashed;
1770 Lexer &Lex;
1771 SourceManager &SourceMgr;
1772 IdentifierTable IdentTable;
1773
1774 /// Returns the text of \c FormatTok.
Manuel Klimekef920692013-01-07 07:56:50 +00001775 StringRef rawTokenText(Token &Tok) {
Alexander Kornienkoe3276842012-12-07 16:15:44 +00001776 return StringRef(SourceMgr.getCharacterData(Tok.getLocation()),
1777 Tok.getLength());
1778 }
1779};
1780
Daniel Jasperf7935112012-12-03 18:12:45 +00001781class Formatter : public UnwrappedLineConsumer {
1782public:
Daniel Jasper25837aa2013-01-14 14:14:23 +00001783 Formatter(DiagnosticsEngine &Diag, const FormatStyle &Style, Lexer &Lex,
1784 SourceManager &SourceMgr,
Daniel Jasperf7935112012-12-03 18:12:45 +00001785 const std::vector<CharSourceRange> &Ranges)
Alexander Kornienko5b7157a2013-01-10 15:05:09 +00001786 : Diag(Diag), Style(Style), Lex(Lex), SourceMgr(SourceMgr),
Daniel Jasperbbc84152013-01-29 11:27:30 +00001787 Whitespaces(SourceMgr), Ranges(Ranges) {
1788 }
Daniel Jasperf7935112012-12-03 18:12:45 +00001789
Daniel Jasperfd8c4b12013-01-11 14:23:32 +00001790 virtual ~Formatter() {}
Daniel Jasper61bd3a12012-12-04 21:05:31 +00001791
Daniel Jasperf7935112012-12-03 18:12:45 +00001792 tooling::Replacements format() {
Alexander Kornienkoe3276842012-12-07 16:15:44 +00001793 LexerBasedFormatTokenSource Tokens(Lex, SourceMgr);
Alexander Kornienko5b7157a2013-01-10 15:05:09 +00001794 UnwrappedLineParser Parser(Diag, Style, Tokens, *this);
Alexander Kornienko870f9eb2012-12-04 17:27:50 +00001795 StructuralError = Parser.parse();
Manuel Klimek1abf7892013-01-04 23:34:14 +00001796 unsigned PreviousEndOfLineColumn = 0;
Daniel Jasperf1e4b7d2013-01-14 13:08:07 +00001797 for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
1798 TokenAnnotator Annotator(Style, SourceMgr, Lex, AnnotatedLines[i]);
1799 Annotator.annotate();
1800 }
1801 for (std::vector<AnnotatedLine>::iterator I = AnnotatedLines.begin(),
1802 E = AnnotatedLines.end();
Manuel Klimek51bd6ec2013-01-10 19:49:59 +00001803 I != E; ++I) {
Daniel Jasperf1e4b7d2013-01-14 13:08:07 +00001804 const AnnotatedLine &TheLine = *I;
1805 if (touchesRanges(TheLine) && TheLine.Type != LT_Invalid) {
Daniel Jasperbbc84152013-01-29 11:27:30 +00001806 unsigned Indent =
1807 formatFirstToken(TheLine.First, TheLine.Level,
1808 TheLine.InPPDirective, PreviousEndOfLineColumn);
Daniel Jaspera67a8f02013-01-16 10:41:46 +00001809 tryFitMultipleLinesInOne(Indent, I, E);
Daniel Jasperf1e4b7d2013-01-14 13:08:07 +00001810 UnwrappedLineFormatter Formatter(Style, SourceMgr, TheLine, Indent,
Daniel Jasperaa701fa2013-01-18 08:44:07 +00001811 TheLine.First, Whitespaces,
Daniel Jasperf1e4b7d2013-01-14 13:08:07 +00001812 StructuralError);
Manuel Klimek51bd6ec2013-01-10 19:49:59 +00001813 PreviousEndOfLineColumn = Formatter.format();
1814 } else {
1815 // If we did not reformat this unwrapped line, the column at the end of
1816 // the last token is unchanged - thus, we can calculate the end of the
1817 // last token, and return the result.
Manuel Klimek51bd6ec2013-01-10 19:49:59 +00001818 PreviousEndOfLineColumn =
Daniel Jasperf1e4b7d2013-01-14 13:08:07 +00001819 SourceMgr.getSpellingColumnNumber(
1820 TheLine.Last->FormatTok.Tok.getLocation()) +
1821 Lex.MeasureTokenLength(TheLine.Last->FormatTok.Tok.getLocation(),
Daniel Jasperbbc84152013-01-29 11:27:30 +00001822 SourceMgr, Lex.getLangOpts()) - 1;
Manuel Klimek51bd6ec2013-01-10 19:49:59 +00001823 }
1824 }
Daniel Jasperaa701fa2013-01-18 08:44:07 +00001825 return Whitespaces.generateReplacements();
Daniel Jasperf7935112012-12-03 18:12:45 +00001826 }
1827
1828private:
Manuel Klimekf4ab9ef2013-01-11 17:54:10 +00001829 /// \brief Tries to merge lines into one.
1830 ///
1831 /// This will change \c Line and \c AnnotatedLine to contain the merged line,
1832 /// if possible; note that \c I will be incremented when lines are merged.
1833 ///
1834 /// Returns whether the resulting \c Line can fit in a single line.
Daniel Jaspera67a8f02013-01-16 10:41:46 +00001835 void tryFitMultipleLinesInOne(unsigned Indent,
Daniel Jasperf1e4b7d2013-01-14 13:08:07 +00001836 std::vector<AnnotatedLine>::iterator &I,
1837 std::vector<AnnotatedLine>::iterator E) {
Manuel Klimekf4ab9ef2013-01-11 17:54:10 +00001838 unsigned Limit = Style.ColumnLimit - (I->InPPDirective ? 1 : 0) - Indent;
1839
Daniel Jaspera67a8f02013-01-16 10:41:46 +00001840 // We can never merge stuff if there are trailing line comments.
1841 if (I->Last->Type == TT_LineComment)
1842 return;
1843
Manuel Klimekf4ab9ef2013-01-11 17:54:10 +00001844 // Check whether the UnwrappedLine can be put onto a single line. If
1845 // so, this is bound to be the optimal solution (by definition) and we
1846 // don't need to analyze the entire solution space.
Manuel Klimeka4fe1c12013-01-21 16:42:44 +00001847 if (I->Last->TotalLength > Limit)
Daniel Jaspera67a8f02013-01-16 10:41:46 +00001848 return;
Manuel Klimeka4fe1c12013-01-21 16:42:44 +00001849 Limit -= I->Last->TotalLength;
Daniel Jasperc36492b2013-01-16 07:02:34 +00001850
Daniel Jasperd41ee2d2013-01-21 14:18:28 +00001851 if (I + 1 == E || (I + 1)->Type == LT_Invalid)
Daniel Jaspera67a8f02013-01-16 10:41:46 +00001852 return;
Manuel Klimekf4ab9ef2013-01-11 17:54:10 +00001853
Daniel Jasper25837aa2013-01-14 14:14:23 +00001854 if (I->Last->is(tok::l_brace)) {
1855 tryMergeSimpleBlock(I, E, Limit);
1856 } else if (I->First.is(tok::kw_if)) {
1857 tryMergeSimpleIf(I, E, Limit);
Daniel Jasper39825ea2013-01-14 15:40:57 +00001858 } else if (I->InPPDirective && (I->First.FormatTok.HasUnescapedNewline ||
1859 I->First.FormatTok.IsFirst)) {
1860 tryMergeSimplePPDirective(I, E, Limit);
Daniel Jasper25837aa2013-01-14 14:14:23 +00001861 }
Daniel Jaspera67a8f02013-01-16 10:41:46 +00001862 return;
Daniel Jasper25837aa2013-01-14 14:14:23 +00001863 }
1864
Daniel Jasper39825ea2013-01-14 15:40:57 +00001865 void tryMergeSimplePPDirective(std::vector<AnnotatedLine>::iterator &I,
1866 std::vector<AnnotatedLine>::iterator E,
1867 unsigned Limit) {
1868 AnnotatedLine &Line = *I;
Daniel Jasper2ab0d012013-01-14 15:52:06 +00001869 if (!(I + 1)->InPPDirective || (I + 1)->First.FormatTok.HasUnescapedNewline)
1870 return;
Daniel Jasper39825ea2013-01-14 15:40:57 +00001871 if (I + 2 != E && (I + 2)->InPPDirective &&
1872 !(I + 2)->First.FormatTok.HasUnescapedNewline)
1873 return;
Manuel Klimeka4fe1c12013-01-21 16:42:44 +00001874 if (1 + (I + 1)->Last->TotalLength > Limit)
Daniel Jaspera67a8f02013-01-16 10:41:46 +00001875 return;
Daniel Jasper39825ea2013-01-14 15:40:57 +00001876 join(Line, *(++I));
1877 }
1878
Daniel Jasper25837aa2013-01-14 14:14:23 +00001879 void tryMergeSimpleIf(std::vector<AnnotatedLine>::iterator &I,
1880 std::vector<AnnotatedLine>::iterator E,
1881 unsigned Limit) {
Daniel Jasper1b750ed2013-01-14 16:24:39 +00001882 if (!Style.AllowShortIfStatementsOnASingleLine)
1883 return;
Manuel Klimekda087612013-01-18 14:46:43 +00001884 if ((I + 1)->InPPDirective != I->InPPDirective ||
1885 ((I + 1)->InPPDirective &&
1886 (I + 1)->First.FormatTok.HasUnescapedNewline))
1887 return;
Daniel Jasper25837aa2013-01-14 14:14:23 +00001888 AnnotatedLine &Line = *I;
Daniel Jasperc36492b2013-01-16 07:02:34 +00001889 if (Line.Last->isNot(tok::r_paren))
1890 return;
Manuel Klimeka4fe1c12013-01-21 16:42:44 +00001891 if (1 + (I + 1)->Last->TotalLength > Limit)
Daniel Jasper25837aa2013-01-14 14:14:23 +00001892 return;
1893 if ((I + 1)->First.is(tok::kw_if) || (I + 1)->First.Type == TT_LineComment)
1894 return;
1895 // Only inline simple if's (no nested if or else).
1896 if (I + 2 != E && (I + 2)->First.is(tok::kw_else))
1897 return;
1898 join(Line, *(++I));
1899 }
1900
1901 void tryMergeSimpleBlock(std::vector<AnnotatedLine>::iterator &I,
Daniel Jasperbbc84152013-01-29 11:27:30 +00001902 std::vector<AnnotatedLine>::iterator E,
1903 unsigned Limit) {
Manuel Klimekf4ab9ef2013-01-11 17:54:10 +00001904 // First, check that the current line allows merging. This is the case if
1905 // we're not in a control flow statement and the last token is an opening
1906 // brace.
Daniel Jasper25837aa2013-01-14 14:14:23 +00001907 AnnotatedLine &Line = *I;
Manuel Klimekf4ab9ef2013-01-11 17:54:10 +00001908 bool AllowedTokens =
Daniel Jasperf1e4b7d2013-01-14 13:08:07 +00001909 Line.First.isNot(tok::kw_if) && Line.First.isNot(tok::kw_while) &&
1910 Line.First.isNot(tok::kw_do) && Line.First.isNot(tok::r_brace) &&
1911 Line.First.isNot(tok::kw_else) && Line.First.isNot(tok::kw_try) &&
1912 Line.First.isNot(tok::kw_catch) && Line.First.isNot(tok::kw_for) &&
Nico Webera21aaae2013-01-11 21:14:08 +00001913 // This gets rid of all ObjC @ keywords and methods.
Daniel Jasperf1e4b7d2013-01-14 13:08:07 +00001914 Line.First.isNot(tok::at) && Line.First.isNot(tok::minus) &&
1915 Line.First.isNot(tok::plus);
Daniel Jasper25837aa2013-01-14 14:14:23 +00001916 if (!AllowedTokens)
1917 return;
Manuel Klimekf4ab9ef2013-01-11 17:54:10 +00001918
Manuel Klimeka4fe1c12013-01-21 16:42:44 +00001919 AnnotatedToken *Tok = &(I + 1)->First;
1920 if (Tok->Children.empty() && Tok->is(tok::r_brace) &&
1921 !Tok->MustBreakBefore && Tok->TotalLength <= Limit) {
1922 Tok->SpaceRequiredBefore = false;
1923 join(Line, *(I + 1));
1924 I += 1;
1925 } else {
1926 // Check that we still have three lines and they fit into the limit.
1927 if (I + 2 == E || (I + 2)->Type == LT_Invalid ||
1928 !nextTwoLinesFitInto(I, Limit))
Daniel Jasper25837aa2013-01-14 14:14:23 +00001929 return;
Manuel Klimekf4ab9ef2013-01-11 17:54:10 +00001930
Manuel Klimeka4fe1c12013-01-21 16:42:44 +00001931 // Second, check that the next line does not contain any braces - if it
1932 // does, readability declines when putting it into a single line.
1933 if ((I + 1)->Last->Type == TT_LineComment || Tok->MustBreakBefore)
1934 return;
1935 do {
1936 if (Tok->is(tok::l_brace) || Tok->is(tok::r_brace))
1937 return;
1938 Tok = Tok->Children.empty() ? NULL : &Tok->Children.back();
1939 } while (Tok != NULL);
Manuel Klimekf4ab9ef2013-01-11 17:54:10 +00001940
Manuel Klimeka4fe1c12013-01-21 16:42:44 +00001941 // Last, check that the third line contains a single closing brace.
1942 Tok = &(I + 2)->First;
1943 if (!Tok->Children.empty() || Tok->isNot(tok::r_brace) ||
1944 Tok->MustBreakBefore)
1945 return;
1946
1947 join(Line, *(I + 1));
1948 join(Line, *(I + 2));
1949 I += 2;
Manuel Klimekf4ab9ef2013-01-11 17:54:10 +00001950 }
Daniel Jasper25837aa2013-01-14 14:14:23 +00001951 }
1952
1953 bool nextTwoLinesFitInto(std::vector<AnnotatedLine>::iterator I,
1954 unsigned Limit) {
Manuel Klimeka4fe1c12013-01-21 16:42:44 +00001955 return 1 + (I + 1)->Last->TotalLength + 1 + (I + 2)->Last->TotalLength <=
1956 Limit;
Manuel Klimekf4ab9ef2013-01-11 17:54:10 +00001957 }
1958
Daniel Jasperf1e4b7d2013-01-14 13:08:07 +00001959 void join(AnnotatedLine &A, const AnnotatedLine &B) {
1960 A.Last->Children.push_back(B.First);
1961 while (!A.Last->Children.empty()) {
1962 A.Last->Children[0].Parent = A.Last;
1963 A.Last = &A.Last->Children[0];
1964 }
Manuel Klimek51bd6ec2013-01-10 19:49:59 +00001965 }
1966
Daniel Jasperf1e4b7d2013-01-14 13:08:07 +00001967 bool touchesRanges(const AnnotatedLine &TheLine) {
1968 const FormatToken *First = &TheLine.First.FormatTok;
1969 const FormatToken *Last = &TheLine.Last->FormatTok;
Daniel Jasper8d1832e2013-01-07 13:26:07 +00001970 CharSourceRange LineRange = CharSourceRange::getTokenRange(
Daniel Jasperbbc84152013-01-29 11:27:30 +00001971 First->Tok.getLocation(), Last->Tok.getLocation());
Daniel Jasperf7935112012-12-03 18:12:45 +00001972 for (unsigned i = 0, e = Ranges.size(); i != e; ++i) {
Manuel Klimek51bd6ec2013-01-10 19:49:59 +00001973 if (!SourceMgr.isBeforeInTranslationUnit(LineRange.getEnd(),
1974 Ranges[i].getBegin()) &&
1975 !SourceMgr.isBeforeInTranslationUnit(Ranges[i].getEnd(),
1976 LineRange.getBegin()))
1977 return true;
Daniel Jasperf7935112012-12-03 18:12:45 +00001978 }
Manuel Klimek51bd6ec2013-01-10 19:49:59 +00001979 return false;
1980 }
1981
1982 virtual void consumeUnwrappedLine(const UnwrappedLine &TheLine) {
Daniel Jasperdaffc0d2013-01-16 09:10:19 +00001983 AnnotatedLines.push_back(AnnotatedLine(TheLine));
Daniel Jasperf7935112012-12-03 18:12:45 +00001984 }
1985
Manuel Klimek0b689fd2013-01-10 18:45:26 +00001986 /// \brief Add a new line and the required indent before the first Token
1987 /// of the \c UnwrappedLine if there was no structural parsing error.
1988 /// Returns the indent level of the \c UnwrappedLine.
1989 unsigned formatFirstToken(const AnnotatedToken &RootToken, unsigned Level,
1990 bool InPPDirective,
1991 unsigned PreviousEndOfLineColumn) {
Daniel Jasperfd8c4b12013-01-11 14:23:32 +00001992 const FormatToken &Tok = RootToken.FormatTok;
Manuel Klimek0b689fd2013-01-10 18:45:26 +00001993 if (!Tok.WhiteSpaceStart.isValid() || StructuralError)
1994 return SourceMgr.getSpellingColumnNumber(Tok.Tok.getLocation()) - 1;
1995
Daniel Jasperbbc84152013-01-29 11:27:30 +00001996 unsigned Newlines =
1997 std::min(Tok.NewlinesBefore, Style.MaxEmptyLinesToKeep + 1);
Manuel Klimek0b689fd2013-01-10 18:45:26 +00001998 if (Newlines == 0 && !Tok.IsFirst)
1999 Newlines = 1;
2000 unsigned Indent = Level * 2;
2001
2002 bool IsAccessModifier = false;
2003 if (RootToken.is(tok::kw_public) || RootToken.is(tok::kw_protected) ||
2004 RootToken.is(tok::kw_private))
2005 IsAccessModifier = true;
2006 else if (RootToken.is(tok::at) && !RootToken.Children.empty() &&
2007 (RootToken.Children[0].isObjCAtKeyword(tok::objc_public) ||
2008 RootToken.Children[0].isObjCAtKeyword(tok::objc_protected) ||
2009 RootToken.Children[0].isObjCAtKeyword(tok::objc_package) ||
2010 RootToken.Children[0].isObjCAtKeyword(tok::objc_private)))
2011 IsAccessModifier = true;
2012
2013 if (IsAccessModifier &&
2014 static_cast<int>(Indent) + Style.AccessModifierOffset >= 0)
2015 Indent += Style.AccessModifierOffset;
2016 if (!InPPDirective || Tok.HasUnescapedNewline) {
Daniel Jasperaa701fa2013-01-18 08:44:07 +00002017 Whitespaces.replaceWhitespace(RootToken, Newlines, Indent, 0, Style);
Manuel Klimek0b689fd2013-01-10 18:45:26 +00002018 } else {
Daniel Jasperaa701fa2013-01-18 08:44:07 +00002019 Whitespaces.replacePPWhitespace(RootToken, Newlines, Indent,
2020 PreviousEndOfLineColumn, Style);
Manuel Klimek0b689fd2013-01-10 18:45:26 +00002021 }
2022 return Indent;
2023 }
2024
Alexander Kornienko116ba682013-01-14 11:34:14 +00002025 DiagnosticsEngine &Diag;
Daniel Jasperf7935112012-12-03 18:12:45 +00002026 FormatStyle Style;
2027 Lexer &Lex;
2028 SourceManager &SourceMgr;
Daniel Jasperaa701fa2013-01-18 08:44:07 +00002029 WhitespaceManager Whitespaces;
Daniel Jasperf7935112012-12-03 18:12:45 +00002030 std::vector<CharSourceRange> Ranges;
Daniel Jasperf1e4b7d2013-01-14 13:08:07 +00002031 std::vector<AnnotatedLine> AnnotatedLines;
Alexander Kornienko870f9eb2012-12-04 17:27:50 +00002032 bool StructuralError;
Daniel Jasperf7935112012-12-03 18:12:45 +00002033};
2034
Daniel Jasperbbc84152013-01-29 11:27:30 +00002035tooling::Replacements
2036reformat(const FormatStyle &Style, Lexer &Lex, SourceManager &SourceMgr,
2037 std::vector<CharSourceRange> Ranges, DiagnosticConsumer *DiagClient) {
Alexander Kornienko5b7157a2013-01-10 15:05:09 +00002038 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
Alexander Kornienko116ba682013-01-14 11:34:14 +00002039 OwningPtr<DiagnosticConsumer> DiagPrinter;
2040 if (DiagClient == 0) {
2041 DiagPrinter.reset(new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts));
2042 DiagPrinter->BeginSourceFile(Lex.getLangOpts(), Lex.getPP());
2043 DiagClient = DiagPrinter.get();
2044 }
Alexander Kornienko5b7157a2013-01-10 15:05:09 +00002045 DiagnosticsEngine Diagnostics(
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002046 IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()), &*DiagOpts,
Alexander Kornienko116ba682013-01-14 11:34:14 +00002047 DiagClient, false);
Alexander Kornienko5b7157a2013-01-10 15:05:09 +00002048 Diagnostics.setSourceManager(&SourceMgr);
2049 Formatter formatter(Diagnostics, Style, Lex, SourceMgr, Ranges);
Daniel Jasperf7935112012-12-03 18:12:45 +00002050 return formatter.format();
2051}
2052
Daniel Jasperc1fa2812013-01-10 13:08:12 +00002053LangOptions getFormattingLangOpts() {
2054 LangOptions LangOpts;
2055 LangOpts.CPlusPlus = 1;
2056 LangOpts.CPlusPlus11 = 1;
2057 LangOpts.Bool = 1;
2058 LangOpts.ObjC1 = 1;
2059 LangOpts.ObjC2 = 1;
2060 return LangOpts;
2061}
2062
Daniel Jasper8d1832e2013-01-07 13:26:07 +00002063} // namespace format
2064} // namespace clang