]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/lib/Frontend/DiagnosticRenderer.cpp
Update clang to trunk r290819 and resolve conflicts.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / lib / Frontend / DiagnosticRenderer.cpp
1 //===--- DiagnosticRenderer.cpp - Diagnostic Pretty-Printing --------------===//
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 #include "clang/Frontend/DiagnosticRenderer.h"
11 #include "clang/Basic/DiagnosticOptions.h"
12 #include "clang/Basic/SourceManager.h"
13 #include "clang/Edit/Commit.h"
14 #include "clang/Edit/EditedSource.h"
15 #include "clang/Edit/EditsReceiver.h"
16 #include "clang/Lex/Lexer.h"
17 #include "llvm/ADT/SmallSet.h"
18 #include "llvm/ADT/SmallString.h"
19 #include "llvm/Support/ErrorHandling.h"
20 #include "llvm/Support/raw_ostream.h"
21 #include <algorithm>
22 using namespace clang;
23
24 DiagnosticRenderer::DiagnosticRenderer(const LangOptions &LangOpts,
25                                        DiagnosticOptions *DiagOpts)
26   : LangOpts(LangOpts), DiagOpts(DiagOpts), LastLevel() {}
27
28 DiagnosticRenderer::~DiagnosticRenderer() {}
29
30 namespace {
31
32 class FixitReceiver : public edit::EditsReceiver {
33   SmallVectorImpl<FixItHint> &MergedFixits;
34
35 public:
36   FixitReceiver(SmallVectorImpl<FixItHint> &MergedFixits)
37     : MergedFixits(MergedFixits) { }
38   void insert(SourceLocation loc, StringRef text) override {
39     MergedFixits.push_back(FixItHint::CreateInsertion(loc, text));
40   }
41   void replace(CharSourceRange range, StringRef text) override {
42     MergedFixits.push_back(FixItHint::CreateReplacement(range, text));
43   }
44 };
45
46 }
47
48 static void mergeFixits(ArrayRef<FixItHint> FixItHints,
49                         const SourceManager &SM, const LangOptions &LangOpts,
50                         SmallVectorImpl<FixItHint> &MergedFixits) {
51   edit::Commit commit(SM, LangOpts);
52   for (ArrayRef<FixItHint>::const_iterator
53          I = FixItHints.begin(), E = FixItHints.end(); I != E; ++I) {
54     const FixItHint &Hint = *I;
55     if (Hint.CodeToInsert.empty()) {
56       if (Hint.InsertFromRange.isValid())
57         commit.insertFromRange(Hint.RemoveRange.getBegin(),
58                            Hint.InsertFromRange, /*afterToken=*/false,
59                            Hint.BeforePreviousInsertions);
60       else
61         commit.remove(Hint.RemoveRange);
62     } else {
63       if (Hint.RemoveRange.isTokenRange() ||
64           Hint.RemoveRange.getBegin() != Hint.RemoveRange.getEnd())
65         commit.replace(Hint.RemoveRange, Hint.CodeToInsert);
66       else
67         commit.insert(Hint.RemoveRange.getBegin(), Hint.CodeToInsert,
68                     /*afterToken=*/false, Hint.BeforePreviousInsertions);
69     }
70   }
71
72   edit::EditedSource Editor(SM, LangOpts);
73   if (Editor.commit(commit)) {
74     FixitReceiver Rec(MergedFixits);
75     Editor.applyRewrites(Rec);
76   }
77 }
78
79 void DiagnosticRenderer::emitDiagnostic(SourceLocation Loc,
80                                         DiagnosticsEngine::Level Level,
81                                         StringRef Message,
82                                         ArrayRef<CharSourceRange> Ranges,
83                                         ArrayRef<FixItHint> FixItHints,
84                                         const SourceManager *SM,
85                                         DiagOrStoredDiag D) {
86   assert(SM || Loc.isInvalid());
87
88   beginDiagnostic(D, Level);
89
90   if (!Loc.isValid())
91     // If we have no source location, just emit the diagnostic message.
92     emitDiagnosticMessage(Loc, PresumedLoc(), Level, Message, Ranges, SM, D);
93   else {
94     // Get the ranges into a local array we can hack on.
95     SmallVector<CharSourceRange, 20> MutableRanges(Ranges.begin(),
96                                                    Ranges.end());
97
98     SmallVector<FixItHint, 8> MergedFixits;
99     if (!FixItHints.empty()) {
100       mergeFixits(FixItHints, *SM, LangOpts, MergedFixits);
101       FixItHints = MergedFixits;
102     }
103
104     for (ArrayRef<FixItHint>::const_iterator I = FixItHints.begin(),
105          E = FixItHints.end();
106          I != E; ++I)
107       if (I->RemoveRange.isValid())
108         MutableRanges.push_back(I->RemoveRange);
109
110     SourceLocation UnexpandedLoc = Loc;
111
112     // Find the ultimate expansion location for the diagnostic.
113     Loc = SM->getFileLoc(Loc);
114
115     PresumedLoc PLoc = SM->getPresumedLoc(Loc, DiagOpts->ShowPresumedLoc);
116
117     // First, if this diagnostic is not in the main file, print out the
118     // "included from" lines.
119     emitIncludeStack(Loc, PLoc, Level, *SM);
120
121     // Next, emit the actual diagnostic message and caret.
122     emitDiagnosticMessage(Loc, PLoc, Level, Message, Ranges, SM, D);
123     emitCaret(Loc, Level, MutableRanges, FixItHints, *SM);
124
125     // If this location is within a macro, walk from UnexpandedLoc up to Loc
126     // and produce a macro backtrace.
127     if (UnexpandedLoc.isValid() && UnexpandedLoc.isMacroID()) {
128       emitMacroExpansions(UnexpandedLoc, Level, MutableRanges, FixItHints, *SM);
129     }
130   }
131
132   LastLoc = Loc;
133   LastLevel = Level;
134
135   endDiagnostic(D, Level);
136 }
137
138
139 void DiagnosticRenderer::emitStoredDiagnostic(StoredDiagnostic &Diag) {
140   emitDiagnostic(Diag.getLocation(), Diag.getLevel(), Diag.getMessage(),
141                  Diag.getRanges(), Diag.getFixIts(),
142                  Diag.getLocation().isValid() ? &Diag.getLocation().getManager()
143                                               : nullptr,
144                  &Diag);
145 }
146
147 void DiagnosticRenderer::emitBasicNote(StringRef Message) {
148   emitDiagnosticMessage(
149       SourceLocation(), PresumedLoc(), DiagnosticsEngine::Note, Message,
150       None, nullptr, DiagOrStoredDiag());
151 }
152
153 /// \brief Prints an include stack when appropriate for a particular
154 /// diagnostic level and location.
155 ///
156 /// This routine handles all the logic of suppressing particular include
157 /// stacks (such as those for notes) and duplicate include stacks when
158 /// repeated warnings occur within the same file. It also handles the logic
159 /// of customizing the formatting and display of the include stack.
160 ///
161 /// \param Loc   The diagnostic location.
162 /// \param PLoc  The presumed location of the diagnostic location.
163 /// \param Level The diagnostic level of the message this stack pertains to.
164 void DiagnosticRenderer::emitIncludeStack(SourceLocation Loc,
165                                           PresumedLoc PLoc,
166                                           DiagnosticsEngine::Level Level,
167                                           const SourceManager &SM) {
168   SourceLocation IncludeLoc =
169       PLoc.isInvalid() ? SourceLocation() : PLoc.getIncludeLoc();
170
171   // Skip redundant include stacks altogether.
172   if (LastIncludeLoc == IncludeLoc)
173     return;
174   
175   LastIncludeLoc = IncludeLoc;
176   
177   if (!DiagOpts->ShowNoteIncludeStack && Level == DiagnosticsEngine::Note)
178     return;
179
180   if (IncludeLoc.isValid())
181     emitIncludeStackRecursively(IncludeLoc, SM);
182   else {
183     emitModuleBuildStack(SM);
184     emitImportStack(Loc, SM);
185   }
186 }
187
188 /// \brief Helper to recursivly walk up the include stack and print each layer
189 /// on the way back down.
190 void DiagnosticRenderer::emitIncludeStackRecursively(SourceLocation Loc,
191                                                      const SourceManager &SM) {
192   if (Loc.isInvalid()) {
193     emitModuleBuildStack(SM);
194     return;
195   }
196   
197   PresumedLoc PLoc = SM.getPresumedLoc(Loc, DiagOpts->ShowPresumedLoc);
198   if (PLoc.isInvalid())
199     return;
200
201   // If this source location was imported from a module, print the module
202   // import stack rather than the 
203   // FIXME: We want submodule granularity here.
204   std::pair<SourceLocation, StringRef> Imported = SM.getModuleImportLoc(Loc);
205   if (!Imported.second.empty()) {
206     // This location was imported by a module. Emit the module import stack.
207     emitImportStackRecursively(Imported.first, Imported.second, SM);
208     return;
209   }
210
211   // Emit the other include frames first.
212   emitIncludeStackRecursively(PLoc.getIncludeLoc(), SM);
213   
214   // Emit the inclusion text/note.
215   emitIncludeLocation(Loc, PLoc, SM);
216 }
217
218 /// \brief Emit the module import stack associated with the current location.
219 void DiagnosticRenderer::emitImportStack(SourceLocation Loc,
220                                          const SourceManager &SM) {
221   if (Loc.isInvalid()) {
222     emitModuleBuildStack(SM);
223     return;
224   }
225
226   std::pair<SourceLocation, StringRef> NextImportLoc
227     = SM.getModuleImportLoc(Loc);
228   emitImportStackRecursively(NextImportLoc.first, NextImportLoc.second, SM);
229 }
230
231 /// \brief Helper to recursivly walk up the import stack and print each layer
232 /// on the way back down.
233 void DiagnosticRenderer::emitImportStackRecursively(SourceLocation Loc,
234                                                     StringRef ModuleName,
235                                                     const SourceManager &SM) {
236   if (ModuleName.empty()) {
237     return;
238   }
239
240   PresumedLoc PLoc = SM.getPresumedLoc(Loc, DiagOpts->ShowPresumedLoc);
241
242   // Emit the other import frames first.
243   std::pair<SourceLocation, StringRef> NextImportLoc
244     = SM.getModuleImportLoc(Loc);
245   emitImportStackRecursively(NextImportLoc.first, NextImportLoc.second, SM);
246
247   // Emit the inclusion text/note.
248   emitImportLocation(Loc, PLoc, ModuleName, SM);
249 }
250
251 /// \brief Emit the module build stack, for cases where a module is (re-)built
252 /// on demand.
253 void DiagnosticRenderer::emitModuleBuildStack(const SourceManager &SM) {
254   ModuleBuildStack Stack = SM.getModuleBuildStack();
255   for (unsigned I = 0, N = Stack.size(); I != N; ++I) {
256     const SourceManager &CurSM = Stack[I].second.getManager();
257     SourceLocation CurLoc = Stack[I].second;
258     emitBuildingModuleLocation(CurLoc,
259                                CurSM.getPresumedLoc(CurLoc,
260                                                     DiagOpts->ShowPresumedLoc),
261                                Stack[I].first,
262                                CurSM);
263   }
264 }
265
266 /// A recursive function to trace all possible backtrace locations
267 /// to match the \p CaretLocFileID.
268 static SourceLocation
269 retrieveMacroLocation(SourceLocation Loc, FileID MacroFileID,
270                       FileID CaretFileID,
271                       const SmallVectorImpl<FileID> &CommonArgExpansions,
272                       bool IsBegin, const SourceManager *SM) {
273   assert(SM->getFileID(Loc) == MacroFileID);
274   if (MacroFileID == CaretFileID)
275     return Loc;
276   if (!Loc.isMacroID())
277     return SourceLocation();
278
279   SourceLocation MacroLocation, MacroArgLocation;
280
281   if (SM->isMacroArgExpansion(Loc)) {
282     // Only look at the immediate spelling location of this macro argument if
283     // the other location in the source range is also present in that expansion.
284     if (std::binary_search(CommonArgExpansions.begin(),
285                            CommonArgExpansions.end(), MacroFileID))
286       MacroLocation = SM->getImmediateSpellingLoc(Loc);
287     MacroArgLocation = IsBegin ? SM->getImmediateExpansionRange(Loc).first
288                                : SM->getImmediateExpansionRange(Loc).second;
289   } else {
290     MacroLocation = IsBegin ? SM->getImmediateExpansionRange(Loc).first
291                             : SM->getImmediateExpansionRange(Loc).second;
292     MacroArgLocation = SM->getImmediateSpellingLoc(Loc);
293   }
294
295   if (MacroLocation.isValid()) {
296     MacroFileID = SM->getFileID(MacroLocation);
297     MacroLocation =
298         retrieveMacroLocation(MacroLocation, MacroFileID, CaretFileID,
299                               CommonArgExpansions, IsBegin, SM);
300     if (MacroLocation.isValid())
301       return MacroLocation;
302   }
303
304   MacroFileID = SM->getFileID(MacroArgLocation);
305   return retrieveMacroLocation(MacroArgLocation, MacroFileID, CaretFileID,
306                                CommonArgExpansions, IsBegin, SM);
307 }
308
309 /// Walk up the chain of macro expansions and collect the FileIDs identifying the
310 /// expansions.
311 static void getMacroArgExpansionFileIDs(SourceLocation Loc,
312                                         SmallVectorImpl<FileID> &IDs,
313                                         bool IsBegin, const SourceManager *SM) {
314   while (Loc.isMacroID()) {
315     if (SM->isMacroArgExpansion(Loc)) {
316       IDs.push_back(SM->getFileID(Loc));
317       Loc = SM->getImmediateSpellingLoc(Loc);
318     } else {
319       auto ExpRange = SM->getImmediateExpansionRange(Loc);
320       Loc = IsBegin ? ExpRange.first : ExpRange.second;
321     }
322   }
323 }
324
325 /// Collect the expansions of the begin and end locations and compute the set
326 /// intersection. Produces a sorted vector of FileIDs in CommonArgExpansions.
327 static void computeCommonMacroArgExpansionFileIDs(
328     SourceLocation Begin, SourceLocation End, const SourceManager *SM,
329     SmallVectorImpl<FileID> &CommonArgExpansions) {
330   SmallVector<FileID, 4> BeginArgExpansions;
331   SmallVector<FileID, 4> EndArgExpansions;
332   getMacroArgExpansionFileIDs(Begin, BeginArgExpansions, /*IsBegin=*/true, SM);
333   getMacroArgExpansionFileIDs(End, EndArgExpansions, /*IsBegin=*/false, SM);
334   std::sort(BeginArgExpansions.begin(), BeginArgExpansions.end());
335   std::sort(EndArgExpansions.begin(), EndArgExpansions.end());
336   std::set_intersection(BeginArgExpansions.begin(), BeginArgExpansions.end(),
337                         EndArgExpansions.begin(), EndArgExpansions.end(),
338                         std::back_inserter(CommonArgExpansions));
339 }
340
341 // Helper function to fix up source ranges.  It takes in an array of ranges,
342 // and outputs an array of ranges where we want to draw the range highlighting
343 // around the location specified by CaretLoc.
344 //
345 // To find locations which correspond to the caret, we crawl the macro caller
346 // chain for the beginning and end of each range.  If the caret location
347 // is in a macro expansion, we search each chain for a location
348 // in the same expansion as the caret; otherwise, we crawl to the top of
349 // each chain. Two locations are part of the same macro expansion
350 // iff the FileID is the same.
351 static void mapDiagnosticRanges(
352     SourceLocation CaretLoc,
353     ArrayRef<CharSourceRange> Ranges,
354     SmallVectorImpl<CharSourceRange> &SpellingRanges,
355     const SourceManager *SM) {
356   FileID CaretLocFileID = SM->getFileID(CaretLoc);
357
358   for (auto I = Ranges.begin(), E = Ranges.end(); I != E; ++I) {
359     if (I->isInvalid()) continue;
360
361     SourceLocation Begin = I->getBegin(), End = I->getEnd();
362     bool IsTokenRange = I->isTokenRange();
363
364     FileID BeginFileID = SM->getFileID(Begin);
365     FileID EndFileID = SM->getFileID(End);
366
367     // Find the common parent for the beginning and end of the range.
368
369     // First, crawl the expansion chain for the beginning of the range.
370     llvm::SmallDenseMap<FileID, SourceLocation> BeginLocsMap;
371     while (Begin.isMacroID() && BeginFileID != EndFileID) {
372       BeginLocsMap[BeginFileID] = Begin;
373       Begin = SM->getImmediateExpansionRange(Begin).first;
374       BeginFileID = SM->getFileID(Begin);
375     }
376
377     // Then, crawl the expansion chain for the end of the range.
378     if (BeginFileID != EndFileID) {
379       while (End.isMacroID() && !BeginLocsMap.count(EndFileID)) {
380         End = SM->getImmediateExpansionRange(End).second;
381         EndFileID = SM->getFileID(End);
382       }
383       if (End.isMacroID()) {
384         Begin = BeginLocsMap[EndFileID];
385         BeginFileID = EndFileID;
386       }
387     }
388
389     // Do the backtracking.
390     SmallVector<FileID, 4> CommonArgExpansions;
391     computeCommonMacroArgExpansionFileIDs(Begin, End, SM, CommonArgExpansions);
392     Begin = retrieveMacroLocation(Begin, BeginFileID, CaretLocFileID,
393                                   CommonArgExpansions, /*IsBegin=*/true, SM);
394     End = retrieveMacroLocation(End, BeginFileID, CaretLocFileID,
395                                 CommonArgExpansions, /*IsBegin=*/false, SM);
396     if (Begin.isInvalid() || End.isInvalid()) continue;
397
398     // Return the spelling location of the beginning and end of the range.
399     Begin = SM->getSpellingLoc(Begin);
400     End = SM->getSpellingLoc(End);
401
402     SpellingRanges.push_back(CharSourceRange(SourceRange(Begin, End),
403                                              IsTokenRange));
404   }
405 }
406
407 void DiagnosticRenderer::emitCaret(SourceLocation Loc,
408                                    DiagnosticsEngine::Level Level,
409                                    ArrayRef<CharSourceRange> Ranges,
410                                    ArrayRef<FixItHint> Hints,
411                                    const SourceManager &SM) {
412   SmallVector<CharSourceRange, 4> SpellingRanges;
413   mapDiagnosticRanges(Loc, Ranges, SpellingRanges, &SM);
414   emitCodeContext(Loc, Level, SpellingRanges, Hints, SM);
415 }
416
417 /// \brief A helper function for emitMacroExpansion to print the
418 /// macro expansion message
419 void DiagnosticRenderer::emitSingleMacroExpansion(
420     SourceLocation Loc,
421     DiagnosticsEngine::Level Level,
422     ArrayRef<CharSourceRange> Ranges,
423     const SourceManager &SM) {
424   // Find the spelling location for the macro definition. We must use the
425   // spelling location here to avoid emitting a macro backtrace for the note.
426   SourceLocation SpellingLoc = SM.getSpellingLoc(Loc);
427
428   // Map the ranges into the FileID of the diagnostic location.
429   SmallVector<CharSourceRange, 4> SpellingRanges;
430   mapDiagnosticRanges(Loc, Ranges, SpellingRanges, &SM);
431
432   SmallString<100> MessageStorage;
433   llvm::raw_svector_ostream Message(MessageStorage);
434   StringRef MacroName =
435       Lexer::getImmediateMacroNameForDiagnostics(Loc, SM, LangOpts);
436   if (MacroName.empty())
437     Message << "expanded from here";
438   else
439     Message << "expanded from macro '" << MacroName << "'";
440
441   emitDiagnostic(SpellingLoc, DiagnosticsEngine::Note, Message.str(),
442                  SpellingRanges, None, &SM);
443 }
444
445 /// Check that the macro argument location of Loc starts with ArgumentLoc.
446 /// The starting location of the macro expansions is used to differeniate
447 /// different macro expansions.
448 static bool checkLocForMacroArgExpansion(SourceLocation Loc,
449                                          const SourceManager &SM,
450                                          SourceLocation ArgumentLoc) {
451   SourceLocation MacroLoc;
452   if (SM.isMacroArgExpansion(Loc, &MacroLoc)) {
453     if (ArgumentLoc == MacroLoc) return true;
454   }
455
456   return false;
457 }
458
459 /// Check if all the locations in the range have the same macro argument
460 /// expansion, and that that expansion starts with ArgumentLoc.
461 static bool checkRangeForMacroArgExpansion(CharSourceRange Range,
462                                            const SourceManager &SM,
463                                            SourceLocation ArgumentLoc) {
464   SourceLocation BegLoc = Range.getBegin(), EndLoc = Range.getEnd();
465   while (BegLoc != EndLoc) {
466     if (!checkLocForMacroArgExpansion(BegLoc, SM, ArgumentLoc))
467       return false;
468     BegLoc.getLocWithOffset(1);
469   }
470
471   return checkLocForMacroArgExpansion(BegLoc, SM, ArgumentLoc);
472 }
473
474 /// A helper function to check if the current ranges are all inside the same
475 /// macro argument expansion as Loc.
476 static bool checkRangesForMacroArgExpansion(SourceLocation Loc,
477                                             ArrayRef<CharSourceRange> Ranges,
478                                             const SourceManager &SM) {
479   assert(Loc.isMacroID() && "Must be a macro expansion!");
480
481   SmallVector<CharSourceRange, 4> SpellingRanges;
482   mapDiagnosticRanges(Loc, Ranges, SpellingRanges, &SM);
483
484   /// Count all valid ranges.
485   unsigned ValidCount = 0;
486   for (auto I : Ranges)
487     if (I.isValid()) ValidCount++;
488
489   if (ValidCount > SpellingRanges.size())
490     return false;
491
492   /// To store the source location of the argument location.
493   SourceLocation ArgumentLoc;
494
495   /// Set the ArgumentLoc to the beginning location of the expansion of Loc
496   /// so to check if the ranges expands to the same beginning location.
497   if (!SM.isMacroArgExpansion(Loc,&ArgumentLoc))
498     return false;
499
500   for (auto I = SpellingRanges.begin(), E = SpellingRanges.end(); I != E; ++I) {
501     if (!checkRangeForMacroArgExpansion(*I, SM, ArgumentLoc))
502       return false;
503   }
504
505   return true;
506 }
507
508 /// \brief Recursively emit notes for each macro expansion and caret
509 /// diagnostics where appropriate.
510 ///
511 /// Walks up the macro expansion stack printing expansion notes, the code
512 /// snippet, caret, underlines and FixItHint display as appropriate at each
513 /// level.
514 ///
515 /// \param Loc The location for this caret.
516 /// \param Level The diagnostic level currently being emitted.
517 /// \param Ranges The underlined ranges for this code snippet.
518 /// \param Hints The FixIt hints active for this diagnostic.
519 void DiagnosticRenderer::emitMacroExpansions(SourceLocation Loc,
520                                              DiagnosticsEngine::Level Level,
521                                              ArrayRef<CharSourceRange> Ranges,
522                                              ArrayRef<FixItHint> Hints,
523                                              const SourceManager &SM) {
524   assert(Loc.isValid() && "must have a valid source location here");
525
526   // Produce a stack of macro backtraces.
527   SmallVector<SourceLocation, 8> LocationStack;
528   unsigned IgnoredEnd = 0;
529   while (Loc.isMacroID()) {
530     // If this is the expansion of a macro argument, point the caret at the
531     // use of the argument in the definition of the macro, not the expansion.
532     if (SM.isMacroArgExpansion(Loc))
533       LocationStack.push_back(SM.getImmediateExpansionRange(Loc).first);
534     else
535       LocationStack.push_back(Loc);
536
537     if (checkRangesForMacroArgExpansion(Loc, Ranges, SM))
538       IgnoredEnd = LocationStack.size();
539
540     Loc = SM.getImmediateMacroCallerLoc(Loc);
541
542     // Once the location no longer points into a macro, try stepping through
543     // the last found location.  This sometimes produces additional useful
544     // backtraces.
545     if (Loc.isFileID())
546       Loc = SM.getImmediateMacroCallerLoc(LocationStack.back());
547     assert(Loc.isValid() && "must have a valid source location here");
548   }
549
550   LocationStack.erase(LocationStack.begin(),
551                       LocationStack.begin() + IgnoredEnd);
552
553   unsigned MacroDepth = LocationStack.size();
554   unsigned MacroLimit = DiagOpts->MacroBacktraceLimit;
555   if (MacroDepth <= MacroLimit || MacroLimit == 0) {
556     for (auto I = LocationStack.rbegin(), E = LocationStack.rend();
557          I != E; ++I)
558       emitSingleMacroExpansion(*I, Level, Ranges, SM);
559     return;
560   }
561
562   unsigned MacroStartMessages = MacroLimit / 2;
563   unsigned MacroEndMessages = MacroLimit / 2 + MacroLimit % 2;
564
565   for (auto I = LocationStack.rbegin(),
566             E = LocationStack.rbegin() + MacroStartMessages;
567        I != E; ++I)
568     emitSingleMacroExpansion(*I, Level, Ranges, SM);
569
570   SmallString<200> MessageStorage;
571   llvm::raw_svector_ostream Message(MessageStorage);
572   Message << "(skipping " << (MacroDepth - MacroLimit)
573           << " expansions in backtrace; use -fmacro-backtrace-limit=0 to "
574              "see all)";
575   emitBasicNote(Message.str());
576
577   for (auto I = LocationStack.rend() - MacroEndMessages,
578             E = LocationStack.rend();
579        I != E; ++I)
580     emitSingleMacroExpansion(*I, Level, Ranges, SM);
581 }
582
583 DiagnosticNoteRenderer::~DiagnosticNoteRenderer() {}
584
585 void DiagnosticNoteRenderer::emitIncludeLocation(SourceLocation Loc,
586                                                  PresumedLoc PLoc,
587                                                  const SourceManager &SM) {
588   // Generate a note indicating the include location.
589   SmallString<200> MessageStorage;
590   llvm::raw_svector_ostream Message(MessageStorage);
591   Message << "in file included from " << PLoc.getFilename() << ':'
592           << PLoc.getLine() << ":";
593   emitNote(Loc, Message.str(), &SM);
594 }
595
596 void DiagnosticNoteRenderer::emitImportLocation(SourceLocation Loc,
597                                                 PresumedLoc PLoc,
598                                                 StringRef ModuleName,
599                                                 const SourceManager &SM) {
600   // Generate a note indicating the include location.
601   SmallString<200> MessageStorage;
602   llvm::raw_svector_ostream Message(MessageStorage);
603   Message << "in module '" << ModuleName;
604   if (PLoc.isValid())
605     Message << "' imported from " << PLoc.getFilename() << ':'
606             << PLoc.getLine();
607   Message << ":";
608   emitNote(Loc, Message.str(), &SM);
609 }
610
611 void
612 DiagnosticNoteRenderer::emitBuildingModuleLocation(SourceLocation Loc,
613                                                    PresumedLoc PLoc,
614                                                    StringRef ModuleName,
615                                                    const SourceManager &SM) {
616   // Generate a note indicating the include location.
617   SmallString<200> MessageStorage;
618   llvm::raw_svector_ostream Message(MessageStorage);
619   if (PLoc.isValid())
620     Message << "while building module '" << ModuleName << "' imported from "
621             << PLoc.getFilename() << ':' << PLoc.getLine() << ":";
622   else
623     Message << "while building module '" << ModuleName << "':";
624   emitNote(Loc, Message.str(), &SM);
625 }