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