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