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