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
This commit is contained in:
Richard Smith 2012-12-05 06:20:58 +00:00
parent afa874d4c0
commit aebee680b6
3 changed files with 52 additions and 53 deletions

View File

@ -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 {

View File

@ -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<CharSourceRange>& Ranges,
ArrayRef<FixItHint> Hints,
const SourceManager &SM,
unsigned &MacroDepth,
unsigned OnMacroInst = 0);
void emitCaret(SourceLocation Loc, DiagnosticsEngine::Level Level,
ArrayRef<CharSourceRange> Ranges, ArrayRef<FixItHint> Hints,
const SourceManager &SM);
void emitMacroExpansions(SourceLocation Loc,
DiagnosticsEngine::Level Level,
ArrayRef<CharSourceRange> Ranges,
ArrayRef<FixItHint> Hints,
const SourceManager &SM,
unsigned &MacroDepth,
unsigned OnMacroInst = 0);
public:
/// \brief Emit a diagnostic.
///

View File

@ -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<CharSourceRange>& Ranges,
ArrayRef<CharSourceRange> Ranges,
SmallVectorImpl<CharSourceRange>& SpellingRanges,
const SourceManager *SM) {
FileID CaretLocFileID = SM->getFileID(CaretLoc);
for (SmallVectorImpl<CharSourceRange>::const_iterator I = Ranges.begin(),
for (ArrayRef<CharSourceRange>::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<CharSourceRange> Ranges,
ArrayRef<FixItHint> Hints,
const SourceManager &SM) {
SmallVector<CharSourceRange, 4> 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<CharSourceRange>& Ranges,
ArrayRef<FixItHint> Hints,
const SourceManager &SM,
unsigned &MacroDepth,
unsigned OnMacroInst)
{
void DiagnosticRenderer::emitMacroExpansions(SourceLocation Loc,
DiagnosticsEngine::Level Level,
ArrayRef<CharSourceRange> Ranges,
ArrayRef<FixItHint> 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<CharSourceRange, 4> 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 &&