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