]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/lib/Format/FormatTokenLexer.cpp
Merge clang trunk r300422 and resolve conflicts.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / lib / Format / FormatTokenLexer.cpp
1 //===--- FormatTokenLexer.cpp - Lex FormatTokens -------------*- C++ ----*-===//
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 FormatTokenLexer, which tokenizes a source file
12 /// into a FormatToken stream suitable for ClangFormat.
13 ///
14 //===----------------------------------------------------------------------===//
15
16 #include "FormatTokenLexer.h"
17 #include "FormatToken.h"
18 #include "clang/Basic/SourceLocation.h"
19 #include "clang/Basic/SourceManager.h"
20 #include "clang/Format/Format.h"
21 #include "llvm/Support/Regex.h"
22
23 namespace clang {
24 namespace format {
25
26 FormatTokenLexer::FormatTokenLexer(const SourceManager &SourceMgr, FileID ID,
27                                    const FormatStyle &Style,
28                                    encoding::Encoding Encoding)
29     : FormatTok(nullptr), IsFirstToken(true), StateStack({LexerState::NORMAL}),
30       Column(0), TrailingWhitespace(0), SourceMgr(SourceMgr), ID(ID),
31       Style(Style), IdentTable(getFormattingLangOpts(Style)),
32       Keywords(IdentTable), Encoding(Encoding), FirstInLineIndex(0),
33       FormattingDisabled(false), MacroBlockBeginRegex(Style.MacroBlockBegin),
34       MacroBlockEndRegex(Style.MacroBlockEnd) {
35   Lex.reset(new Lexer(ID, SourceMgr.getBuffer(ID), SourceMgr,
36                       getFormattingLangOpts(Style)));
37   Lex->SetKeepWhitespaceMode(true);
38
39   for (const std::string &ForEachMacro : Style.ForEachMacros)
40     ForEachMacros.push_back(&IdentTable.get(ForEachMacro));
41   std::sort(ForEachMacros.begin(), ForEachMacros.end());
42 }
43
44 ArrayRef<FormatToken *> FormatTokenLexer::lex() {
45   assert(Tokens.empty());
46   assert(FirstInLineIndex == 0);
47   do {
48     Tokens.push_back(getNextToken());
49     if (Style.Language == FormatStyle::LK_JavaScript) {
50       tryParseJSRegexLiteral();
51       handleTemplateStrings();
52     }
53     tryMergePreviousTokens();
54     if (Tokens.back()->NewlinesBefore > 0 || Tokens.back()->IsMultiline)
55       FirstInLineIndex = Tokens.size() - 1;
56   } while (Tokens.back()->Tok.isNot(tok::eof));
57   return Tokens;
58 }
59
60 void FormatTokenLexer::tryMergePreviousTokens() {
61   if (tryMerge_TMacro())
62     return;
63   if (tryMergeConflictMarkers())
64     return;
65   if (tryMergeLessLess())
66     return;
67   if (tryMergeNSStringLiteral())
68     return;
69
70   if (Style.Language == FormatStyle::LK_JavaScript) {
71     static const tok::TokenKind JSIdentity[] = {tok::equalequal, tok::equal};
72     static const tok::TokenKind JSNotIdentity[] = {tok::exclaimequal,
73                                                    tok::equal};
74     static const tok::TokenKind JSShiftEqual[] = {tok::greater, tok::greater,
75                                                   tok::greaterequal};
76     static const tok::TokenKind JSRightArrow[] = {tok::equal, tok::greater};
77     // FIXME: Investigate what token type gives the correct operator priority.
78     if (tryMergeTokens(JSIdentity, TT_BinaryOperator))
79       return;
80     if (tryMergeTokens(JSNotIdentity, TT_BinaryOperator))
81       return;
82     if (tryMergeTokens(JSShiftEqual, TT_BinaryOperator))
83       return;
84     if (tryMergeTokens(JSRightArrow, TT_JsFatArrow))
85       return;
86   }
87
88   if (Style.Language == FormatStyle::LK_Java) {
89     static const tok::TokenKind JavaRightLogicalShift[] = {tok::greater,
90                                                            tok::greater,
91                                                            tok::greater};
92     static const tok::TokenKind JavaRightLogicalShiftAssign[] = {tok::greater,
93                                                                  tok::greater,
94                                                                  tok::greaterequal};
95     if (tryMergeTokens(JavaRightLogicalShift, TT_BinaryOperator))
96       return;
97     if (tryMergeTokens(JavaRightLogicalShiftAssign, TT_BinaryOperator))
98       return;
99   }
100 }
101
102 bool FormatTokenLexer::tryMergeNSStringLiteral() {
103   if (Tokens.size() < 2)
104     return false;
105   auto &At = *(Tokens.end() - 2);
106   auto &String = *(Tokens.end() - 1);
107   if (!At->is(tok::at) || !String->is(tok::string_literal))
108     return false;
109   At->Tok.setKind(tok::string_literal);
110   At->TokenText = StringRef(At->TokenText.begin(),
111                             String->TokenText.end() - At->TokenText.begin());
112   At->ColumnWidth += String->ColumnWidth;
113   At->Type = TT_ObjCStringLiteral;
114   Tokens.erase(Tokens.end() - 1);
115   return true;
116 }
117
118 bool FormatTokenLexer::tryMergeLessLess() {
119   // Merge X,less,less,Y into X,lessless,Y unless X or Y is less.
120   if (Tokens.size() < 3)
121     return false;
122
123   bool FourthTokenIsLess = false;
124   if (Tokens.size() > 3)
125     FourthTokenIsLess = (Tokens.end() - 4)[0]->is(tok::less);
126
127   auto First = Tokens.end() - 3;
128   if (First[2]->is(tok::less) || First[1]->isNot(tok::less) ||
129       First[0]->isNot(tok::less) || FourthTokenIsLess)
130     return false;
131
132   // Only merge if there currently is no whitespace between the two "<".
133   if (First[1]->WhitespaceRange.getBegin() !=
134       First[1]->WhitespaceRange.getEnd())
135     return false;
136
137   First[0]->Tok.setKind(tok::lessless);
138   First[0]->TokenText = "<<";
139   First[0]->ColumnWidth += 1;
140   Tokens.erase(Tokens.end() - 2);
141   return true;
142 }
143
144 bool FormatTokenLexer::tryMergeTokens(ArrayRef<tok::TokenKind> Kinds,
145                                       TokenType NewType) {
146   if (Tokens.size() < Kinds.size())
147     return false;
148
149   SmallVectorImpl<FormatToken *>::const_iterator First =
150       Tokens.end() - Kinds.size();
151   if (!First[0]->is(Kinds[0]))
152     return false;
153   unsigned AddLength = 0;
154   for (unsigned i = 1; i < Kinds.size(); ++i) {
155     if (!First[i]->is(Kinds[i]) ||
156         First[i]->WhitespaceRange.getBegin() !=
157             First[i]->WhitespaceRange.getEnd())
158       return false;
159     AddLength += First[i]->TokenText.size();
160   }
161   Tokens.resize(Tokens.size() - Kinds.size() + 1);
162   First[0]->TokenText = StringRef(First[0]->TokenText.data(),
163                                   First[0]->TokenText.size() + AddLength);
164   First[0]->ColumnWidth += AddLength;
165   First[0]->Type = NewType;
166   return true;
167 }
168
169 // Returns \c true if \p Tok can only be followed by an operand in JavaScript.
170 bool FormatTokenLexer::precedesOperand(FormatToken *Tok) {
171   // NB: This is not entirely correct, as an r_paren can introduce an operand
172   // location in e.g. `if (foo) /bar/.exec(...);`. That is a rare enough
173   // corner case to not matter in practice, though.
174   return Tok->isOneOf(tok::period, tok::l_paren, tok::comma, tok::l_brace,
175                       tok::r_brace, tok::l_square, tok::semi, tok::exclaim,
176                       tok::colon, tok::question, tok::tilde) ||
177          Tok->isOneOf(tok::kw_return, tok::kw_do, tok::kw_case, tok::kw_throw,
178                       tok::kw_else, tok::kw_new, tok::kw_delete, tok::kw_void,
179                       tok::kw_typeof, Keywords.kw_instanceof, Keywords.kw_in) ||
180          Tok->isBinaryOperator();
181 }
182
183 bool FormatTokenLexer::canPrecedeRegexLiteral(FormatToken *Prev) {
184   if (!Prev)
185     return true;
186
187   // Regex literals can only follow after prefix unary operators, not after
188   // postfix unary operators. If the '++' is followed by a non-operand
189   // introducing token, the slash here is the operand and not the start of a
190   // regex.
191   // `!` is an unary prefix operator, but also a post-fix operator that casts
192   // away nullability, so the same check applies.
193   if (Prev->isOneOf(tok::plusplus, tok::minusminus, tok::exclaim))
194     return (Tokens.size() < 3 || precedesOperand(Tokens[Tokens.size() - 3]));
195
196   // The previous token must introduce an operand location where regex
197   // literals can occur.
198   if (!precedesOperand(Prev))
199     return false;
200
201   return true;
202 }
203
204 // Tries to parse a JavaScript Regex literal starting at the current token,
205 // if that begins with a slash and is in a location where JavaScript allows
206 // regex literals. Changes the current token to a regex literal and updates
207 // its text if successful.
208 void FormatTokenLexer::tryParseJSRegexLiteral() {
209   FormatToken *RegexToken = Tokens.back();
210   if (!RegexToken->isOneOf(tok::slash, tok::slashequal))
211     return;
212
213   FormatToken *Prev = nullptr;
214   for (auto I = Tokens.rbegin() + 1, E = Tokens.rend(); I != E; ++I) {
215     // NB: Because previous pointers are not initialized yet, this cannot use
216     // Token.getPreviousNonComment.
217     if ((*I)->isNot(tok::comment)) {
218       Prev = *I;
219       break;
220     }
221   }
222
223   if (!canPrecedeRegexLiteral(Prev))
224     return;
225
226   // 'Manually' lex ahead in the current file buffer.
227   const char *Offset = Lex->getBufferLocation();
228   const char *RegexBegin = Offset - RegexToken->TokenText.size();
229   StringRef Buffer = Lex->getBuffer();
230   bool InCharacterClass = false;
231   bool HaveClosingSlash = false;
232   for (; !HaveClosingSlash && Offset != Buffer.end(); ++Offset) {
233     // Regular expressions are terminated with a '/', which can only be
234     // escaped using '\' or a character class between '[' and ']'.
235     // See http://www.ecma-international.org/ecma-262/5.1/#sec-7.8.5.
236     switch (*Offset) {
237     case '\\':
238       // Skip the escaped character.
239       ++Offset;
240       break;
241     case '[':
242       InCharacterClass = true;
243       break;
244     case ']':
245       InCharacterClass = false;
246       break;
247     case '/':
248       if (!InCharacterClass)
249         HaveClosingSlash = true;
250       break;
251     }
252   }
253
254   RegexToken->Type = TT_RegexLiteral;
255   // Treat regex literals like other string_literals.
256   RegexToken->Tok.setKind(tok::string_literal);
257   RegexToken->TokenText = StringRef(RegexBegin, Offset - RegexBegin);
258   RegexToken->ColumnWidth = RegexToken->TokenText.size();
259
260   resetLexer(SourceMgr.getFileOffset(Lex->getSourceLocation(Offset)));
261 }
262
263 void FormatTokenLexer::handleTemplateStrings() {
264   FormatToken *BacktickToken = Tokens.back();
265
266   if (BacktickToken->is(tok::l_brace)) {
267     StateStack.push(LexerState::NORMAL);
268     return;
269   }
270   if (BacktickToken->is(tok::r_brace)) {
271     if (StateStack.size() == 1)
272       return;
273     StateStack.pop();
274     if (StateStack.top() != LexerState::TEMPLATE_STRING)
275       return;
276     // If back in TEMPLATE_STRING, fallthrough and continue parsing the
277   } else if (BacktickToken->is(tok::unknown) &&
278              BacktickToken->TokenText == "`") {
279     StateStack.push(LexerState::TEMPLATE_STRING);
280   } else {
281     return; // Not actually a template
282   }
283
284   // 'Manually' lex ahead in the current file buffer.
285   const char *Offset = Lex->getBufferLocation();
286   const char *TmplBegin = Offset - BacktickToken->TokenText.size(); // at "`"
287   for (; Offset != Lex->getBuffer().end(); ++Offset) {
288     if (Offset[0] == '`') {
289       StateStack.pop();
290       break;
291     }
292     if (Offset[0] == '\\') {
293       ++Offset; // Skip the escaped character.
294     } else if (Offset + 1 < Lex->getBuffer().end() && Offset[0] == '$' &&
295                Offset[1] == '{') {
296       // '${' introduces an expression interpolation in the template string.
297       StateStack.push(LexerState::NORMAL);
298       ++Offset;
299       break;
300     }
301   }
302
303   StringRef LiteralText(TmplBegin, Offset - TmplBegin + 1);
304   BacktickToken->Type = TT_TemplateString;
305   BacktickToken->Tok.setKind(tok::string_literal);
306   BacktickToken->TokenText = LiteralText;
307
308   // Adjust width for potentially multiline string literals.
309   size_t FirstBreak = LiteralText.find('\n');
310   StringRef FirstLineText = FirstBreak == StringRef::npos
311                                 ? LiteralText
312                                 : LiteralText.substr(0, FirstBreak);
313   BacktickToken->ColumnWidth = encoding::columnWidthWithTabs(
314       FirstLineText, BacktickToken->OriginalColumn, Style.TabWidth, Encoding);
315   size_t LastBreak = LiteralText.rfind('\n');
316   if (LastBreak != StringRef::npos) {
317     BacktickToken->IsMultiline = true;
318     unsigned StartColumn = 0; // The template tail spans the entire line.
319     BacktickToken->LastLineColumnWidth = encoding::columnWidthWithTabs(
320         LiteralText.substr(LastBreak + 1, LiteralText.size()), StartColumn,
321         Style.TabWidth, Encoding);
322   }
323
324   SourceLocation loc = Offset < Lex->getBuffer().end()
325                            ? Lex->getSourceLocation(Offset + 1)
326                            : SourceMgr.getLocForEndOfFile(ID);
327   resetLexer(SourceMgr.getFileOffset(loc));
328 }
329
330 bool FormatTokenLexer::tryMerge_TMacro() {
331   if (Tokens.size() < 4)
332     return false;
333   FormatToken *Last = Tokens.back();
334   if (!Last->is(tok::r_paren))
335     return false;
336
337   FormatToken *String = Tokens[Tokens.size() - 2];
338   if (!String->is(tok::string_literal) || String->IsMultiline)
339     return false;
340
341   if (!Tokens[Tokens.size() - 3]->is(tok::l_paren))
342     return false;
343
344   FormatToken *Macro = Tokens[Tokens.size() - 4];
345   if (Macro->TokenText != "_T")
346     return false;
347
348   const char *Start = Macro->TokenText.data();
349   const char *End = Last->TokenText.data() + Last->TokenText.size();
350   String->TokenText = StringRef(Start, End - Start);
351   String->IsFirst = Macro->IsFirst;
352   String->LastNewlineOffset = Macro->LastNewlineOffset;
353   String->WhitespaceRange = Macro->WhitespaceRange;
354   String->OriginalColumn = Macro->OriginalColumn;
355   String->ColumnWidth = encoding::columnWidthWithTabs(
356       String->TokenText, String->OriginalColumn, Style.TabWidth, Encoding);
357   String->NewlinesBefore = Macro->NewlinesBefore;
358   String->HasUnescapedNewline = Macro->HasUnescapedNewline;
359
360   Tokens.pop_back();
361   Tokens.pop_back();
362   Tokens.pop_back();
363   Tokens.back() = String;
364   return true;
365 }
366
367 bool FormatTokenLexer::tryMergeConflictMarkers() {
368   if (Tokens.back()->NewlinesBefore == 0 && Tokens.back()->isNot(tok::eof))
369     return false;
370
371   // Conflict lines look like:
372   // <marker> <text from the vcs>
373   // For example:
374   // >>>>>>> /file/in/file/system at revision 1234
375   //
376   // We merge all tokens in a line that starts with a conflict marker
377   // into a single token with a special token type that the unwrapped line
378   // parser will use to correctly rebuild the underlying code.
379
380   FileID ID;
381   // Get the position of the first token in the line.
382   unsigned FirstInLineOffset;
383   std::tie(ID, FirstInLineOffset) = SourceMgr.getDecomposedLoc(
384       Tokens[FirstInLineIndex]->getStartOfNonWhitespace());
385   StringRef Buffer = SourceMgr.getBuffer(ID)->getBuffer();
386   // Calculate the offset of the start of the current line.
387   auto LineOffset = Buffer.rfind('\n', FirstInLineOffset);
388   if (LineOffset == StringRef::npos) {
389     LineOffset = 0;
390   } else {
391     ++LineOffset;
392   }
393
394   auto FirstSpace = Buffer.find_first_of(" \n", LineOffset);
395   StringRef LineStart;
396   if (FirstSpace == StringRef::npos) {
397     LineStart = Buffer.substr(LineOffset);
398   } else {
399     LineStart = Buffer.substr(LineOffset, FirstSpace - LineOffset);
400   }
401
402   TokenType Type = TT_Unknown;
403   if (LineStart == "<<<<<<<" || LineStart == ">>>>") {
404     Type = TT_ConflictStart;
405   } else if (LineStart == "|||||||" || LineStart == "=======" ||
406              LineStart == "====") {
407     Type = TT_ConflictAlternative;
408   } else if (LineStart == ">>>>>>>" || LineStart == "<<<<") {
409     Type = TT_ConflictEnd;
410   }
411
412   if (Type != TT_Unknown) {
413     FormatToken *Next = Tokens.back();
414
415     Tokens.resize(FirstInLineIndex + 1);
416     // We do not need to build a complete token here, as we will skip it
417     // during parsing anyway (as we must not touch whitespace around conflict
418     // markers).
419     Tokens.back()->Type = Type;
420     Tokens.back()->Tok.setKind(tok::kw___unknown_anytype);
421
422     Tokens.push_back(Next);
423     return true;
424   }
425
426   return false;
427 }
428
429 FormatToken *FormatTokenLexer::getStashedToken() {
430   // Create a synthesized second '>' or '<' token.
431   Token Tok = FormatTok->Tok;
432   StringRef TokenText = FormatTok->TokenText;
433
434   unsigned OriginalColumn = FormatTok->OriginalColumn;
435   FormatTok = new (Allocator.Allocate()) FormatToken;
436   FormatTok->Tok = Tok;
437   SourceLocation TokLocation =
438       FormatTok->Tok.getLocation().getLocWithOffset(Tok.getLength() - 1);
439   FormatTok->Tok.setLocation(TokLocation);
440   FormatTok->WhitespaceRange = SourceRange(TokLocation, TokLocation);
441   FormatTok->TokenText = TokenText;
442   FormatTok->ColumnWidth = 1;
443   FormatTok->OriginalColumn = OriginalColumn + 1;
444
445   return FormatTok;
446 }
447
448 FormatToken *FormatTokenLexer::getNextToken() {
449   if (StateStack.top() == LexerState::TOKEN_STASHED) {
450     StateStack.pop();
451     return getStashedToken();
452   }
453
454   FormatTok = new (Allocator.Allocate()) FormatToken;
455   readRawToken(*FormatTok);
456   SourceLocation WhitespaceStart =
457       FormatTok->Tok.getLocation().getLocWithOffset(-TrailingWhitespace);
458   FormatTok->IsFirst = IsFirstToken;
459   IsFirstToken = false;
460
461   // Consume and record whitespace until we find a significant token.
462   unsigned WhitespaceLength = TrailingWhitespace;
463   while (FormatTok->Tok.is(tok::unknown)) {
464     StringRef Text = FormatTok->TokenText;
465     auto EscapesNewline = [&](int pos) {
466       // A '\r' here is just part of '\r\n'. Skip it.
467       if (pos >= 0 && Text[pos] == '\r')
468         --pos;
469       // See whether there is an odd number of '\' before this.
470       unsigned count = 0;
471       for (; pos >= 0; --pos, ++count)
472         if (Text[pos] != '\\')
473           break;
474       return count & 1;
475     };
476     // FIXME: This miscounts tok:unknown tokens that are not just
477     // whitespace, e.g. a '`' character.
478     for (int i = 0, e = Text.size(); i != e; ++i) {
479       switch (Text[i]) {
480       case '\n':
481         ++FormatTok->NewlinesBefore;
482         FormatTok->HasUnescapedNewline = !EscapesNewline(i - 1);
483         FormatTok->LastNewlineOffset = WhitespaceLength + i + 1;
484         Column = 0;
485         break;
486       case '\r':
487         FormatTok->LastNewlineOffset = WhitespaceLength + i + 1;
488         Column = 0;
489         break;
490       case '\f':
491       case '\v':
492         Column = 0;
493         break;
494       case ' ':
495         ++Column;
496         break;
497       case '\t':
498         Column += Style.TabWidth - Column % Style.TabWidth;
499         break;
500       case '\\':
501         if (i + 1 == e || (Text[i + 1] != '\r' && Text[i + 1] != '\n'))
502           FormatTok->Type = TT_ImplicitStringLiteral;
503         break;
504       default:
505         FormatTok->Type = TT_ImplicitStringLiteral;
506         break;
507       }
508       if (FormatTok->Type == TT_ImplicitStringLiteral)
509         break;
510     }
511
512     if (FormatTok->is(TT_ImplicitStringLiteral))
513       break;
514     WhitespaceLength += FormatTok->Tok.getLength();
515
516     readRawToken(*FormatTok);
517   }
518
519   // In case the token starts with escaped newlines, we want to
520   // take them into account as whitespace - this pattern is quite frequent
521   // in macro definitions.
522   // FIXME: Add a more explicit test.
523   while (FormatTok->TokenText.size() > 1 && FormatTok->TokenText[0] == '\\' &&
524          FormatTok->TokenText[1] == '\n') {
525     ++FormatTok->NewlinesBefore;
526     WhitespaceLength += 2;
527     FormatTok->LastNewlineOffset = 2;
528     Column = 0;
529     FormatTok->TokenText = FormatTok->TokenText.substr(2);
530   }
531
532   FormatTok->WhitespaceRange = SourceRange(
533       WhitespaceStart, WhitespaceStart.getLocWithOffset(WhitespaceLength));
534
535   FormatTok->OriginalColumn = Column;
536
537   TrailingWhitespace = 0;
538   if (FormatTok->Tok.is(tok::comment)) {
539     // FIXME: Add the trimmed whitespace to Column.
540     StringRef UntrimmedText = FormatTok->TokenText;
541     FormatTok->TokenText = FormatTok->TokenText.rtrim(" \t\v\f");
542     TrailingWhitespace = UntrimmedText.size() - FormatTok->TokenText.size();
543   } else if (FormatTok->Tok.is(tok::raw_identifier)) {
544     IdentifierInfo &Info = IdentTable.get(FormatTok->TokenText);
545     FormatTok->Tok.setIdentifierInfo(&Info);
546     FormatTok->Tok.setKind(Info.getTokenID());
547     if (Style.Language == FormatStyle::LK_Java &&
548         FormatTok->isOneOf(tok::kw_struct, tok::kw_union, tok::kw_delete,
549                            tok::kw_operator)) {
550       FormatTok->Tok.setKind(tok::identifier);
551       FormatTok->Tok.setIdentifierInfo(nullptr);
552     } else if (Style.Language == FormatStyle::LK_JavaScript &&
553                FormatTok->isOneOf(tok::kw_struct, tok::kw_union,
554                                   tok::kw_operator)) {
555       FormatTok->Tok.setKind(tok::identifier);
556       FormatTok->Tok.setIdentifierInfo(nullptr);
557     }
558   } else if (FormatTok->Tok.is(tok::greatergreater)) {
559     FormatTok->Tok.setKind(tok::greater);
560     FormatTok->TokenText = FormatTok->TokenText.substr(0, 1);
561     ++Column;
562     StateStack.push(LexerState::TOKEN_STASHED);
563   } else if (FormatTok->Tok.is(tok::lessless)) {
564     FormatTok->Tok.setKind(tok::less);
565     FormatTok->TokenText = FormatTok->TokenText.substr(0, 1);
566     ++Column;
567     StateStack.push(LexerState::TOKEN_STASHED);
568   }
569
570   // Now FormatTok is the next non-whitespace token.
571
572   StringRef Text = FormatTok->TokenText;
573   size_t FirstNewlinePos = Text.find('\n');
574   if (FirstNewlinePos == StringRef::npos) {
575     // FIXME: ColumnWidth actually depends on the start column, we need to
576     // take this into account when the token is moved.
577     FormatTok->ColumnWidth =
578         encoding::columnWidthWithTabs(Text, Column, Style.TabWidth, Encoding);
579     Column += FormatTok->ColumnWidth;
580   } else {
581     FormatTok->IsMultiline = true;
582     // FIXME: ColumnWidth actually depends on the start column, we need to
583     // take this into account when the token is moved.
584     FormatTok->ColumnWidth = encoding::columnWidthWithTabs(
585         Text.substr(0, FirstNewlinePos), Column, Style.TabWidth, Encoding);
586
587     // The last line of the token always starts in column 0.
588     // Thus, the length can be precomputed even in the presence of tabs.
589     FormatTok->LastLineColumnWidth = encoding::columnWidthWithTabs(
590         Text.substr(Text.find_last_of('\n') + 1), 0, Style.TabWidth, Encoding);
591     Column = FormatTok->LastLineColumnWidth;
592   }
593
594   if (Style.isCpp()) {
595     if (!(Tokens.size() > 0 && Tokens.back()->Tok.getIdentifierInfo() &&
596           Tokens.back()->Tok.getIdentifierInfo()->getPPKeywordID() ==
597               tok::pp_define) &&
598         std::find(ForEachMacros.begin(), ForEachMacros.end(),
599                   FormatTok->Tok.getIdentifierInfo()) != ForEachMacros.end()) {
600       FormatTok->Type = TT_ForEachMacro;
601     } else if (FormatTok->is(tok::identifier)) {
602       if (MacroBlockBeginRegex.match(Text)) {
603         FormatTok->Type = TT_MacroBlockBegin;
604       } else if (MacroBlockEndRegex.match(Text)) {
605         FormatTok->Type = TT_MacroBlockEnd;
606       }
607     }
608   }
609
610   return FormatTok;
611 }
612
613 void FormatTokenLexer::readRawToken(FormatToken &Tok) {
614   Lex->LexFromRawLexer(Tok.Tok);
615   Tok.TokenText = StringRef(SourceMgr.getCharacterData(Tok.Tok.getLocation()),
616                             Tok.Tok.getLength());
617   // For formatting, treat unterminated string literals like normal string
618   // literals.
619   if (Tok.is(tok::unknown)) {
620     if (!Tok.TokenText.empty() && Tok.TokenText[0] == '"') {
621       Tok.Tok.setKind(tok::string_literal);
622       Tok.IsUnterminatedLiteral = true;
623     } else if (Style.Language == FormatStyle::LK_JavaScript &&
624                Tok.TokenText == "''") {
625       Tok.Tok.setKind(tok::string_literal);
626     }
627   }
628
629   if (Style.Language == FormatStyle::LK_JavaScript &&
630       Tok.is(tok::char_constant)) {
631     Tok.Tok.setKind(tok::string_literal);
632   }
633
634   if (Tok.is(tok::comment) && (Tok.TokenText == "// clang-format on" ||
635                                Tok.TokenText == "/* clang-format on */")) {
636     FormattingDisabled = false;
637   }
638
639   Tok.Finalized = FormattingDisabled;
640
641   if (Tok.is(tok::comment) && (Tok.TokenText == "// clang-format off" ||
642                                Tok.TokenText == "/* clang-format off */")) {
643     FormattingDisabled = true;
644   }
645 }
646
647 void FormatTokenLexer::resetLexer(unsigned Offset) {
648   StringRef Buffer = SourceMgr.getBufferData(ID);
649   Lex.reset(new Lexer(SourceMgr.getLocForStartOfFile(ID),
650                       getFormattingLangOpts(Style), Buffer.begin(),
651                       Buffer.begin() + Offset, Buffer.end()));
652   Lex->SetKeepWhitespaceMode(true);
653   TrailingWhitespace = 0;
654 }
655
656 } // namespace format
657 } // namespace clang