Home | History | Annotate | Download | only in Frontend
      1 //===--- TextDiagnostic.cpp - Text Diagnostic Pretty-Printing -------------===//
      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 #include "clang/Frontend/TextDiagnostic.h"
     11 #include "clang/Basic/FileManager.h"
     12 #include "clang/Basic/SourceManager.h"
     13 #include "clang/Basic/ConvertUTF.h"
     14 #include "clang/Frontend/DiagnosticOptions.h"
     15 #include "clang/Lex/Lexer.h"
     16 #include "llvm/Support/MemoryBuffer.h"
     17 #include "llvm/Support/raw_ostream.h"
     18 #include "llvm/Support/ErrorHandling.h"
     19 #include "llvm/Support/Locale.h"
     20 #include "llvm/ADT/SmallString.h"
     21 #include "llvm/ADT/StringExtras.h"
     22 #include <algorithm>
     23 
     24 using namespace clang;
     25 
     26 static const enum raw_ostream::Colors noteColor =
     27   raw_ostream::BLACK;
     28 static const enum raw_ostream::Colors fixitColor =
     29   raw_ostream::GREEN;
     30 static const enum raw_ostream::Colors caretColor =
     31   raw_ostream::GREEN;
     32 static const enum raw_ostream::Colors warningColor =
     33   raw_ostream::MAGENTA;
     34 static const enum raw_ostream::Colors errorColor = raw_ostream::RED;
     35 static const enum raw_ostream::Colors fatalColor = raw_ostream::RED;
     36 // Used for changing only the bold attribute.
     37 static const enum raw_ostream::Colors savedColor =
     38   raw_ostream::SAVEDCOLOR;
     39 
     40 /// \brief Number of spaces to indent when word-wrapping.
     41 const unsigned WordWrapIndentation = 6;
     42 
     43 int bytesSincePreviousTabOrLineBegin(StringRef SourceLine, size_t i) {
     44   int bytes = 0;
     45   while (0<i) {
     46     if (SourceLine[--i]=='\t')
     47       break;
     48     ++bytes;
     49   }
     50   return bytes;
     51 }
     52 
     53 /// \brief returns a printable representation of first item from input range
     54 ///
     55 /// This function returns a printable representation of the next item in a line
     56 ///  of source. If the next byte begins a valid and printable character, that
     57 ///  character is returned along with 'true'.
     58 ///
     59 /// Otherwise, if the next byte begins a valid, but unprintable character, a
     60 ///  printable, escaped representation of the character is returned, along with
     61 ///  'false'. Otherwise a printable, escaped representation of the next byte
     62 ///  is returned along with 'false'.
     63 ///
     64 /// \note The index is updated to be used with a subsequent call to
     65 ///        printableTextForNextCharacter.
     66 ///
     67 /// \param SourceLine The line of source
     68 /// \param i Pointer to byte index,
     69 /// \param TabStop used to expand tabs
     70 /// \return pair(printable text, 'true' iff original text was printable)
     71 ///
     72 std::pair<SmallString<16>,bool>
     73 printableTextForNextCharacter(StringRef SourceLine, size_t *i,
     74                               unsigned TabStop) {
     75   assert(i && "i must not be null");
     76   assert(*i<SourceLine.size() && "must point to a valid index");
     77 
     78   if (SourceLine[*i]=='\t') {
     79     assert(0 < TabStop && TabStop <= DiagnosticOptions::MaxTabStop &&
     80            "Invalid -ftabstop value");
     81     unsigned col = bytesSincePreviousTabOrLineBegin(SourceLine, *i);
     82     unsigned NumSpaces = TabStop - col%TabStop;
     83     assert(0 < NumSpaces && NumSpaces <= TabStop
     84            && "Invalid computation of space amt");
     85     ++(*i);
     86 
     87     SmallString<16> expandedTab;
     88     expandedTab.assign(NumSpaces, ' ');
     89     return std::make_pair(expandedTab, true);
     90   }
     91 
     92   // FIXME: this data is copied from the private implementation of ConvertUTF.h
     93   static const char trailingBytesForUTF8[256] = {
     94     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
     95     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
     96     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
     97     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
     98     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
     99     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    100     1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    101     2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
    102   };
    103 
    104   unsigned char const *begin, *end;
    105   begin = reinterpret_cast<unsigned char const *>(&*(SourceLine.begin() + *i));
    106   end = begin + SourceLine.size();
    107 
    108   if (isLegalUTF8Sequence(begin, end)) {
    109     UTF32 c;
    110     UTF32 *cptr = &c;
    111     unsigned char const *original_begin = begin;
    112     char trailingBytes = trailingBytesForUTF8[(unsigned char)SourceLine[*i]];
    113     unsigned char const *cp_end = begin+trailingBytes+1;
    114 
    115     ConversionResult res = ConvertUTF8toUTF32(&begin, cp_end, &cptr, cptr+1,
    116                                               strictConversion);
    117     (void)res;
    118     assert(conversionOK==res);
    119     assert(0 < begin-original_begin
    120            && "we must be further along in the string now");
    121     *i += begin-original_begin;
    122 
    123     if (!llvm::sys::locale::isPrint(c)) {
    124       // If next character is valid UTF-8, but not printable
    125       SmallString<16> expandedCP("<U+>");
    126       while (c) {
    127         expandedCP.insert(expandedCP.begin()+3, llvm::hexdigit(c%16));
    128         c/=16;
    129       }
    130       while (expandedCP.size() < 8)
    131         expandedCP.insert(expandedCP.begin()+3, llvm::hexdigit(0));
    132       return std::make_pair(expandedCP, false);
    133     }
    134 
    135     // If next character is valid UTF-8, and printable
    136     return std::make_pair(SmallString<16>(original_begin, cp_end), true);
    137 
    138   }
    139 
    140   // If next byte is not valid UTF-8 (and therefore not printable)
    141   SmallString<16> expandedByte("<XX>");
    142   unsigned char byte = SourceLine[*i];
    143   expandedByte[1] = llvm::hexdigit(byte / 16);
    144   expandedByte[2] = llvm::hexdigit(byte % 16);
    145   ++(*i);
    146   return std::make_pair(expandedByte, false);
    147 }
    148 
    149 void expandTabs(std::string &SourceLine, unsigned TabStop) {
    150   size_t i = SourceLine.size();
    151   while (i>0) {
    152     i--;
    153     if (SourceLine[i]!='\t')
    154       continue;
    155     size_t tmp_i = i;
    156     std::pair<SmallString<16>,bool> res
    157       = printableTextForNextCharacter(SourceLine, &tmp_i, TabStop);
    158     SourceLine.replace(i, 1, res.first.c_str());
    159   }
    160 }
    161 
    162 /// This function takes a raw source line and produces a mapping from the bytes
    163 ///  of the printable representation of the line to the columns those printable
    164 ///  characters will appear at (numbering the first column as 0).
    165 ///
    166 /// If a byte 'i' corresponds to muliple columns (e.g. the byte contains a tab
    167 ///  character) then the the array will map that byte to the first column the
    168 ///  tab appears at and the next value in the map will have been incremented
    169 ///  more than once.
    170 ///
    171 /// If a byte is the first in a sequence of bytes that together map to a single
    172 ///  entity in the output, then the array will map that byte to the appropriate
    173 ///  column while the subsequent bytes will be -1.
    174 ///
    175 /// The last element in the array does not correspond to any byte in the input
    176 ///  and instead is the number of columns needed to display the source
    177 ///
    178 /// example: (given a tabstop of 8)
    179 ///
    180 ///    "a \t \u3042" -> {0,1,2,8,9,-1,-1,11}
    181 ///
    182 ///  (\u3042 is represented in UTF-8 by three bytes and takes two columns to
    183 ///   display)
    184 void byteToColumn(StringRef SourceLine, unsigned TabStop,
    185                          SmallVectorImpl<int> &out) {
    186   out.clear();
    187 
    188   if (SourceLine.empty()) {
    189     out.resize(1u,0);
    190     return;
    191   }
    192 
    193   out.resize(SourceLine.size()+1, -1);
    194 
    195   int columns = 0;
    196   size_t i = 0;
    197   while (i<SourceLine.size()) {
    198     out[i] = columns;
    199     std::pair<SmallString<16>,bool> res
    200       = printableTextForNextCharacter(SourceLine, &i, TabStop);
    201     columns += llvm::sys::locale::columnWidth(res.first);
    202   }
    203   out.back() = columns;
    204 }
    205 
    206 /// This function takes a raw source line and produces a mapping from columns
    207 ///  to the byte of the source line that produced the character displaying at
    208 ///  that column. This is the inverse of the mapping produced by byteToColumn()
    209 ///
    210 /// The last element in the array is the number of bytes in the source string
    211 ///
    212 /// example: (given a tabstop of 8)
    213 ///
    214 ///    "a \t \u3042" -> {0,1,2,-1,-1,-1,-1,-1,3,4,-1,7}
    215 ///
    216 ///  (\u3042 is represented in UTF-8 by three bytes and takes two columns to
    217 ///   display)
    218 void columnToByte(StringRef SourceLine, unsigned TabStop,
    219                          SmallVectorImpl<int> &out) {
    220   out.clear();
    221 
    222   if (SourceLine.empty()) {
    223     out.resize(1u, 0);
    224     return;
    225   }
    226 
    227   int columns = 0;
    228   size_t i = 0;
    229   while (i<SourceLine.size()) {
    230     out.resize(columns+1, -1);
    231     out.back() = i;
    232     std::pair<SmallString<16>,bool> res
    233       = printableTextForNextCharacter(SourceLine, &i, TabStop);
    234     columns += llvm::sys::locale::columnWidth(res.first);
    235   }
    236   out.resize(columns+1, -1);
    237   out.back() = i;
    238 }
    239 
    240 struct SourceColumnMap {
    241   SourceColumnMap(StringRef SourceLine, unsigned TabStop)
    242   : m_SourceLine(SourceLine) {
    243 
    244     ::byteToColumn(SourceLine, TabStop, m_byteToColumn);
    245     ::columnToByte(SourceLine, TabStop, m_columnToByte);
    246 
    247     assert(m_byteToColumn.size()==SourceLine.size()+1);
    248     assert(0 < m_byteToColumn.size() && 0 < m_columnToByte.size());
    249     assert(m_byteToColumn.size()
    250            == static_cast<unsigned>(m_columnToByte.back()+1));
    251     assert(static_cast<unsigned>(m_byteToColumn.back()+1)
    252            == m_columnToByte.size());
    253   }
    254   int columns() const { return m_byteToColumn.back(); }
    255   int bytes() const { return m_columnToByte.back(); }
    256   int byteToColumn(int n) const {
    257     assert(0<=n && n<static_cast<int>(m_byteToColumn.size()));
    258     return m_byteToColumn[n];
    259   }
    260   int columnToByte(int n) const {
    261     assert(0<=n && n<static_cast<int>(m_columnToByte.size()));
    262     return m_columnToByte[n];
    263   }
    264   StringRef getSourceLine() const {
    265     return m_SourceLine;
    266   }
    267 
    268 private:
    269   const std::string m_SourceLine;
    270   SmallVector<int,200> m_byteToColumn;
    271   SmallVector<int,200> m_columnToByte;
    272 };
    273 
    274 // used in assert in selectInterestingSourceRegion()
    275 namespace {
    276 struct char_out_of_range {
    277   const char lower,upper;
    278   char_out_of_range(char lower, char upper) :
    279     lower(lower), upper(upper) {}
    280   bool operator()(char c) { return c < lower || upper < c; }
    281 };
    282 }
    283 
    284 /// \brief When the source code line we want to print is too long for
    285 /// the terminal, select the "interesting" region.
    286 static void selectInterestingSourceRegion(std::string &SourceLine,
    287                                           std::string &CaretLine,
    288                                           std::string &FixItInsertionLine,
    289                                           unsigned Columns,
    290                                           const SourceColumnMap &map) {
    291   unsigned MaxColumns = std::max<unsigned>(map.columns(),
    292                                            std::max(CaretLine.size(),
    293                                                     FixItInsertionLine.size()));
    294   // if the number of columns is less than the desired number we're done
    295   if (MaxColumns <= Columns)
    296     return;
    297 
    298   // no special characters allowed in CaretLine or FixItInsertionLine
    299   assert(CaretLine.end() ==
    300          std::find_if(CaretLine.begin(), CaretLine.end(),
    301          char_out_of_range(' ','~')));
    302   assert(FixItInsertionLine.end() ==
    303          std::find_if(FixItInsertionLine.begin(), FixItInsertionLine.end(),
    304          char_out_of_range(' ','~')));
    305 
    306   // Find the slice that we need to display the full caret line
    307   // correctly.
    308   unsigned CaretStart = 0, CaretEnd = CaretLine.size();
    309   for (; CaretStart != CaretEnd; ++CaretStart)
    310     if (!isspace(CaretLine[CaretStart]))
    311       break;
    312 
    313   for (; CaretEnd != CaretStart; --CaretEnd)
    314     if (!isspace(CaretLine[CaretEnd - 1]))
    315       break;
    316 
    317   // caret has already been inserted into CaretLine so the above whitespace
    318   // check is guaranteed to include the caret
    319 
    320   // If we have a fix-it line, make sure the slice includes all of the
    321   // fix-it information.
    322   if (!FixItInsertionLine.empty()) {
    323     unsigned FixItStart = 0, FixItEnd = FixItInsertionLine.size();
    324     for (; FixItStart != FixItEnd; ++FixItStart)
    325       if (!isspace(FixItInsertionLine[FixItStart]))
    326         break;
    327 
    328     for (; FixItEnd != FixItStart; --FixItEnd)
    329       if (!isspace(FixItInsertionLine[FixItEnd - 1]))
    330         break;
    331 
    332     CaretStart = std::min(FixItStart, CaretStart);
    333     CaretEnd = std::max(FixItEnd, CaretEnd);
    334   }
    335 
    336   // CaretLine[CaretStart, CaretEnd) contains all of the interesting
    337   // parts of the caret line. While this slice is smaller than the
    338   // number of columns we have, try to grow the slice to encompass
    339   // more context.
    340 
    341   unsigned SourceStart = map.columnToByte(std::min<unsigned>(CaretStart,
    342                                                              map.columns()));
    343   unsigned SourceEnd = map.columnToByte(std::min<unsigned>(CaretEnd,
    344                                                            map.columns()));
    345 
    346   unsigned CaretColumnsOutsideSource = CaretEnd-CaretStart
    347     - (map.byteToColumn(SourceEnd)-map.byteToColumn(SourceStart));
    348 
    349   char const *front_ellipse = "  ...";
    350   char const *front_space   = "     ";
    351   char const *back_ellipse = "...";
    352   unsigned ellipses_space = strlen(front_ellipse) + strlen(back_ellipse);
    353 
    354   unsigned TargetColumns = Columns;
    355   // Give us extra room for the ellipses
    356   //  and any of the caret line that extends past the source
    357   if (TargetColumns > ellipses_space+CaretColumnsOutsideSource)
    358     TargetColumns -= ellipses_space+CaretColumnsOutsideSource;
    359 
    360   while (SourceStart>0 || SourceEnd<SourceLine.size()) {
    361     bool ExpandedRegion = false;
    362 
    363     if (SourceStart>0) {
    364       unsigned NewStart = SourceStart-1;
    365 
    366       // Skip over any whitespace we see here; we're looking for
    367       // another bit of interesting text.
    368       while (NewStart &&
    369              (map.byteToColumn(NewStart)==-1 || isspace(SourceLine[NewStart])))
    370         --NewStart;
    371 
    372       // Skip over this bit of "interesting" text.
    373       while (NewStart &&
    374              (map.byteToColumn(NewStart)!=-1 && !isspace(SourceLine[NewStart])))
    375         --NewStart;
    376 
    377       // Move up to the non-whitespace character we just saw.
    378       if (NewStart)
    379         ++NewStart;
    380 
    381       unsigned NewColumns = map.byteToColumn(SourceEnd) -
    382                               map.byteToColumn(NewStart);
    383       if (NewColumns <= TargetColumns) {
    384         SourceStart = NewStart;
    385         ExpandedRegion = true;
    386       }
    387     }
    388 
    389     if (SourceEnd<SourceLine.size()) {
    390       unsigned NewEnd = SourceEnd+1;
    391 
    392       // Skip over any whitespace we see here; we're looking for
    393       // another bit of interesting text.
    394       while (NewEnd<SourceLine.size() &&
    395              (map.byteToColumn(NewEnd)==-1 || isspace(SourceLine[NewEnd])))
    396         ++NewEnd;
    397 
    398       // Skip over this bit of "interesting" text.
    399       while (NewEnd<SourceLine.size() &&
    400              (map.byteToColumn(NewEnd)!=-1 && !isspace(SourceLine[NewEnd])))
    401         ++NewEnd;
    402 
    403       unsigned NewColumns = map.byteToColumn(NewEnd) -
    404                               map.byteToColumn(SourceStart);
    405       if (NewColumns <= TargetColumns) {
    406         SourceEnd = NewEnd;
    407         ExpandedRegion = true;
    408       }
    409     }
    410 
    411     if (!ExpandedRegion)
    412       break;
    413   }
    414 
    415   CaretStart = map.byteToColumn(SourceStart);
    416   CaretEnd = map.byteToColumn(SourceEnd) + CaretColumnsOutsideSource;
    417 
    418   // [CaretStart, CaretEnd) is the slice we want. Update the various
    419   // output lines to show only this slice, with two-space padding
    420   // before the lines so that it looks nicer.
    421 
    422   assert(CaretStart!=(unsigned)-1 && CaretEnd!=(unsigned)-1 &&
    423          SourceStart!=(unsigned)-1 && SourceEnd!=(unsigned)-1);
    424   assert(SourceStart <= SourceEnd);
    425   assert(CaretStart <= CaretEnd);
    426 
    427   unsigned BackColumnsRemoved
    428     = map.byteToColumn(SourceLine.size())-map.byteToColumn(SourceEnd);
    429   unsigned FrontColumnsRemoved = CaretStart;
    430   unsigned ColumnsKept = CaretEnd-CaretStart;
    431 
    432   // We checked up front that the line needed truncation
    433   assert(FrontColumnsRemoved+ColumnsKept+BackColumnsRemoved > Columns);
    434 
    435   // The line needs some trunctiona, and we'd prefer to keep the front
    436   //  if possible, so remove the back
    437   if (BackColumnsRemoved)
    438     SourceLine.replace(SourceEnd, std::string::npos, back_ellipse);
    439 
    440   // If that's enough then we're done
    441   if (FrontColumnsRemoved+ColumnsKept <= Columns)
    442     return;
    443 
    444   // Otherwise remove the front as well
    445   if (FrontColumnsRemoved) {
    446     SourceLine.replace(0, SourceStart, front_ellipse);
    447     CaretLine.replace(0, CaretStart, front_space);
    448     if (!FixItInsertionLine.empty())
    449       FixItInsertionLine.replace(0, CaretStart, front_space);
    450   }
    451 }
    452 
    453 /// \brief Skip over whitespace in the string, starting at the given
    454 /// index.
    455 ///
    456 /// \returns The index of the first non-whitespace character that is
    457 /// greater than or equal to Idx or, if no such character exists,
    458 /// returns the end of the string.
    459 static unsigned skipWhitespace(unsigned Idx, StringRef Str, unsigned Length) {
    460   while (Idx < Length && isspace(Str[Idx]))
    461     ++Idx;
    462   return Idx;
    463 }
    464 
    465 /// \brief If the given character is the start of some kind of
    466 /// balanced punctuation (e.g., quotes or parentheses), return the
    467 /// character that will terminate the punctuation.
    468 ///
    469 /// \returns The ending punctuation character, if any, or the NULL
    470 /// character if the input character does not start any punctuation.
    471 static inline char findMatchingPunctuation(char c) {
    472   switch (c) {
    473   case '\'': return '\'';
    474   case '`': return '\'';
    475   case '"':  return '"';
    476   case '(':  return ')';
    477   case '[': return ']';
    478   case '{': return '}';
    479   default: break;
    480   }
    481 
    482   return 0;
    483 }
    484 
    485 /// \brief Find the end of the word starting at the given offset
    486 /// within a string.
    487 ///
    488 /// \returns the index pointing one character past the end of the
    489 /// word.
    490 static unsigned findEndOfWord(unsigned Start, StringRef Str,
    491                               unsigned Length, unsigned Column,
    492                               unsigned Columns) {
    493   assert(Start < Str.size() && "Invalid start position!");
    494   unsigned End = Start + 1;
    495 
    496   // If we are already at the end of the string, take that as the word.
    497   if (End == Str.size())
    498     return End;
    499 
    500   // Determine if the start of the string is actually opening
    501   // punctuation, e.g., a quote or parentheses.
    502   char EndPunct = findMatchingPunctuation(Str[Start]);
    503   if (!EndPunct) {
    504     // This is a normal word. Just find the first space character.
    505     while (End < Length && !isspace(Str[End]))
    506       ++End;
    507     return End;
    508   }
    509 
    510   // We have the start of a balanced punctuation sequence (quotes,
    511   // parentheses, etc.). Determine the full sequence is.
    512   SmallString<16> PunctuationEndStack;
    513   PunctuationEndStack.push_back(EndPunct);
    514   while (End < Length && !PunctuationEndStack.empty()) {
    515     if (Str[End] == PunctuationEndStack.back())
    516       PunctuationEndStack.pop_back();
    517     else if (char SubEndPunct = findMatchingPunctuation(Str[End]))
    518       PunctuationEndStack.push_back(SubEndPunct);
    519 
    520     ++End;
    521   }
    522 
    523   // Find the first space character after the punctuation ended.
    524   while (End < Length && !isspace(Str[End]))
    525     ++End;
    526 
    527   unsigned PunctWordLength = End - Start;
    528   if (// If the word fits on this line
    529       Column + PunctWordLength <= Columns ||
    530       // ... or the word is "short enough" to take up the next line
    531       // without too much ugly white space
    532       PunctWordLength < Columns/3)
    533     return End; // Take the whole thing as a single "word".
    534 
    535   // The whole quoted/parenthesized string is too long to print as a
    536   // single "word". Instead, find the "word" that starts just after
    537   // the punctuation and use that end-point instead. This will recurse
    538   // until it finds something small enough to consider a word.
    539   return findEndOfWord(Start + 1, Str, Length, Column + 1, Columns);
    540 }
    541 
    542 /// \brief Print the given string to a stream, word-wrapping it to
    543 /// some number of columns in the process.
    544 ///
    545 /// \param OS the stream to which the word-wrapping string will be
    546 /// emitted.
    547 /// \param Str the string to word-wrap and output.
    548 /// \param Columns the number of columns to word-wrap to.
    549 /// \param Column the column number at which the first character of \p
    550 /// Str will be printed. This will be non-zero when part of the first
    551 /// line has already been printed.
    552 /// \param Indentation the number of spaces to indent any lines beyond
    553 /// the first line.
    554 /// \returns true if word-wrapping was required, or false if the
    555 /// string fit on the first line.
    556 static bool printWordWrapped(raw_ostream &OS, StringRef Str,
    557                              unsigned Columns,
    558                              unsigned Column = 0,
    559                              unsigned Indentation = WordWrapIndentation) {
    560   const unsigned Length = std::min(Str.find('\n'), Str.size());
    561 
    562   // The string used to indent each line.
    563   SmallString<16> IndentStr;
    564   IndentStr.assign(Indentation, ' ');
    565   bool Wrapped = false;
    566   for (unsigned WordStart = 0, WordEnd; WordStart < Length;
    567        WordStart = WordEnd) {
    568     // Find the beginning of the next word.
    569     WordStart = skipWhitespace(WordStart, Str, Length);
    570     if (WordStart == Length)
    571       break;
    572 
    573     // Find the end of this word.
    574     WordEnd = findEndOfWord(WordStart, Str, Length, Column, Columns);
    575 
    576     // Does this word fit on the current line?
    577     unsigned WordLength = WordEnd - WordStart;
    578     if (Column + WordLength < Columns) {
    579       // This word fits on the current line; print it there.
    580       if (WordStart) {
    581         OS << ' ';
    582         Column += 1;
    583       }
    584       OS << Str.substr(WordStart, WordLength);
    585       Column += WordLength;
    586       continue;
    587     }
    588 
    589     // This word does not fit on the current line, so wrap to the next
    590     // line.
    591     OS << '\n';
    592     OS.write(&IndentStr[0], Indentation);
    593     OS << Str.substr(WordStart, WordLength);
    594     Column = Indentation + WordLength;
    595     Wrapped = true;
    596   }
    597 
    598   // Append any remaning text from the message with its existing formatting.
    599   OS << Str.substr(Length);
    600 
    601   return Wrapped;
    602 }
    603 
    604 TextDiagnostic::TextDiagnostic(raw_ostream &OS,
    605                                const SourceManager &SM,
    606                                const LangOptions &LangOpts,
    607                                const DiagnosticOptions &DiagOpts)
    608   : DiagnosticRenderer(SM, LangOpts, DiagOpts), OS(OS) {}
    609 
    610 TextDiagnostic::~TextDiagnostic() {}
    611 
    612 void
    613 TextDiagnostic::emitDiagnosticMessage(SourceLocation Loc,
    614                                       PresumedLoc PLoc,
    615                                       DiagnosticsEngine::Level Level,
    616                                       StringRef Message,
    617                                       ArrayRef<clang::CharSourceRange> Ranges,
    618                                       DiagOrStoredDiag D) {
    619   uint64_t StartOfLocationInfo = OS.tell();
    620 
    621   // Emit the location of this particular diagnostic.
    622   emitDiagnosticLoc(Loc, PLoc, Level, Ranges);
    623 
    624   if (DiagOpts.ShowColors)
    625     OS.resetColor();
    626 
    627   printDiagnosticLevel(OS, Level, DiagOpts.ShowColors);
    628   printDiagnosticMessage(OS, Level, Message,
    629                          OS.tell() - StartOfLocationInfo,
    630                          DiagOpts.MessageLength, DiagOpts.ShowColors);
    631 }
    632 
    633 /*static*/ void
    634 TextDiagnostic::printDiagnosticLevel(raw_ostream &OS,
    635                                      DiagnosticsEngine::Level Level,
    636                                      bool ShowColors) {
    637   if (ShowColors) {
    638     // Print diagnostic category in bold and color
    639     switch (Level) {
    640     case DiagnosticsEngine::Ignored:
    641       llvm_unreachable("Invalid diagnostic type");
    642     case DiagnosticsEngine::Note:    OS.changeColor(noteColor, true); break;
    643     case DiagnosticsEngine::Warning: OS.changeColor(warningColor, true); break;
    644     case DiagnosticsEngine::Error:   OS.changeColor(errorColor, true); break;
    645     case DiagnosticsEngine::Fatal:   OS.changeColor(fatalColor, true); break;
    646     }
    647   }
    648 
    649   switch (Level) {
    650   case DiagnosticsEngine::Ignored:
    651     llvm_unreachable("Invalid diagnostic type");
    652   case DiagnosticsEngine::Note:    OS << "note: "; break;
    653   case DiagnosticsEngine::Warning: OS << "warning: "; break;
    654   case DiagnosticsEngine::Error:   OS << "error: "; break;
    655   case DiagnosticsEngine::Fatal:   OS << "fatal error: "; break;
    656   }
    657 
    658   if (ShowColors)
    659     OS.resetColor();
    660 }
    661 
    662 /*static*/ void
    663 TextDiagnostic::printDiagnosticMessage(raw_ostream &OS,
    664                                        DiagnosticsEngine::Level Level,
    665                                        StringRef Message,
    666                                        unsigned CurrentColumn, unsigned Columns,
    667                                        bool ShowColors) {
    668   if (ShowColors) {
    669     // Print warnings, errors and fatal errors in bold, no color
    670     switch (Level) {
    671     case DiagnosticsEngine::Warning: OS.changeColor(savedColor, true); break;
    672     case DiagnosticsEngine::Error:   OS.changeColor(savedColor, true); break;
    673     case DiagnosticsEngine::Fatal:   OS.changeColor(savedColor, true); break;
    674     default: break; //don't bold notes
    675     }
    676   }
    677 
    678   if (Columns)
    679     printWordWrapped(OS, Message, Columns, CurrentColumn);
    680   else
    681     OS << Message;
    682 
    683   if (ShowColors)
    684     OS.resetColor();
    685   OS << '\n';
    686 }
    687 
    688 /// \brief Print out the file/line/column information and include trace.
    689 ///
    690 /// This method handlen the emission of the diagnostic location information.
    691 /// This includes extracting as much location information as is present for
    692 /// the diagnostic and printing it, as well as any include stack or source
    693 /// ranges necessary.
    694 void TextDiagnostic::emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
    695                                        DiagnosticsEngine::Level Level,
    696                                        ArrayRef<CharSourceRange> Ranges) {
    697   if (PLoc.isInvalid()) {
    698     // At least print the file name if available:
    699     FileID FID = SM.getFileID(Loc);
    700     if (!FID.isInvalid()) {
    701       const FileEntry* FE = SM.getFileEntryForID(FID);
    702       if (FE && FE->getName()) {
    703         OS << FE->getName();
    704         if (FE->getDevice() == 0 && FE->getInode() == 0
    705             && FE->getFileMode() == 0) {
    706           // in PCH is a guess, but a good one:
    707           OS << " (in PCH)";
    708         }
    709         OS << ": ";
    710       }
    711     }
    712     return;
    713   }
    714   unsigned LineNo = PLoc.getLine();
    715 
    716   if (!DiagOpts.ShowLocation)
    717     return;
    718 
    719   if (DiagOpts.ShowColors)
    720     OS.changeColor(savedColor, true);
    721 
    722   OS << PLoc.getFilename();
    723   switch (DiagOpts.Format) {
    724   case DiagnosticOptions::Clang: OS << ':'  << LineNo; break;
    725   case DiagnosticOptions::Msvc:  OS << '('  << LineNo; break;
    726   case DiagnosticOptions::Vi:    OS << " +" << LineNo; break;
    727   }
    728 
    729   if (DiagOpts.ShowColumn)
    730     // Compute the column number.
    731     if (unsigned ColNo = PLoc.getColumn()) {
    732       if (DiagOpts.Format == DiagnosticOptions::Msvc) {
    733         OS << ',';
    734         ColNo--;
    735       } else
    736         OS << ':';
    737       OS << ColNo;
    738     }
    739   switch (DiagOpts.Format) {
    740   case DiagnosticOptions::Clang:
    741   case DiagnosticOptions::Vi:    OS << ':';    break;
    742   case DiagnosticOptions::Msvc:  OS << ") : "; break;
    743   }
    744 
    745   if (DiagOpts.ShowSourceRanges && !Ranges.empty()) {
    746     FileID CaretFileID =
    747       SM.getFileID(SM.getExpansionLoc(Loc));
    748     bool PrintedRange = false;
    749 
    750     for (ArrayRef<CharSourceRange>::const_iterator RI = Ranges.begin(),
    751          RE = Ranges.end();
    752          RI != RE; ++RI) {
    753       // Ignore invalid ranges.
    754       if (!RI->isValid()) continue;
    755 
    756       SourceLocation B = SM.getExpansionLoc(RI->getBegin());
    757       SourceLocation E = SM.getExpansionLoc(RI->getEnd());
    758 
    759       // If the End location and the start location are the same and are a
    760       // macro location, then the range was something that came from a
    761       // macro expansion or _Pragma.  If this is an object-like macro, the
    762       // best we can do is to highlight the range.  If this is a
    763       // function-like macro, we'd also like to highlight the arguments.
    764       if (B == E && RI->getEnd().isMacroID())
    765         E = SM.getExpansionRange(RI->getEnd()).second;
    766 
    767       std::pair<FileID, unsigned> BInfo = SM.getDecomposedLoc(B);
    768       std::pair<FileID, unsigned> EInfo = SM.getDecomposedLoc(E);
    769 
    770       // If the start or end of the range is in another file, just discard
    771       // it.
    772       if (BInfo.first != CaretFileID || EInfo.first != CaretFileID)
    773         continue;
    774 
    775       // Add in the length of the token, so that we cover multi-char
    776       // tokens.
    777       unsigned TokSize = 0;
    778       if (RI->isTokenRange())
    779         TokSize = Lexer::MeasureTokenLength(E, SM, LangOpts);
    780 
    781       OS << '{' << SM.getLineNumber(BInfo.first, BInfo.second) << ':'
    782         << SM.getColumnNumber(BInfo.first, BInfo.second) << '-'
    783         << SM.getLineNumber(EInfo.first, EInfo.second) << ':'
    784         << (SM.getColumnNumber(EInfo.first, EInfo.second)+TokSize)
    785         << '}';
    786       PrintedRange = true;
    787     }
    788 
    789     if (PrintedRange)
    790       OS << ':';
    791   }
    792   OS << ' ';
    793 }
    794 
    795 void TextDiagnostic::emitBasicNote(StringRef Message) {
    796   // FIXME: Emit this as a real note diagnostic.
    797   // FIXME: Format an actual diagnostic rather than a hard coded string.
    798   OS << "note: " << Message << "\n";
    799 }
    800 
    801 void TextDiagnostic::emitIncludeLocation(SourceLocation Loc,
    802                                          PresumedLoc PLoc) {
    803   if (DiagOpts.ShowLocation)
    804     OS << "In file included from " << PLoc.getFilename() << ':'
    805        << PLoc.getLine() << ":\n";
    806   else
    807     OS << "In included file:\n";
    808 }
    809 
    810 /// \brief Emit a code snippet and caret line.
    811 ///
    812 /// This routine emits a single line's code snippet and caret line..
    813 ///
    814 /// \param Loc The location for the caret.
    815 /// \param Ranges The underlined ranges for this code snippet.
    816 /// \param Hints The FixIt hints active for this diagnostic.
    817 void TextDiagnostic::emitSnippetAndCaret(
    818     SourceLocation Loc, DiagnosticsEngine::Level Level,
    819     SmallVectorImpl<CharSourceRange>& Ranges,
    820     ArrayRef<FixItHint> Hints) {
    821   assert(!Loc.isInvalid() && "must have a valid source location here");
    822   assert(Loc.isFileID() && "must have a file location here");
    823 
    824   // If caret diagnostics are enabled and we have location, we want to
    825   // emit the caret.  However, we only do this if the location moved
    826   // from the last diagnostic, if the last diagnostic was a note that
    827   // was part of a different warning or error diagnostic, or if the
    828   // diagnostic has ranges.  We don't want to emit the same caret
    829   // multiple times if one loc has multiple diagnostics.
    830   if (!DiagOpts.ShowCarets)
    831     return;
    832   if (Loc == LastLoc && Ranges.empty() && Hints.empty() &&
    833       (LastLevel != DiagnosticsEngine::Note || Level == LastLevel))
    834     return;
    835 
    836   // Decompose the location into a FID/Offset pair.
    837   std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
    838   FileID FID = LocInfo.first;
    839   unsigned FileOffset = LocInfo.second;
    840 
    841   // Get information about the buffer it points into.
    842   bool Invalid = false;
    843   StringRef BufData = SM.getBufferData(FID, &Invalid);
    844   if (Invalid)
    845     return;
    846 
    847   const char *BufStart = BufData.data();
    848   const char *BufEnd = BufStart + BufData.size();
    849 
    850   unsigned LineNo = SM.getLineNumber(FID, FileOffset);
    851   unsigned ColNo = SM.getColumnNumber(FID, FileOffset);
    852   unsigned CaretEndColNo
    853     = ColNo + Lexer::MeasureTokenLength(Loc, SM, LangOpts);
    854 
    855   // Rewind from the current position to the start of the line.
    856   const char *TokPtr = BufStart+FileOffset;
    857   const char *LineStart = TokPtr-ColNo+1; // Column # is 1-based.
    858 
    859 
    860   // Compute the line end.  Scan forward from the error position to the end of
    861   // the line.
    862   const char *LineEnd = TokPtr;
    863   while (*LineEnd != '\n' && *LineEnd != '\r' && LineEnd!=BufEnd)
    864     ++LineEnd;
    865 
    866   // FIXME: This shouldn't be necessary, but the CaretEndColNo can extend past
    867   // the source line length as currently being computed. See
    868   // test/Misc/message-length.c.
    869   CaretEndColNo = std::min(CaretEndColNo, unsigned(LineEnd - LineStart));
    870 
    871   // Copy the line of code into an std::string for ease of manipulation.
    872   std::string SourceLine(LineStart, LineEnd);
    873 
    874   // Create a line for the caret that is filled with spaces that is the same
    875   // length as the line of source code.
    876   std::string CaretLine(LineEnd-LineStart, ' ');
    877 
    878   const SourceColumnMap sourceColMap(SourceLine, DiagOpts.TabStop);
    879 
    880   // Highlight all of the characters covered by Ranges with ~ characters.
    881   for (SmallVectorImpl<CharSourceRange>::iterator I = Ranges.begin(),
    882                                                   E = Ranges.end();
    883        I != E; ++I)
    884     highlightRange(*I, LineNo, FID, sourceColMap, CaretLine);
    885 
    886   // Next, insert the caret itself.
    887   ColNo = sourceColMap.byteToColumn(ColNo-1);
    888   if (CaretLine.size()<ColNo+1)
    889     CaretLine.resize(ColNo+1, ' ');
    890   CaretLine[ColNo] = '^';
    891 
    892   std::string FixItInsertionLine = buildFixItInsertionLine(LineNo,
    893                                                            sourceColMap,
    894                                                            Hints);
    895 
    896   // If the source line is too long for our terminal, select only the
    897   // "interesting" source region within that line.
    898   unsigned Columns = DiagOpts.MessageLength;
    899   if (Columns)
    900     selectInterestingSourceRegion(SourceLine, CaretLine, FixItInsertionLine,
    901                                   Columns, sourceColMap);
    902 
    903   // If we are in -fdiagnostics-print-source-range-info mode, we are trying
    904   // to produce easily machine parsable output.  Add a space before the
    905   // source line and the caret to make it trivial to tell the main diagnostic
    906   // line from what the user is intended to see.
    907   if (DiagOpts.ShowSourceRanges) {
    908     SourceLine = ' ' + SourceLine;
    909     CaretLine = ' ' + CaretLine;
    910   }
    911 
    912   // Finally, remove any blank spaces from the end of CaretLine.
    913   while (CaretLine[CaretLine.size()-1] == ' ')
    914     CaretLine.erase(CaretLine.end()-1);
    915 
    916   // Emit what we have computed.
    917   emitSnippet(SourceLine);
    918 
    919   if (DiagOpts.ShowColors)
    920     OS.changeColor(caretColor, true);
    921   OS << CaretLine << '\n';
    922   if (DiagOpts.ShowColors)
    923     OS.resetColor();
    924 
    925   if (!FixItInsertionLine.empty()) {
    926     if (DiagOpts.ShowColors)
    927       // Print fixit line in color
    928       OS.changeColor(fixitColor, false);
    929     if (DiagOpts.ShowSourceRanges)
    930       OS << ' ';
    931     OS << FixItInsertionLine << '\n';
    932     if (DiagOpts.ShowColors)
    933       OS.resetColor();
    934   }
    935 
    936   // Print out any parseable fixit information requested by the options.
    937   emitParseableFixits(Hints);
    938 }
    939 
    940 void TextDiagnostic::emitSnippet(StringRef line)
    941 {
    942   if (line.empty())
    943     return;
    944 
    945   size_t i = 0;
    946 
    947   std::string to_print;
    948   bool print_reversed = false;
    949 
    950   while (i<line.size()) {
    951     std::pair<SmallString<16>,bool> res
    952         = printableTextForNextCharacter(line, &i, DiagOpts.TabStop);
    953     bool was_printable = res.second;
    954 
    955     if (DiagOpts.ShowColors
    956         && was_printable==print_reversed) {
    957       if (print_reversed)
    958         OS.reverseColor();
    959       OS << to_print;
    960       to_print.clear();
    961       if (DiagOpts.ShowColors)
    962         OS.resetColor();
    963     }
    964 
    965     print_reversed = !was_printable;
    966     to_print += res.first.str();
    967   }
    968 
    969   if (print_reversed && DiagOpts.ShowColors)
    970     OS.reverseColor();
    971   OS << to_print;
    972   if (print_reversed && DiagOpts.ShowColors)
    973     OS.resetColor();
    974 
    975   OS << '\n';
    976 }
    977 
    978 /// \brief Highlight a SourceRange (with ~'s) for any characters on LineNo.
    979 void TextDiagnostic::highlightRange(const CharSourceRange &R,
    980                                     unsigned LineNo, FileID FID,
    981                                     const SourceColumnMap &map,
    982                                     std::string &CaretLine) {
    983   if (!R.isValid()) return;
    984 
    985   SourceLocation Begin = SM.getExpansionLoc(R.getBegin());
    986   SourceLocation End = SM.getExpansionLoc(R.getEnd());
    987 
    988   // If the End location and the start location are the same and are a macro
    989   // location, then the range was something that came from a macro expansion
    990   // or _Pragma.  If this is an object-like macro, the best we can do is to
    991   // highlight the range.  If this is a function-like macro, we'd also like to
    992   // highlight the arguments.
    993   if (Begin == End && R.getEnd().isMacroID())
    994     End = SM.getExpansionRange(R.getEnd()).second;
    995 
    996   unsigned StartLineNo = SM.getExpansionLineNumber(Begin);
    997   if (StartLineNo > LineNo || SM.getFileID(Begin) != FID)
    998     return;  // No intersection.
    999 
   1000   unsigned EndLineNo = SM.getExpansionLineNumber(End);
   1001   if (EndLineNo < LineNo || SM.getFileID(End) != FID)
   1002     return;  // No intersection.
   1003 
   1004   // Compute the column number of the start.
   1005   unsigned StartColNo = 0;
   1006   if (StartLineNo == LineNo) {
   1007     StartColNo = SM.getExpansionColumnNumber(Begin);
   1008     if (StartColNo) --StartColNo;  // Zero base the col #.
   1009   }
   1010 
   1011   // Compute the column number of the end.
   1012   unsigned EndColNo = map.getSourceLine().size();
   1013   if (EndLineNo == LineNo) {
   1014     EndColNo = SM.getExpansionColumnNumber(End);
   1015     if (EndColNo) {
   1016       --EndColNo;  // Zero base the col #.
   1017 
   1018       // Add in the length of the token, so that we cover multi-char tokens if
   1019       // this is a token range.
   1020       if (R.isTokenRange())
   1021         EndColNo += Lexer::MeasureTokenLength(End, SM, LangOpts);
   1022     } else {
   1023       EndColNo = CaretLine.size();
   1024     }
   1025   }
   1026 
   1027   assert(StartColNo <= EndColNo && "Invalid range!");
   1028 
   1029   // Check that a token range does not highlight only whitespace.
   1030   if (R.isTokenRange()) {
   1031     // Pick the first non-whitespace column.
   1032     while (StartColNo < map.getSourceLine().size() &&
   1033            (map.getSourceLine()[StartColNo] == ' ' ||
   1034             map.getSourceLine()[StartColNo] == '\t'))
   1035       ++StartColNo;
   1036 
   1037     // Pick the last non-whitespace column.
   1038     if (EndColNo > map.getSourceLine().size())
   1039       EndColNo = map.getSourceLine().size();
   1040     while (EndColNo-1 &&
   1041            (map.getSourceLine()[EndColNo-1] == ' ' ||
   1042             map.getSourceLine()[EndColNo-1] == '\t'))
   1043       --EndColNo;
   1044 
   1045     // If the start/end passed each other, then we are trying to highlight a
   1046     // range that just exists in whitespace, which must be some sort of other
   1047     // bug.
   1048     assert(StartColNo <= EndColNo && "Trying to highlight whitespace??");
   1049   }
   1050 
   1051   assert(StartColNo <= map.getSourceLine().size() && "Invalid range!");
   1052   assert(EndColNo <= map.getSourceLine().size() && "Invalid range!");
   1053 
   1054   // Fill the range with ~'s.
   1055   StartColNo = map.byteToColumn(StartColNo);
   1056   EndColNo = map.byteToColumn(EndColNo);
   1057 
   1058   assert(StartColNo <= EndColNo && "Invalid range!");
   1059   if (CaretLine.size() < EndColNo)
   1060     CaretLine.resize(EndColNo,' ');
   1061   std::fill(CaretLine.begin()+StartColNo,CaretLine.begin()+EndColNo,'~');
   1062 }
   1063 
   1064 std::string TextDiagnostic::buildFixItInsertionLine(
   1065   unsigned LineNo,
   1066   const SourceColumnMap &map,
   1067   ArrayRef<FixItHint> Hints) {
   1068 
   1069   std::string FixItInsertionLine;
   1070   if (Hints.empty() || !DiagOpts.ShowFixits)
   1071     return FixItInsertionLine;
   1072 
   1073   for (ArrayRef<FixItHint>::iterator I = Hints.begin(), E = Hints.end();
   1074        I != E; ++I) {
   1075     if (!I->CodeToInsert.empty()) {
   1076       // We have an insertion hint. Determine whether the inserted
   1077       // code is on the same line as the caret.
   1078       std::pair<FileID, unsigned> HintLocInfo
   1079         = SM.getDecomposedExpansionLoc(I->RemoveRange.getBegin());
   1080       if (LineNo == SM.getLineNumber(HintLocInfo.first, HintLocInfo.second)) {
   1081         // Insert the new code into the line just below the code
   1082         // that the user wrote.
   1083         unsigned HintColNo
   1084           = SM.getColumnNumber(HintLocInfo.first, HintLocInfo.second) - 1;
   1085         // hint must start inside the source or right at the end
   1086         assert(HintColNo<static_cast<unsigned>(map.bytes())+1);
   1087         HintColNo = map.byteToColumn(HintColNo);
   1088 
   1089         // FIXME: if the fixit includes tabs or other characters that do not
   1090         //  take up a single column per byte when displayed then
   1091         //  I->CodeToInsert.size() is not a column number and we're mixing
   1092         //  units (columns + bytes). We should get printable versions
   1093         //  of each fixit before using them.
   1094         unsigned LastColumnModified
   1095           = HintColNo + I->CodeToInsert.size();
   1096 
   1097         if (LastColumnModified > static_cast<unsigned>(map.bytes())) {
   1098           unsigned LastExistingColumn = map.byteToColumn(map.bytes());
   1099           unsigned AddedColumns = LastColumnModified-LastExistingColumn;
   1100           LastColumnModified = LastExistingColumn + AddedColumns;
   1101         } else {
   1102           LastColumnModified = map.byteToColumn(LastColumnModified);
   1103         }
   1104 
   1105         if (LastColumnModified > FixItInsertionLine.size())
   1106           FixItInsertionLine.resize(LastColumnModified, ' ');
   1107         assert(HintColNo+I->CodeToInsert.size() <= FixItInsertionLine.size());
   1108         std::copy(I->CodeToInsert.begin(), I->CodeToInsert.end(),
   1109                   FixItInsertionLine.begin() + HintColNo);
   1110       } else {
   1111         FixItInsertionLine.clear();
   1112         break;
   1113       }
   1114     }
   1115   }
   1116 
   1117   expandTabs(FixItInsertionLine, DiagOpts.TabStop);
   1118 
   1119   return FixItInsertionLine;
   1120 }
   1121 
   1122 void TextDiagnostic::emitParseableFixits(ArrayRef<FixItHint> Hints) {
   1123   if (!DiagOpts.ShowParseableFixits)
   1124     return;
   1125 
   1126   // We follow FixItRewriter's example in not (yet) handling
   1127   // fix-its in macros.
   1128   for (ArrayRef<FixItHint>::iterator I = Hints.begin(), E = Hints.end();
   1129        I != E; ++I) {
   1130     if (I->RemoveRange.isInvalid() ||
   1131         I->RemoveRange.getBegin().isMacroID() ||
   1132         I->RemoveRange.getEnd().isMacroID())
   1133       return;
   1134   }
   1135 
   1136   for (ArrayRef<FixItHint>::iterator I = Hints.begin(), E = Hints.end();
   1137        I != E; ++I) {
   1138     SourceLocation BLoc = I->RemoveRange.getBegin();
   1139     SourceLocation ELoc = I->RemoveRange.getEnd();
   1140 
   1141     std::pair<FileID, unsigned> BInfo = SM.getDecomposedLoc(BLoc);
   1142     std::pair<FileID, unsigned> EInfo = SM.getDecomposedLoc(ELoc);
   1143 
   1144     // Adjust for token ranges.
   1145     if (I->RemoveRange.isTokenRange())
   1146       EInfo.second += Lexer::MeasureTokenLength(ELoc, SM, LangOpts);
   1147 
   1148     // We specifically do not do word-wrapping or tab-expansion here,
   1149     // because this is supposed to be easy to parse.
   1150     PresumedLoc PLoc = SM.getPresumedLoc(BLoc);
   1151     if (PLoc.isInvalid())
   1152       break;
   1153 
   1154     OS << "fix-it:\"";
   1155     OS.write_escaped(PLoc.getFilename());
   1156     OS << "\":{" << SM.getLineNumber(BInfo.first, BInfo.second)
   1157       << ':' << SM.getColumnNumber(BInfo.first, BInfo.second)
   1158       << '-' << SM.getLineNumber(EInfo.first, EInfo.second)
   1159       << ':' << SM.getColumnNumber(EInfo.first, EInfo.second)
   1160       << "}:\"";
   1161     OS.write_escaped(I->CodeToInsert);
   1162     OS << "\"\n";
   1163   }
   1164 }
   1165