DiagnosticRenderer.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  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. #include "clang/Frontend/DiagnosticRenderer.h"
  10. #include "clang/Basic/FileManager.h"
  11. #include "clang/Basic/SourceManager.h"
  12. #include "clang/Frontend/DiagnosticOptions.h"
  13. #include "clang/Lex/Lexer.h"
  14. #include "llvm/Support/MemoryBuffer.h"
  15. #include "llvm/Support/raw_ostream.h"
  16. #include "llvm/Support/ErrorHandling.h"
  17. #include "llvm/ADT/SmallString.h"
  18. #include <algorithm>
  19. using namespace clang;
  20. /// Look through spelling locations for a macro argument expansion, and
  21. /// if found skip to it so that we can trace the argument rather than the macros
  22. /// in which that argument is used. If no macro argument expansion is found,
  23. /// don't skip anything and return the starting location.
  24. static SourceLocation skipToMacroArgExpansion(const SourceManager &SM,
  25. SourceLocation StartLoc) {
  26. for (SourceLocation L = StartLoc; L.isMacroID();
  27. L = SM.getImmediateSpellingLoc(L)) {
  28. if (SM.isMacroArgExpansion(L))
  29. return L;
  30. }
  31. // Otherwise just return initial location, there's nothing to skip.
  32. return StartLoc;
  33. }
  34. /// Gets the location of the immediate macro caller, one level up the stack
  35. /// toward the initial macro typed into the source.
  36. static SourceLocation getImmediateMacroCallerLoc(const SourceManager &SM,
  37. SourceLocation Loc) {
  38. if (!Loc.isMacroID()) return Loc;
  39. // When we have the location of (part of) an expanded parameter, its spelling
  40. // location points to the argument as typed into the macro call, and
  41. // therefore is used to locate the macro caller.
  42. if (SM.isMacroArgExpansion(Loc))
  43. return SM.getImmediateSpellingLoc(Loc);
  44. // Otherwise, the caller of the macro is located where this macro is
  45. // expanded (while the spelling is part of the macro definition).
  46. return SM.getImmediateExpansionRange(Loc).first;
  47. }
  48. /// Gets the location of the immediate macro callee, one level down the stack
  49. /// toward the leaf macro.
  50. static SourceLocation getImmediateMacroCalleeLoc(const SourceManager &SM,
  51. SourceLocation Loc) {
  52. if (!Loc.isMacroID()) return Loc;
  53. // When we have the location of (part of) an expanded parameter, its
  54. // expansion location points to the unexpanded paramater reference within
  55. // the macro definition (or callee).
  56. if (SM.isMacroArgExpansion(Loc))
  57. return SM.getImmediateExpansionRange(Loc).first;
  58. // Otherwise, the callee of the macro is located where this location was
  59. // spelled inside the macro definition.
  60. return SM.getImmediateSpellingLoc(Loc);
  61. }
  62. /// \brief Retrieve the name of the immediate macro expansion.
  63. ///
  64. /// This routine starts from a source location, and finds the name of the macro
  65. /// responsible for its immediate expansion. It looks through any intervening
  66. /// macro argument expansions to compute this. It returns a StringRef which
  67. /// refers to the SourceManager-owned buffer of the source where that macro
  68. /// name is spelled. Thus, the result shouldn't out-live that SourceManager.
  69. ///
  70. /// This differs from Lexer::getImmediateMacroName in that any macro argument
  71. /// location will result in the topmost function macro that accepted it.
  72. /// e.g.
  73. /// \code
  74. /// MAC1( MAC2(foo) )
  75. /// \endcode
  76. /// for location of 'foo' token, this function will return "MAC1" while
  77. /// Lexer::getImmediateMacroName will return "MAC2".
  78. static StringRef getImmediateMacroName(SourceLocation Loc,
  79. const SourceManager &SM,
  80. const LangOptions &LangOpts) {
  81. assert(Loc.isMacroID() && "Only reasonble to call this on macros");
  82. // Walk past macro argument expanions.
  83. while (SM.isMacroArgExpansion(Loc))
  84. Loc = SM.getImmediateExpansionRange(Loc).first;
  85. // Find the spelling location of the start of the non-argument expansion
  86. // range. This is where the macro name was spelled in order to begin
  87. // expanding this macro.
  88. Loc = SM.getSpellingLoc(SM.getImmediateExpansionRange(Loc).first);
  89. // Dig out the buffer where the macro name was spelled and the extents of the
  90. // name so that we can render it into the expansion note.
  91. std::pair<FileID, unsigned> ExpansionInfo = SM.getDecomposedLoc(Loc);
  92. unsigned MacroTokenLength = Lexer::MeasureTokenLength(Loc, SM, LangOpts);
  93. StringRef ExpansionBuffer = SM.getBufferData(ExpansionInfo.first);
  94. return ExpansionBuffer.substr(ExpansionInfo.second, MacroTokenLength);
  95. }
  96. /// Get the presumed location of a diagnostic message. This computes the
  97. /// presumed location for the top of any macro backtrace when present.
  98. static PresumedLoc getDiagnosticPresumedLoc(const SourceManager &SM,
  99. SourceLocation Loc) {
  100. // This is a condensed form of the algorithm used by emitCaretDiagnostic to
  101. // walk to the top of the macro call stack.
  102. while (Loc.isMacroID()) {
  103. Loc = skipToMacroArgExpansion(SM, Loc);
  104. Loc = getImmediateMacroCallerLoc(SM, Loc);
  105. }
  106. return SM.getPresumedLoc(Loc);
  107. }
  108. DiagnosticRenderer::DiagnosticRenderer(const SourceManager &SM,
  109. const LangOptions &LangOpts,
  110. const DiagnosticOptions &DiagOpts)
  111. : SM(SM), LangOpts(LangOpts), DiagOpts(DiagOpts), LastLevel() {}
  112. DiagnosticRenderer::~DiagnosticRenderer() {}
  113. void DiagnosticRenderer::emitDiagnostic(SourceLocation Loc,
  114. DiagnosticsEngine::Level Level,
  115. StringRef Message,
  116. ArrayRef<CharSourceRange> Ranges,
  117. ArrayRef<FixItHint> FixItHints,
  118. const Diagnostic *Info) {
  119. beginDiagnostic(Info, Level);
  120. PresumedLoc PLoc = getDiagnosticPresumedLoc(SM, Loc);
  121. // First, if this diagnostic is not in the main file, print out the
  122. // "included from" lines.
  123. emitIncludeStack(PLoc.getIncludeLoc(), Level);
  124. // Next, emit the actual diagnostic message.
  125. emitDiagnosticMessage(Loc, PLoc, Level, Message, Ranges, Info);
  126. // Only recurse if we have a valid location.
  127. if (Loc.isValid()) {
  128. // Get the ranges into a local array we can hack on.
  129. SmallVector<CharSourceRange, 20> MutableRanges(Ranges.begin(),
  130. Ranges.end());
  131. for (ArrayRef<FixItHint>::const_iterator I = FixItHints.begin(),
  132. E = FixItHints.end();
  133. I != E; ++I)
  134. if (I->RemoveRange.isValid())
  135. MutableRanges.push_back(I->RemoveRange);
  136. unsigned MacroDepth = 0;
  137. emitMacroExpansionsAndCarets(Loc, Level, MutableRanges, FixItHints,
  138. MacroDepth);
  139. }
  140. LastLoc = Loc;
  141. LastLevel = Level;
  142. endDiagnostic(Info, Level);
  143. }
  144. /// \brief Prints an include stack when appropriate for a particular
  145. /// diagnostic level and location.
  146. ///
  147. /// This routine handles all the logic of suppressing particular include
  148. /// stacks (such as those for notes) and duplicate include stacks when
  149. /// repeated warnings occur within the same file. It also handles the logic
  150. /// of customizing the formatting and display of the include stack.
  151. ///
  152. /// \param Level The diagnostic level of the message this stack pertains to.
  153. /// \param Loc The include location of the current file (not the diagnostic
  154. /// location).
  155. void DiagnosticRenderer::emitIncludeStack(SourceLocation Loc,
  156. DiagnosticsEngine::Level Level) {
  157. // Skip redundant include stacks altogether.
  158. if (LastIncludeLoc == Loc)
  159. return;
  160. LastIncludeLoc = Loc;
  161. if (!DiagOpts.ShowNoteIncludeStack && Level == DiagnosticsEngine::Note)
  162. return;
  163. emitIncludeStackRecursively(Loc);
  164. }
  165. /// \brief Helper to recursivly walk up the include stack and print each layer
  166. /// on the way back down.
  167. void DiagnosticRenderer::emitIncludeStackRecursively(SourceLocation Loc) {
  168. if (Loc.isInvalid())
  169. return;
  170. PresumedLoc PLoc = SM.getPresumedLoc(Loc);
  171. if (PLoc.isInvalid())
  172. return;
  173. // Emit the other include frames first.
  174. emitIncludeStackRecursively(PLoc.getIncludeLoc());
  175. // Emit the inclusion text/note.
  176. emitIncludeLocation(Loc, PLoc);
  177. }
  178. /// \brief Recursively emit notes for each macro expansion and caret
  179. /// diagnostics where appropriate.
  180. ///
  181. /// Walks up the macro expansion stack printing expansion notes, the code
  182. /// snippet, caret, underlines and FixItHint display as appropriate at each
  183. /// level.
  184. ///
  185. /// \param Loc The location for this caret.
  186. /// \param Level The diagnostic level currently being emitted.
  187. /// \param Ranges The underlined ranges for this code snippet.
  188. /// \param Hints The FixIt hints active for this diagnostic.
  189. /// \param MacroSkipEnd The depth to stop skipping macro expansions.
  190. /// \param OnMacroInst The current depth of the macro expansion stack.
  191. void DiagnosticRenderer::emitMacroExpansionsAndCarets(
  192. SourceLocation Loc,
  193. DiagnosticsEngine::Level Level,
  194. SmallVectorImpl<CharSourceRange>& Ranges,
  195. ArrayRef<FixItHint> Hints,
  196. unsigned &MacroDepth,
  197. unsigned OnMacroInst)
  198. {
  199. assert(!Loc.isInvalid() && "must have a valid source location here");
  200. // If this is a file source location, directly emit the source snippet and
  201. // caret line. Also record the macro depth reached.
  202. if (Loc.isFileID()) {
  203. assert(MacroDepth == 0 && "We shouldn't hit a leaf node twice!");
  204. MacroDepth = OnMacroInst;
  205. emitCodeContext(Loc, Level, Ranges, Hints);
  206. return;
  207. }
  208. // Otherwise recurse through each macro expansion layer.
  209. // When processing macros, skip over the expansions leading up to
  210. // a macro argument, and trace the argument's expansion stack instead.
  211. Loc = skipToMacroArgExpansion(SM, Loc);
  212. SourceLocation OneLevelUp = getImmediateMacroCallerLoc(SM, Loc);
  213. // FIXME: Map ranges?
  214. emitMacroExpansionsAndCarets(OneLevelUp, Level, Ranges, Hints, MacroDepth,
  215. OnMacroInst + 1);
  216. // Save the original location so we can find the spelling of the macro call.
  217. SourceLocation MacroLoc = Loc;
  218. // Map the location.
  219. Loc = getImmediateMacroCalleeLoc(SM, Loc);
  220. unsigned MacroSkipStart = 0, MacroSkipEnd = 0;
  221. if (MacroDepth > DiagOpts.MacroBacktraceLimit &&
  222. DiagOpts.MacroBacktraceLimit != 0) {
  223. MacroSkipStart = DiagOpts.MacroBacktraceLimit / 2 +
  224. DiagOpts.MacroBacktraceLimit % 2;
  225. MacroSkipEnd = MacroDepth - DiagOpts.MacroBacktraceLimit / 2;
  226. }
  227. // Whether to suppress printing this macro expansion.
  228. bool Suppressed = (OnMacroInst >= MacroSkipStart &&
  229. OnMacroInst < MacroSkipEnd);
  230. // Map the ranges.
  231. for (SmallVectorImpl<CharSourceRange>::iterator I = Ranges.begin(),
  232. E = Ranges.end();
  233. I != E; ++I) {
  234. SourceLocation Start = I->getBegin(), End = I->getEnd();
  235. if (Start.isMacroID())
  236. I->setBegin(getImmediateMacroCalleeLoc(SM, Start));
  237. if (End.isMacroID())
  238. I->setEnd(getImmediateMacroCalleeLoc(SM, End));
  239. }
  240. if (Suppressed) {
  241. // Tell the user that we've skipped contexts.
  242. if (OnMacroInst == MacroSkipStart) {
  243. SmallString<200> MessageStorage;
  244. llvm::raw_svector_ostream Message(MessageStorage);
  245. Message << "(skipping " << (MacroSkipEnd - MacroSkipStart)
  246. << " expansions in backtrace; use -fmacro-backtrace-limit=0 to "
  247. "see all)";
  248. emitBasicNote(Message.str());
  249. }
  250. return;
  251. }
  252. SmallString<100> MessageStorage;
  253. llvm::raw_svector_ostream Message(MessageStorage);
  254. Message << "expanded from macro '"
  255. << getImmediateMacroName(MacroLoc, SM, LangOpts) << "'";
  256. emitDiagnostic(SM.getSpellingLoc(Loc), DiagnosticsEngine::Note,
  257. Message.str(),
  258. Ranges, ArrayRef<FixItHint>());
  259. }