diff options
Diffstat (limited to 'lib/Frontend/DiagnosticRenderer.cpp')
| -rw-r--r-- | lib/Frontend/DiagnosticRenderer.cpp | 127 | 
1 files changed, 36 insertions, 91 deletions
diff --git a/lib/Frontend/DiagnosticRenderer.cpp b/lib/Frontend/DiagnosticRenderer.cpp index 6c3bb1d695345..f052f90fa9534 100644 --- a/lib/Frontend/DiagnosticRenderer.cpp +++ b/lib/Frontend/DiagnosticRenderer.cpp @@ -22,56 +22,6 @@  #include <algorithm>  using namespace clang; -/// Look through spelling locations for a macro argument expansion, and -/// if found skip to it so that we can trace the argument rather than the macros -/// in which that argument is used. If no macro argument expansion is found, -/// don't skip anything and return the starting location. -static SourceLocation skipToMacroArgExpansion(const SourceManager &SM, -                                              SourceLocation StartLoc) { -  for (SourceLocation L = StartLoc; L.isMacroID(); -       L = SM.getImmediateSpellingLoc(L)) { -    if (SM.isMacroArgExpansion(L)) -      return L; -  } -   -  // Otherwise just return initial location, there's nothing to skip. -  return StartLoc; -} - -/// Gets the location of the immediate macro caller, one level up the stack -/// toward the initial macro typed into the source. -static SourceLocation getImmediateMacroCallerLoc(const SourceManager &SM, -                                                 SourceLocation Loc) { -  if (!Loc.isMacroID()) return Loc; -   -  // When we have the location of (part of) an expanded parameter, its spelling -  // location points to the argument as typed into the macro call, and -  // therefore is used to locate the macro caller. -  if (SM.isMacroArgExpansion(Loc)) -    return SM.getImmediateSpellingLoc(Loc); -   -  // Otherwise, the caller of the macro is located where this macro is -  // expanded (while the spelling is part of the macro definition). -  return SM.getImmediateExpansionRange(Loc).first; -} - -/// Gets the location of the immediate macro callee, one level down the stack -/// toward the leaf macro. -static SourceLocation getImmediateMacroCalleeLoc(const SourceManager &SM, -                                                 SourceLocation Loc) { -  if (!Loc.isMacroID()) return Loc; -   -  // When we have the location of (part of) an expanded parameter, its -  // expansion location points to the unexpanded paramater reference within -  // the macro definition (or callee). -  if (SM.isMacroArgExpansion(Loc)) -    return SM.getImmediateExpansionRange(Loc).first; -   -  // Otherwise, the callee of the macro is located where this location was -  // spelled inside the macro definition. -  return SM.getImmediateSpellingLoc(Loc); -} -  /// \brief Retrieve the name of the immediate macro expansion.  ///  /// This routine starts from a source location, and finds the name of the macro @@ -109,24 +59,9 @@ static StringRef getImmediateMacroName(SourceLocation Loc,     return ExpansionBuffer.substr(ExpansionInfo.second, MacroTokenLength);  } -/// Get the presumed location of a diagnostic message. This computes the -/// presumed location for the top of any macro backtrace when present. -static PresumedLoc getDiagnosticPresumedLoc(const SourceManager &SM, -                                            SourceLocation Loc) { -  // This is a condensed form of the algorithm used by emitCaretDiagnostic to -  // walk to the top of the macro call stack. -  while (Loc.isMacroID()) { -    Loc = skipToMacroArgExpansion(SM, Loc); -    Loc = getImmediateMacroCallerLoc(SM, Loc); -  } -   -  return SM.getPresumedLoc(Loc); -} - -DiagnosticRenderer::DiagnosticRenderer(const SourceManager &SM, -                                       const LangOptions &LangOpts, +DiagnosticRenderer::DiagnosticRenderer(const LangOptions &LangOpts,                                         const DiagnosticOptions &DiagOpts) -: SM(SM), LangOpts(LangOpts), DiagOpts(DiagOpts), LastLevel() {} +: LangOpts(LangOpts), DiagOpts(DiagOpts), LastLevel() {}  DiagnosticRenderer::~DiagnosticRenderer() {} @@ -184,18 +119,23 @@ void DiagnosticRenderer::emitDiagnostic(SourceLocation Loc,                                          StringRef Message,                                          ArrayRef<CharSourceRange> Ranges,                                          ArrayRef<FixItHint> FixItHints, +                                        const SourceManager *SM,                                          DiagOrStoredDiag D) { +  assert(SM || Loc.isInvalid());    beginDiagnostic(D, Level); -  PresumedLoc PLoc = getDiagnosticPresumedLoc(SM, Loc); +  PresumedLoc PLoc; +  if (Loc.isValid()) { +    PLoc = SM->getPresumedLocForDisplay(Loc); -  // First, if this diagnostic is not in the main file, print out the -  // "included from" lines. -  emitIncludeStack(PLoc.getIncludeLoc(), Level); +    // First, if this diagnostic is not in the main file, print out the +    // "included from" lines. +    emitIncludeStack(PLoc.getIncludeLoc(), Level, *SM); +  }    // Next, emit the actual diagnostic message. -  emitDiagnosticMessage(Loc, PLoc, Level, Message, Ranges, D); +  emitDiagnosticMessage(Loc, PLoc, Level, Message, Ranges, SM, D);    // Only recurse if we have a valid location.    if (Loc.isValid()) { @@ -205,7 +145,7 @@ void DiagnosticRenderer::emitDiagnostic(SourceLocation Loc,      llvm::SmallVector<FixItHint, 8> MergedFixits;      if (!FixItHints.empty()) { -      mergeFixits(FixItHints, SM, LangOpts, MergedFixits); +      mergeFixits(FixItHints, *SM, LangOpts, MergedFixits);        FixItHints = MergedFixits;      } @@ -216,7 +156,7 @@ void DiagnosticRenderer::emitDiagnostic(SourceLocation Loc,          MutableRanges.push_back(I->RemoveRange);      unsigned MacroDepth = 0; -    emitMacroExpansionsAndCarets(Loc, Level, MutableRanges, FixItHints, +    emitMacroExpansionsAndCarets(Loc, Level, MutableRanges, FixItHints, *SM,                                   MacroDepth);    } @@ -230,6 +170,8 @@ void DiagnosticRenderer::emitDiagnostic(SourceLocation Loc,  void DiagnosticRenderer::emitStoredDiagnostic(StoredDiagnostic &Diag) {    emitDiagnostic(Diag.getLocation(), Diag.getLevel(), Diag.getMessage(),                   Diag.getRanges(), Diag.getFixIts(), +                 Diag.getLocation().isValid() ? &Diag.getLocation().getManager() +                                              : 0,                   &Diag);  } @@ -245,7 +187,8 @@ void DiagnosticRenderer::emitStoredDiagnostic(StoredDiagnostic &Diag) {  /// \param Loc   The include location of the current file (not the diagnostic  ///              location).  void DiagnosticRenderer::emitIncludeStack(SourceLocation Loc, -                                          DiagnosticsEngine::Level Level) { +                                          DiagnosticsEngine::Level Level, +                                          const SourceManager &SM) {    // Skip redundant include stacks altogether.    if (LastIncludeLoc == Loc)      return; @@ -254,12 +197,13 @@ void DiagnosticRenderer::emitIncludeStack(SourceLocation Loc,    if (!DiagOpts.ShowNoteIncludeStack && Level == DiagnosticsEngine::Note)      return; -  emitIncludeStackRecursively(Loc); +  emitIncludeStackRecursively(Loc, SM);  }  /// \brief Helper to recursivly walk up the include stack and print each layer  /// on the way back down. -void DiagnosticRenderer::emitIncludeStackRecursively(SourceLocation Loc) { +void DiagnosticRenderer::emitIncludeStackRecursively(SourceLocation Loc, +                                                     const SourceManager &SM) {    if (Loc.isInvalid())      return; @@ -268,10 +212,10 @@ void DiagnosticRenderer::emitIncludeStackRecursively(SourceLocation Loc) {      return;    // Emit the other include frames first. -  emitIncludeStackRecursively(PLoc.getIncludeLoc()); +  emitIncludeStackRecursively(PLoc.getIncludeLoc(), SM);    // Emit the inclusion text/note. -  emitIncludeLocation(Loc, PLoc); +  emitIncludeLocation(Loc, PLoc, SM);  }  /// \brief Recursively emit notes for each macro expansion and caret @@ -292,6 +236,7 @@ void DiagnosticRenderer::emitMacroExpansionsAndCarets(         DiagnosticsEngine::Level Level,         SmallVectorImpl<CharSourceRange>& Ranges,         ArrayRef<FixItHint> Hints, +       const SourceManager &SM,         unsigned &MacroDepth,         unsigned OnMacroInst)  { @@ -302,26 +247,26 @@ void DiagnosticRenderer::emitMacroExpansionsAndCarets(    if (Loc.isFileID()) {      assert(MacroDepth == 0 && "We shouldn't hit a leaf node twice!");      MacroDepth = OnMacroInst; -    emitCodeContext(Loc, Level, Ranges, Hints); +    emitCodeContext(Loc, Level, Ranges, Hints, SM);      return;    }    // Otherwise recurse through each macro expansion layer.    // When processing macros, skip over the expansions leading up to    // a macro argument, and trace the argument's expansion stack instead. -  Loc = skipToMacroArgExpansion(SM, Loc); +  Loc = SM.skipToMacroArgExpansion(Loc); -  SourceLocation OneLevelUp = getImmediateMacroCallerLoc(SM, Loc); +  SourceLocation OneLevelUp = SM.getImmediateMacroCallerLoc(Loc);    // FIXME: Map ranges? -  emitMacroExpansionsAndCarets(OneLevelUp, Level, Ranges, Hints, MacroDepth, +  emitMacroExpansionsAndCarets(OneLevelUp, Level, Ranges, Hints, SM, MacroDepth,                                 OnMacroInst + 1);    // Save the original location so we can find the spelling of the macro call.    SourceLocation MacroLoc = Loc;    // Map the location. -  Loc = getImmediateMacroCalleeLoc(SM, Loc); +  Loc = SM.getImmediateMacroCalleeLoc(Loc);    unsigned MacroSkipStart = 0, MacroSkipEnd = 0;    if (MacroDepth > DiagOpts.MacroBacktraceLimit && @@ -341,9 +286,9 @@ void DiagnosticRenderer::emitMacroExpansionsAndCarets(         I != E; ++I) {      SourceLocation Start = I->getBegin(), End = I->getEnd();      if (Start.isMacroID()) -      I->setBegin(getImmediateMacroCalleeLoc(SM, Start)); +      I->setBegin(SM.getImmediateMacroCalleeLoc(Start));      if (End.isMacroID()) -      I->setEnd(getImmediateMacroCalleeLoc(SM, End)); +      I->setEnd(SM.getImmediateMacroCalleeLoc(End));    }    if (Suppressed) { @@ -365,22 +310,22 @@ void DiagnosticRenderer::emitMacroExpansionsAndCarets(            << getImmediateMacroName(MacroLoc, SM, LangOpts) << "'";    emitDiagnostic(SM.getSpellingLoc(Loc), DiagnosticsEngine::Note,                   Message.str(), -                 Ranges, ArrayRef<FixItHint>()); +                 Ranges, ArrayRef<FixItHint>(), &SM);  }  DiagnosticNoteRenderer::~DiagnosticNoteRenderer() {}  void DiagnosticNoteRenderer::emitIncludeLocation(SourceLocation Loc, -                                                 PresumedLoc PLoc) { +                                                 PresumedLoc PLoc, +                                                 const SourceManager &SM) {    // Generate a note indicating the include location.    SmallString<200> MessageStorage;    llvm::raw_svector_ostream Message(MessageStorage);    Message << "in file included from " << PLoc.getFilename() << ':'            << PLoc.getLine() << ":"; -  emitNote(Loc, Message.str()); +  emitNote(Loc, Message.str(), &SM);  }  void DiagnosticNoteRenderer::emitBasicNote(StringRef Message) { -  emitNote(SourceLocation(), Message);   +  emitNote(SourceLocation(), Message, 0);    } -  | 
