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