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