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:
parent
afa874d4c0
commit
aebee680b6
@ -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 {
|
||||
|
||||
@ -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.
|
||||
///
|
||||
|
||||
@ -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 &&
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user