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