From aebee680b64fbda9326ec2cf4cd2c9e15a39cb43 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Wed, 5 Dec 2012 06:20:58 +0000 Subject: [PATCH] Simplify slightly by seperating out the responsibility for emission of a caret diagnostic from the emission of macro backtraces. Incidentally, we now get the displayed source location for a diagnostic and the location for the caret from the same place, rather than computing them separately. No functionality change. llvm-svn: 169357 --- clang/include/clang/Basic/SourceManager.h | 12 ---- clang/include/clang/Frontend/DiagnosticRenderer.h | 17 ++--- clang/lib/Frontend/DiagnosticRenderer.cpp | 76 +++++++++++++---------- 3 files changed, 52 insertions(+), 53 deletions(-) diff --git a/clang/include/clang/Basic/SourceManager.h b/clang/include/clang/Basic/SourceManager.h index a69ffad..a2d7a59 100644 --- a/clang/include/clang/Basic/SourceManager.h +++ b/clang/include/clang/Basic/SourceManager.h @@ -1473,18 +1473,6 @@ public: return !isLoadedFileID(FID); } - /// Get a presumed location suitable for displaying in a diagnostic message, - /// taking into account macro arguments and expansions. - PresumedLoc getPresumedLocForDisplay(SourceLocation Loc, - bool UseLineDirectives = true) const{ - // 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 = getImmediateMacroCallerLoc(Loc); - - return getPresumedLoc(Loc, UseLineDirectives); - } - /// Gets the location of the immediate macro caller, one level up the stack /// toward the initial macro typed into the source. SourceLocation getImmediateMacroCallerLoc(SourceLocation Loc) const { diff --git a/clang/include/clang/Frontend/DiagnosticRenderer.h b/clang/include/clang/Frontend/DiagnosticRenderer.h index 4c22e2a..b20a7f0 100644 --- a/clang/include/clang/Frontend/DiagnosticRenderer.h +++ b/clang/include/clang/Frontend/DiagnosticRenderer.h @@ -114,13 +114,16 @@ private: void emitImportStackRecursively(SourceLocation Loc, StringRef ModuleName, const SourceManager &SM); void emitModuleBuildStack(const SourceManager &SM); - void emitMacroExpansionsAndCarets(SourceLocation Loc, - DiagnosticsEngine::Level Level, - SmallVectorImpl& Ranges, - ArrayRef Hints, - const SourceManager &SM, - unsigned &MacroDepth, - unsigned OnMacroInst = 0); + void emitCaret(SourceLocation Loc, DiagnosticsEngine::Level Level, + ArrayRef Ranges, ArrayRef Hints, + const SourceManager &SM); + void emitMacroExpansions(SourceLocation Loc, + DiagnosticsEngine::Level Level, + ArrayRef Ranges, + ArrayRef Hints, + const SourceManager &SM, + unsigned &MacroDepth, + unsigned OnMacroInst = 0); public: /// \brief Emit a diagnostic. /// diff --git a/clang/lib/Frontend/DiagnosticRenderer.cpp b/clang/lib/Frontend/DiagnosticRenderer.cpp index 084c5cb..ded1120 100644 --- a/clang/lib/Frontend/DiagnosticRenderer.cpp +++ b/clang/lib/Frontend/DiagnosticRenderer.cpp @@ -126,17 +126,22 @@ void DiagnosticRenderer::emitDiagnostic(SourceLocation Loc, beginDiagnostic(D, Level); + SourceLocation ExpandedLoc = Loc; PresumedLoc PLoc; if (Loc.isValid()) { - PLoc = SM->getPresumedLocForDisplay(Loc, DiagOpts->ShowPresumedLoc); + // Perform the same walk as emitMacroExpansions, to find the ultimate + // expansion location for the diagnostic. + while (ExpandedLoc.isMacroID()) + ExpandedLoc = SM->getImmediateMacroCallerLoc(ExpandedLoc); + PLoc = SM->getPresumedLoc(ExpandedLoc, DiagOpts->ShowPresumedLoc); // First, if this diagnostic is not in the main file, print out the // "included from" lines. - emitIncludeStack(Loc, PLoc, Level, *SM); + emitIncludeStack(ExpandedLoc, PLoc, Level, *SM); } // Next, emit the actual diagnostic message. - emitDiagnosticMessage(Loc, PLoc, Level, Message, Ranges, SM, D); + emitDiagnosticMessage(ExpandedLoc, PLoc, Level, Message, Ranges, SM, D); // Only recurse if we have a valid location. if (Loc.isValid()) { @@ -155,10 +160,16 @@ void DiagnosticRenderer::emitDiagnostic(SourceLocation Loc, I != E; ++I) if (I->RemoveRange.isValid()) MutableRanges.push_back(I->RemoveRange); - - unsigned MacroDepth = 0; - emitMacroExpansionsAndCarets(Loc, Level, MutableRanges, FixItHints, *SM, - MacroDepth); + + emitCaret(ExpandedLoc, Level, MutableRanges, FixItHints, *SM); + + // If this location is within a macro, walk from the unexpanded location + // up to ExpandedLoc and produce a macro backtrace. + if (Loc.isMacroID()) { + unsigned MacroDepth = 0; + emitMacroExpansions(Loc, Level, MutableRanges, FixItHints, *SM, + MacroDepth); + } } LastLoc = Loc; @@ -302,12 +313,12 @@ void DiagnosticRenderer::emitModuleBuildStack(const SourceManager &SM) { // iff the FileID is the same. static void mapDiagnosticRanges( SourceLocation CaretLoc, - const SmallVectorImpl& Ranges, + ArrayRef Ranges, SmallVectorImpl& SpellingRanges, const SourceManager *SM) { FileID CaretLocFileID = SM->getFileID(CaretLoc); - for (SmallVectorImpl::const_iterator I = Ranges.begin(), + for (ArrayRef::const_iterator I = Ranges.begin(), E = Ranges.end(); I != E; ++I) { SourceLocation Begin = I->getBegin(), End = I->getEnd(); @@ -357,6 +368,16 @@ static void mapDiagnosticRanges( } } +void DiagnosticRenderer::emitCaret(SourceLocation Loc, + DiagnosticsEngine::Level Level, + ArrayRef Ranges, + ArrayRef Hints, + const SourceManager &SM) { + SmallVector SpellingRanges; + mapDiagnosticRanges(Loc, Ranges, SpellingRanges, &SM); + emitCodeContext(Loc, Level, SpellingRanges, Hints, SM); +} + /// \brief Recursively emit notes for each macro expansion and caret /// diagnostics where appropriate. /// @@ -370,35 +391,22 @@ static void mapDiagnosticRanges( /// \param Hints The FixIt hints active for this diagnostic. /// \param MacroSkipEnd The depth to stop skipping macro expansions. /// \param OnMacroInst The current depth of the macro expansion stack. -void DiagnosticRenderer::emitMacroExpansionsAndCarets( - SourceLocation Loc, - DiagnosticsEngine::Level Level, - SmallVectorImpl& Ranges, - ArrayRef Hints, - const SourceManager &SM, - unsigned &MacroDepth, - unsigned OnMacroInst) -{ +void DiagnosticRenderer::emitMacroExpansions(SourceLocation Loc, + DiagnosticsEngine::Level Level, + ArrayRef Ranges, + ArrayRef Hints, + const SourceManager &SM, + unsigned &MacroDepth, + unsigned OnMacroInst) { assert(!Loc.isInvalid() && "must have a valid source location here"); - // If this is a file source location, directly emit the source snippet and - // caret line. Also record the macro depth reached. - if (Loc.isFileID()) { - // Map the ranges. - SmallVector SpellingRanges; - mapDiagnosticRanges(Loc, Ranges, SpellingRanges, &SM); - - assert(MacroDepth == 0 && "We shouldn't hit a leaf node twice!"); - MacroDepth = OnMacroInst; - emitCodeContext(Loc, Level, SpellingRanges, Hints, SM); - return; - } - // Otherwise recurse through each macro expansion layer. - // Walk up to the caller of this macro, and produce a backtrace down to there. SourceLocation OneLevelUp = SM.getImmediateMacroCallerLoc(Loc); - emitMacroExpansionsAndCarets(OneLevelUp, Level, Ranges, Hints, SM, MacroDepth, - OnMacroInst + 1); + if (OneLevelUp.isMacroID()) + emitMacroExpansions(OneLevelUp, Level, Ranges, Hints, SM, + MacroDepth, OnMacroInst + 1); + else + MacroDepth = OnMacroInst + 1; unsigned MacroSkipStart = 0, MacroSkipEnd = 0; if (MacroDepth > DiagOpts->MacroBacktraceLimit && -- 2.7.4