[NFC] Refactor DiagnosticRenderer to use FullSourceLoc

Move the DiagnosticRenderer and its dependents to using FullSourceLocs
instead of a SourceLocation and SourceManager pointer. The changeset is
rather large but entirely mechanical.

This is step one to allow DiagnosticRenderer to take either
llvm::SMLocs or clang::SourceLocations.

Patch by Sanne Wouda

Review: https://reviews.llvm.org/D31709

Change-Id: If351a112cdf6718e2d3ef6721b8da9c6376b32dd
llvm-svn: 305684
This commit is contained in:
Christof Douma 2017-06-19 12:05:58 +00:00
parent 78aaf7db04
commit f9d86db755
9 changed files with 377 additions and 363 deletions

View File

@ -262,6 +262,65 @@ public:
bool isInvalid() const { return !isValid(); }
};
/// \brief Represents an unpacked "presumed" location which can be presented
/// to the user.
///
/// A 'presumed' location can be modified by \#line and GNU line marker
/// directives and is always the expansion point of a normal location.
///
/// You can get a PresumedLoc from a SourceLocation with SourceManager.
class PresumedLoc {
const char *Filename;
unsigned Line, Col;
SourceLocation IncludeLoc;
public:
PresumedLoc() : Filename(nullptr) {}
PresumedLoc(const char *FN, unsigned Ln, unsigned Co, SourceLocation IL)
: Filename(FN), Line(Ln), Col(Co), IncludeLoc(IL) {}
/// \brief Return true if this object is invalid or uninitialized.
///
/// This occurs when created with invalid source locations or when walking
/// off the top of a \#include stack.
bool isInvalid() const { return Filename == nullptr; }
bool isValid() const { return Filename != nullptr; }
/// \brief Return the presumed filename of this location.
///
/// This can be affected by \#line etc.
const char *getFilename() const {
assert(isValid());
return Filename;
}
/// \brief Return the presumed line number of this location.
///
/// This can be affected by \#line etc.
unsigned getLine() const {
assert(isValid());
return Line;
}
/// \brief Return the presumed column number of this location.
///
/// This cannot be affected by \#line, but is packaged here for convenience.
unsigned getColumn() const {
assert(isValid());
return Col;
}
/// \brief Return the presumed include location of this location.
///
/// This can be affected by GNU linemarker directives.
SourceLocation getIncludeLoc() const {
assert(isValid());
return IncludeLoc;
}
};
class FileEntry;
/// \brief A SourceLocation and its associated SourceManager.
///
/// This is useful for argument passing to functions that expect both objects.
@ -274,6 +333,12 @@ public:
explicit FullSourceLoc(SourceLocation Loc, const SourceManager &SM)
: SourceLocation(Loc), SrcMgr(&SM) {}
bool hasManager() const {
bool hasSrcMgr = SrcMgr != nullptr;
assert(hasSrcMgr == isValid() && "FullSourceLoc has location but no manager");
return hasSrcMgr;
}
/// \pre This FullSourceLoc has an associated SourceManager.
const SourceManager &getManager() const {
assert(SrcMgr && "SourceManager is NULL.");
@ -284,6 +349,13 @@ public:
FullSourceLoc getExpansionLoc() const;
FullSourceLoc getSpellingLoc() const;
FullSourceLoc getFileLoc() const;
std::pair<FullSourceLoc, FullSourceLoc> getImmediateExpansionRange() const;
PresumedLoc getPresumedLoc(bool UseLineDirectives = true) const;
bool isMacroArgExpansion(FullSourceLoc *StartLoc = nullptr) const;
FullSourceLoc getImmediateMacroCallerLoc() const;
std::pair<FullSourceLoc, StringRef> getModuleImportLoc() const;
unsigned getFileOffset() const;
unsigned getExpansionLineNumber(bool *Invalid = nullptr) const;
unsigned getExpansionColumnNumber(bool *Invalid = nullptr) const;
@ -293,6 +365,12 @@ public:
const char *getCharacterData(bool *Invalid = nullptr) const;
unsigned getLineNumber(bool *Invalid = nullptr) const;
unsigned getColumnNumber(bool *Invalid = nullptr) const;
std::pair<FullSourceLoc, FullSourceLoc> getExpansionRange() const;
const FileEntry *getFileEntry() const;
/// \brief Return a StringRef to the source buffer data for the
/// specified FileID.
@ -345,50 +423,6 @@ public:
};
/// \brief Represents an unpacked "presumed" location which can be presented
/// to the user.
///
/// A 'presumed' location can be modified by \#line and GNU line marker
/// directives and is always the expansion point of a normal location.
///
/// You can get a PresumedLoc from a SourceLocation with SourceManager.
class PresumedLoc {
const char *Filename;
unsigned Line, Col;
SourceLocation IncludeLoc;
public:
PresumedLoc() : Filename(nullptr) {}
PresumedLoc(const char *FN, unsigned Ln, unsigned Co, SourceLocation IL)
: Filename(FN), Line(Ln), Col(Co), IncludeLoc(IL) {
}
/// \brief Return true if this object is invalid or uninitialized.
///
/// This occurs when created with invalid source locations or when walking
/// off the top of a \#include stack.
bool isInvalid() const { return Filename == nullptr; }
bool isValid() const { return Filename != nullptr; }
/// \brief Return the presumed filename of this location.
///
/// This can be affected by \#line etc.
const char *getFilename() const { assert(isValid()); return Filename; }
/// \brief Return the presumed line number of this location.
///
/// This can be affected by \#line etc.
unsigned getLine() const { assert(isValid()); return Line; }
/// \brief Return the presumed column number of this location.
///
/// This cannot be affected by \#line, but is packaged here for convenience.
unsigned getColumn() const { assert(isValid()); return Col; }
/// \brief Return the presumed include location of this location.
///
/// This can be affected by GNU linemarker directives.
SourceLocation getIncludeLoc() const { assert(isValid()); return IncludeLoc; }
};
} // end namespace clang

View File

@ -70,33 +70,27 @@ protected:
DiagnosticOptions *DiagOpts);
virtual ~DiagnosticRenderer();
virtual void emitDiagnosticMessage(SourceLocation Loc, PresumedLoc PLoc,
virtual void emitDiagnosticMessage(FullSourceLoc Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level,
StringRef Message,
ArrayRef<CharSourceRange> Ranges,
const SourceManager *SM,
DiagOrStoredDiag Info) = 0;
virtual void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level,
ArrayRef<CharSourceRange> Ranges,
const SourceManager &SM) = 0;
virtual void emitCodeContext(SourceLocation Loc,
virtual void emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level,
ArrayRef<CharSourceRange> Ranges) = 0;
virtual void emitCodeContext(FullSourceLoc Loc,
DiagnosticsEngine::Level Level,
SmallVectorImpl<CharSourceRange>& Ranges,
ArrayRef<FixItHint> Hints,
const SourceManager &SM) = 0;
virtual void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc,
const SourceManager &SM) = 0;
virtual void emitImportLocation(SourceLocation Loc, PresumedLoc PLoc,
StringRef ModuleName,
const SourceManager &SM) = 0;
virtual void emitBuildingModuleLocation(SourceLocation Loc, PresumedLoc PLoc,
StringRef ModuleName,
const SourceManager &SM) = 0;
SmallVectorImpl<CharSourceRange> &Ranges,
ArrayRef<FixItHint> Hints) = 0;
virtual void emitIncludeLocation(FullSourceLoc Loc, PresumedLoc PLoc) = 0;
virtual void emitImportLocation(FullSourceLoc Loc, PresumedLoc PLoc,
StringRef ModuleName) = 0;
virtual void emitBuildingModuleLocation(FullSourceLoc Loc, PresumedLoc PLoc,
StringRef ModuleName) = 0;
virtual void beginDiagnostic(DiagOrStoredDiag D,
DiagnosticsEngine::Level Level) {}
@ -106,25 +100,21 @@ protected:
private:
void emitBasicNote(StringRef Message);
void emitIncludeStack(SourceLocation Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level, const SourceManager &SM);
void emitIncludeStackRecursively(SourceLocation Loc, const SourceManager &SM);
void emitImportStack(SourceLocation Loc, const SourceManager &SM);
void emitImportStackRecursively(SourceLocation Loc, StringRef ModuleName,
const SourceManager &SM);
void emitIncludeStack(FullSourceLoc Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level);
void emitIncludeStackRecursively(FullSourceLoc Loc);
void emitImportStack(FullSourceLoc Loc);
void emitImportStackRecursively(FullSourceLoc Loc, StringRef ModuleName);
void emitModuleBuildStack(const SourceManager &SM);
void emitCaret(SourceLocation Loc, DiagnosticsEngine::Level Level,
ArrayRef<CharSourceRange> Ranges, ArrayRef<FixItHint> Hints,
const SourceManager &SM);
void emitSingleMacroExpansion(SourceLocation Loc,
void emitCaret(FullSourceLoc Loc, DiagnosticsEngine::Level Level,
ArrayRef<CharSourceRange> Ranges, ArrayRef<FixItHint> Hints);
void emitSingleMacroExpansion(FullSourceLoc Loc,
DiagnosticsEngine::Level Level,
ArrayRef<CharSourceRange> Ranges,
const SourceManager &SM);
void emitMacroExpansions(SourceLocation Loc,
DiagnosticsEngine::Level Level,
ArrayRef<CharSourceRange> Ranges);
void emitMacroExpansions(FullSourceLoc Loc, DiagnosticsEngine::Level Level,
ArrayRef<CharSourceRange> Ranges,
ArrayRef<FixItHint> Hints,
const SourceManager &SM);
ArrayRef<FixItHint> Hints);
public:
/// \brief Emit a diagnostic.
///
@ -140,10 +130,9 @@ public:
/// \param FixItHints The FixIt hints active for this diagnostic.
/// \param SM The SourceManager; will be null if the diagnostic came from the
/// frontend, thus \p Loc will be invalid.
void emitDiagnostic(SourceLocation Loc, DiagnosticsEngine::Level Level,
void emitDiagnostic(FullSourceLoc Loc, DiagnosticsEngine::Level Level,
StringRef Message, ArrayRef<CharSourceRange> Ranges,
ArrayRef<FixItHint> FixItHints,
const SourceManager *SM,
DiagOrStoredDiag D = (Diagnostic *)nullptr);
void emitStoredDiagnostic(StoredDiagnostic &Diag);
@ -159,19 +148,15 @@ public:
~DiagnosticNoteRenderer() override;
void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc,
const SourceManager &SM) override;
void emitIncludeLocation(FullSourceLoc Loc, PresumedLoc PLoc) override;
void emitImportLocation(SourceLocation Loc, PresumedLoc PLoc,
StringRef ModuleName,
const SourceManager &SM) override;
void emitImportLocation(FullSourceLoc Loc, PresumedLoc PLoc,
StringRef ModuleName) override;
void emitBuildingModuleLocation(SourceLocation Loc, PresumedLoc PLoc,
StringRef ModuleName,
const SourceManager &SM) override;
void emitBuildingModuleLocation(FullSourceLoc Loc, PresumedLoc PLoc,
StringRef ModuleName) override;
virtual void emitNote(SourceLocation Loc, StringRef Message,
const SourceManager *SM) = 0;
virtual void emitNote(FullSourceLoc Loc, StringRef Message) = 0;
};
} // end clang namespace
#endif

View File

@ -75,44 +75,35 @@ public:
unsigned Columns, bool ShowColors);
protected:
void emitDiagnosticMessage(SourceLocation Loc,PresumedLoc PLoc,
DiagnosticsEngine::Level Level,
StringRef Message,
void emitDiagnosticMessage(FullSourceLoc Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level, StringRef Message,
ArrayRef<CharSourceRange> Ranges,
const SourceManager *SM,
DiagOrStoredDiag D) override;
void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
void emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level,
ArrayRef<CharSourceRange> Ranges,
const SourceManager &SM) override;
ArrayRef<CharSourceRange> Ranges) override;
void emitCodeContext(SourceLocation Loc,
DiagnosticsEngine::Level Level,
SmallVectorImpl<CharSourceRange>& Ranges,
ArrayRef<FixItHint> Hints,
const SourceManager &SM) override {
emitSnippetAndCaret(Loc, Level, Ranges, Hints, SM);
void emitCodeContext(FullSourceLoc Loc, DiagnosticsEngine::Level Level,
SmallVectorImpl<CharSourceRange> &Ranges,
ArrayRef<FixItHint> Hints) override {
emitSnippetAndCaret(Loc, Level, Ranges, Hints);
}
void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc,
const SourceManager &SM) override;
void emitIncludeLocation(FullSourceLoc Loc, PresumedLoc PLoc) override;
void emitImportLocation(SourceLocation Loc, PresumedLoc PLoc,
StringRef ModuleName,
const SourceManager &SM) override;
void emitImportLocation(FullSourceLoc Loc, PresumedLoc PLoc,
StringRef ModuleName) override;
void emitBuildingModuleLocation(SourceLocation Loc, PresumedLoc PLoc,
StringRef ModuleName,
const SourceManager &SM) override;
void emitBuildingModuleLocation(FullSourceLoc Loc, PresumedLoc PLoc,
StringRef ModuleName) override;
private:
void emitFilename(StringRef Filename, const SourceManager &SM);
void emitSnippetAndCaret(SourceLocation Loc, DiagnosticsEngine::Level Level,
SmallVectorImpl<CharSourceRange>& Ranges,
ArrayRef<FixItHint> Hints,
const SourceManager &SM);
void emitSnippetAndCaret(FullSourceLoc Loc, DiagnosticsEngine::Level Level,
SmallVectorImpl<CharSourceRange> &Ranges,
ArrayRef<FixItHint> Hints);
void emitSnippet(StringRef SourceLine);

View File

@ -92,6 +92,76 @@ FullSourceLoc FullSourceLoc::getSpellingLoc() const {
return FullSourceLoc(SrcMgr->getSpellingLoc(*this), *SrcMgr);
}
FullSourceLoc FullSourceLoc::getFileLoc() const {
assert(isValid());
return FullSourceLoc(SrcMgr->getFileLoc(*this), *SrcMgr);
}
std::pair<FullSourceLoc, FullSourceLoc>
FullSourceLoc::getImmediateExpansionRange() const {
assert(isValid());
std::pair<SourceLocation, SourceLocation> Range =
SrcMgr->getImmediateExpansionRange(*this);
return std::make_pair(FullSourceLoc(Range.first, *SrcMgr),
FullSourceLoc(Range.second, *SrcMgr));
}
PresumedLoc FullSourceLoc::getPresumedLoc(bool UseLineDirectives) const {
if (!isValid())
return PresumedLoc();
return SrcMgr->getPresumedLoc(*this, UseLineDirectives);
}
bool FullSourceLoc::isMacroArgExpansion(FullSourceLoc *StartLoc) const {
assert(isValid());
return SrcMgr->isMacroArgExpansion(*this, StartLoc);
}
FullSourceLoc FullSourceLoc::getImmediateMacroCallerLoc() const {
assert(isValid());
return FullSourceLoc(SrcMgr->getImmediateMacroCallerLoc(*this), *SrcMgr);
}
std::pair<FullSourceLoc, StringRef> FullSourceLoc::getModuleImportLoc() const {
if (!isValid())
return std::make_pair(FullSourceLoc(), StringRef());
std::pair<SourceLocation, StringRef> ImportLoc =
SrcMgr->getModuleImportLoc(*this);
return std::make_pair(FullSourceLoc(ImportLoc.first, *SrcMgr),
ImportLoc.second);
}
unsigned FullSourceLoc::getFileOffset() const {
assert(isValid());
return SrcMgr->getFileOffset(*this);
}
unsigned FullSourceLoc::getLineNumber(bool *Invalid) const {
assert(isValid());
return SrcMgr->getLineNumber(getFileID(), getFileOffset(), Invalid);
}
unsigned FullSourceLoc::getColumnNumber(bool *Invalid) const {
assert(isValid());
return SrcMgr->getColumnNumber(getFileID(), getFileOffset(), Invalid);
}
std::pair<FullSourceLoc, FullSourceLoc>
FullSourceLoc::getExpansionRange() const {
assert(isValid());
std::pair<SourceLocation, SourceLocation> Range =
SrcMgr->getExpansionRange(*this);
return std::make_pair(FullSourceLoc(Range.first, *SrcMgr),
FullSourceLoc(Range.second, *SrcMgr));
}
const FileEntry *FullSourceLoc::getFileEntry() const {
assert(isValid());
return SrcMgr->getFileEntryForID(getFileID());
}
unsigned FullSourceLoc::getExpansionLineNumber(bool *Invalid) const {
assert(isValid());
return SrcMgr->getExpansionLineNumber(*this, Invalid);

View File

@ -76,20 +76,19 @@ static void mergeFixits(ArrayRef<FixItHint> FixItHints,
}
}
void DiagnosticRenderer::emitDiagnostic(SourceLocation Loc,
void DiagnosticRenderer::emitDiagnostic(FullSourceLoc Loc,
DiagnosticsEngine::Level Level,
StringRef Message,
ArrayRef<CharSourceRange> Ranges,
ArrayRef<FixItHint> FixItHints,
const SourceManager *SM,
DiagOrStoredDiag D) {
assert(SM || Loc.isInvalid());
assert(Loc.hasManager() || Loc.isInvalid());
beginDiagnostic(D, Level);
if (!Loc.isValid())
// If we have no source location, just emit the diagnostic message.
emitDiagnosticMessage(Loc, PresumedLoc(), Level, Message, Ranges, SM, D);
emitDiagnosticMessage(Loc, PresumedLoc(), Level, Message, Ranges, D);
else {
// Get the ranges into a local array we can hack on.
SmallVector<CharSourceRange, 20> MutableRanges(Ranges.begin(),
@ -97,7 +96,7 @@ void DiagnosticRenderer::emitDiagnostic(SourceLocation Loc,
SmallVector<FixItHint, 8> MergedFixits;
if (!FixItHints.empty()) {
mergeFixits(FixItHints, *SM, LangOpts, MergedFixits);
mergeFixits(FixItHints, Loc.getManager(), LangOpts, MergedFixits);
FixItHints = MergedFixits;
}
@ -107,25 +106,25 @@ void DiagnosticRenderer::emitDiagnostic(SourceLocation Loc,
if (I->RemoveRange.isValid())
MutableRanges.push_back(I->RemoveRange);
SourceLocation UnexpandedLoc = Loc;
FullSourceLoc UnexpandedLoc = Loc;
// Find the ultimate expansion location for the diagnostic.
Loc = SM->getFileLoc(Loc);
Loc = Loc.getFileLoc();
PresumedLoc PLoc = SM->getPresumedLoc(Loc, DiagOpts->ShowPresumedLoc);
PresumedLoc PLoc = Loc.getPresumedLoc(DiagOpts->ShowPresumedLoc);
// First, if this diagnostic is not in the main file, print out the
// "included from" lines.
emitIncludeStack(Loc, PLoc, Level, *SM);
emitIncludeStack(Loc, PLoc, Level);
// Next, emit the actual diagnostic message and caret.
emitDiagnosticMessage(Loc, PLoc, Level, Message, Ranges, SM, D);
emitCaret(Loc, Level, MutableRanges, FixItHints, *SM);
emitDiagnosticMessage(Loc, PLoc, Level, Message, Ranges, D);
emitCaret(Loc, Level, MutableRanges, FixItHints);
// If this location is within a macro, walk from UnexpandedLoc up to Loc
// and produce a macro backtrace.
if (UnexpandedLoc.isValid() && UnexpandedLoc.isMacroID()) {
emitMacroExpansions(UnexpandedLoc, Level, MutableRanges, FixItHints, *SM);
emitMacroExpansions(UnexpandedLoc, Level, MutableRanges, FixItHints);
}
}
@ -139,15 +138,12 @@ 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()
: nullptr,
&Diag);
}
void DiagnosticRenderer::emitBasicNote(StringRef Message) {
emitDiagnosticMessage(
SourceLocation(), PresumedLoc(), DiagnosticsEngine::Note, Message,
None, nullptr, DiagOrStoredDiag());
emitDiagnosticMessage(FullSourceLoc(), PresumedLoc(), DiagnosticsEngine::Note,
Message, None, DiagOrStoredDiag());
}
/// \brief Prints an include stack when appropriate for a particular
@ -161,12 +157,11 @@ void DiagnosticRenderer::emitBasicNote(StringRef Message) {
/// \param Loc The diagnostic location.
/// \param PLoc The presumed location of the diagnostic location.
/// \param Level The diagnostic level of the message this stack pertains to.
void DiagnosticRenderer::emitIncludeStack(SourceLocation Loc,
PresumedLoc PLoc,
DiagnosticsEngine::Level Level,
const SourceManager &SM) {
SourceLocation IncludeLoc =
PLoc.isInvalid() ? SourceLocation() : PLoc.getIncludeLoc();
void DiagnosticRenderer::emitIncludeStack(FullSourceLoc Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level) {
FullSourceLoc IncludeLoc =
PLoc.isInvalid() ? FullSourceLoc()
: FullSourceLoc(PLoc.getIncludeLoc(), Loc.getManager());
// Skip redundant include stacks altogether.
if (LastIncludeLoc == IncludeLoc)
@ -178,74 +173,70 @@ void DiagnosticRenderer::emitIncludeStack(SourceLocation Loc,
return;
if (IncludeLoc.isValid())
emitIncludeStackRecursively(IncludeLoc, SM);
emitIncludeStackRecursively(IncludeLoc);
else {
emitModuleBuildStack(SM);
emitImportStack(Loc, SM);
emitModuleBuildStack(Loc.getManager());
emitImportStack(Loc);
}
}
/// \brief Helper to recursivly walk up the include stack and print each layer
/// on the way back down.
void DiagnosticRenderer::emitIncludeStackRecursively(SourceLocation Loc,
const SourceManager &SM) {
void DiagnosticRenderer::emitIncludeStackRecursively(FullSourceLoc Loc) {
if (Loc.isInvalid()) {
emitModuleBuildStack(SM);
emitModuleBuildStack(Loc.getManager());
return;
}
PresumedLoc PLoc = SM.getPresumedLoc(Loc, DiagOpts->ShowPresumedLoc);
PresumedLoc PLoc = Loc.getPresumedLoc(DiagOpts->ShowPresumedLoc);
if (PLoc.isInvalid())
return;
// If this source location was imported from a module, print the module
// import stack rather than the
// FIXME: We want submodule granularity here.
std::pair<SourceLocation, StringRef> Imported = SM.getModuleImportLoc(Loc);
std::pair<FullSourceLoc, StringRef> Imported = Loc.getModuleImportLoc();
if (!Imported.second.empty()) {
// This location was imported by a module. Emit the module import stack.
emitImportStackRecursively(Imported.first, Imported.second, SM);
emitImportStackRecursively(Imported.first, Imported.second);
return;
}
// Emit the other include frames first.
emitIncludeStackRecursively(PLoc.getIncludeLoc(), SM);
emitIncludeStackRecursively(
FullSourceLoc(PLoc.getIncludeLoc(), Loc.getManager()));
// Emit the inclusion text/note.
emitIncludeLocation(Loc, PLoc, SM);
emitIncludeLocation(Loc, PLoc);
}
/// \brief Emit the module import stack associated with the current location.
void DiagnosticRenderer::emitImportStack(SourceLocation Loc,
const SourceManager &SM) {
void DiagnosticRenderer::emitImportStack(FullSourceLoc Loc) {
if (Loc.isInvalid()) {
emitModuleBuildStack(SM);
emitModuleBuildStack(Loc.getManager());
return;
}
std::pair<SourceLocation, StringRef> NextImportLoc
= SM.getModuleImportLoc(Loc);
emitImportStackRecursively(NextImportLoc.first, NextImportLoc.second, SM);
std::pair<FullSourceLoc, StringRef> NextImportLoc = Loc.getModuleImportLoc();
emitImportStackRecursively(NextImportLoc.first, NextImportLoc.second);
}
/// \brief Helper to recursivly walk up the import stack and print each layer
/// on the way back down.
void DiagnosticRenderer::emitImportStackRecursively(SourceLocation Loc,
StringRef ModuleName,
const SourceManager &SM) {
void DiagnosticRenderer::emitImportStackRecursively(FullSourceLoc Loc,
StringRef ModuleName) {
if (ModuleName.empty()) {
return;
}
PresumedLoc PLoc = SM.getPresumedLoc(Loc, DiagOpts->ShowPresumedLoc);
PresumedLoc PLoc = Loc.getPresumedLoc(DiagOpts->ShowPresumedLoc);
// Emit the other import frames first.
std::pair<SourceLocation, StringRef> NextImportLoc
= SM.getModuleImportLoc(Loc);
emitImportStackRecursively(NextImportLoc.first, NextImportLoc.second, SM);
std::pair<FullSourceLoc, StringRef> NextImportLoc = Loc.getModuleImportLoc();
emitImportStackRecursively(NextImportLoc.first, NextImportLoc.second);
// Emit the inclusion text/note.
emitImportLocation(Loc, PLoc, ModuleName, SM);
emitImportLocation(Loc, PLoc, ModuleName);
}
/// \brief Emit the module build stack, for cases where a module is (re-)built
@ -253,13 +244,9 @@ void DiagnosticRenderer::emitImportStackRecursively(SourceLocation Loc,
void DiagnosticRenderer::emitModuleBuildStack(const SourceManager &SM) {
ModuleBuildStack Stack = SM.getModuleBuildStack();
for (unsigned I = 0, N = Stack.size(); I != N; ++I) {
const SourceManager &CurSM = Stack[I].second.getManager();
SourceLocation CurLoc = Stack[I].second;
emitBuildingModuleLocation(CurLoc,
CurSM.getPresumedLoc(CurLoc,
emitBuildingModuleLocation(Stack[I].second, Stack[I].second.getPresumedLoc(
DiagOpts->ShowPresumedLoc),
Stack[I].first,
CurSM);
Stack[I].first);
}
}
@ -348,12 +335,12 @@ static void computeCommonMacroArgExpansionFileIDs(
// in the same expansion as the caret; otherwise, we crawl to the top of
// each chain. Two locations are part of the same macro expansion
// iff the FileID is the same.
static void mapDiagnosticRanges(
SourceLocation CaretLoc,
ArrayRef<CharSourceRange> Ranges,
SmallVectorImpl<CharSourceRange> &SpellingRanges,
const SourceManager *SM) {
FileID CaretLocFileID = SM->getFileID(CaretLoc);
static void
mapDiagnosticRanges(FullSourceLoc CaretLoc, ArrayRef<CharSourceRange> Ranges,
SmallVectorImpl<CharSourceRange> &SpellingRanges) {
FileID CaretLocFileID = CaretLoc.getFileID();
const SourceManager *SM = &CaretLoc.getManager();
for (auto I = Ranges.begin(), E = Ranges.end(); I != E; ++I) {
if (I->isInvalid()) continue;
@ -404,42 +391,39 @@ static void mapDiagnosticRanges(
}
}
void DiagnosticRenderer::emitCaret(SourceLocation Loc,
void DiagnosticRenderer::emitCaret(FullSourceLoc Loc,
DiagnosticsEngine::Level Level,
ArrayRef<CharSourceRange> Ranges,
ArrayRef<FixItHint> Hints,
const SourceManager &SM) {
ArrayRef<FixItHint> Hints) {
SmallVector<CharSourceRange, 4> SpellingRanges;
mapDiagnosticRanges(Loc, Ranges, SpellingRanges, &SM);
emitCodeContext(Loc, Level, SpellingRanges, Hints, SM);
mapDiagnosticRanges(Loc, Ranges, SpellingRanges);
emitCodeContext(Loc, Level, SpellingRanges, Hints);
}
/// \brief A helper function for emitMacroExpansion to print the
/// macro expansion message
void DiagnosticRenderer::emitSingleMacroExpansion(
SourceLocation Loc,
DiagnosticsEngine::Level Level,
ArrayRef<CharSourceRange> Ranges,
const SourceManager &SM) {
FullSourceLoc Loc, DiagnosticsEngine::Level Level,
ArrayRef<CharSourceRange> Ranges) {
// Find the spelling location for the macro definition. We must use the
// spelling location here to avoid emitting a macro backtrace for the note.
SourceLocation SpellingLoc = SM.getSpellingLoc(Loc);
FullSourceLoc SpellingLoc = Loc.getSpellingLoc();
// Map the ranges into the FileID of the diagnostic location.
SmallVector<CharSourceRange, 4> SpellingRanges;
mapDiagnosticRanges(Loc, Ranges, SpellingRanges, &SM);
mapDiagnosticRanges(Loc, Ranges, SpellingRanges);
SmallString<100> MessageStorage;
llvm::raw_svector_ostream Message(MessageStorage);
StringRef MacroName =
Lexer::getImmediateMacroNameForDiagnostics(Loc, SM, LangOpts);
StringRef MacroName = Lexer::getImmediateMacroNameForDiagnostics(
Loc, Loc.getManager(), LangOpts);
if (MacroName.empty())
Message << "expanded from here";
else
Message << "expanded from macro '" << MacroName << "'";
emitDiagnostic(SpellingLoc, DiagnosticsEngine::Note, Message.str(),
SpellingRanges, None, &SM);
SpellingRanges, None);
}
/// Check that the macro argument location of Loc starts with ArgumentLoc.
@ -473,13 +457,12 @@ static bool checkRangeForMacroArgExpansion(CharSourceRange Range,
/// A helper function to check if the current ranges are all inside the same
/// macro argument expansion as Loc.
static bool checkRangesForMacroArgExpansion(SourceLocation Loc,
ArrayRef<CharSourceRange> Ranges,
const SourceManager &SM) {
static bool checkRangesForMacroArgExpansion(FullSourceLoc Loc,
ArrayRef<CharSourceRange> Ranges) {
assert(Loc.isMacroID() && "Must be a macro expansion!");
SmallVector<CharSourceRange, 4> SpellingRanges;
mapDiagnosticRanges(Loc, Ranges, SpellingRanges, &SM);
mapDiagnosticRanges(Loc, Ranges, SpellingRanges);
/// Count all valid ranges.
unsigned ValidCount = 0;
@ -490,15 +473,15 @@ static bool checkRangesForMacroArgExpansion(SourceLocation Loc,
return false;
/// To store the source location of the argument location.
SourceLocation ArgumentLoc;
FullSourceLoc ArgumentLoc;
/// Set the ArgumentLoc to the beginning location of the expansion of Loc
/// so to check if the ranges expands to the same beginning location.
if (!SM.isMacroArgExpansion(Loc,&ArgumentLoc))
if (!Loc.isMacroArgExpansion(&ArgumentLoc))
return false;
for (auto I = SpellingRanges.begin(), E = SpellingRanges.end(); I != E; ++I) {
if (!checkRangeForMacroArgExpansion(*I, SM, ArgumentLoc))
if (!checkRangeForMacroArgExpansion(*I, Loc.getManager(), ArgumentLoc))
return false;
}
@ -516,34 +499,33 @@ static bool checkRangesForMacroArgExpansion(SourceLocation Loc,
/// \param Level The diagnostic level currently being emitted.
/// \param Ranges The underlined ranges for this code snippet.
/// \param Hints The FixIt hints active for this diagnostic.
void DiagnosticRenderer::emitMacroExpansions(SourceLocation Loc,
void DiagnosticRenderer::emitMacroExpansions(FullSourceLoc Loc,
DiagnosticsEngine::Level Level,
ArrayRef<CharSourceRange> Ranges,
ArrayRef<FixItHint> Hints,
const SourceManager &SM) {
ArrayRef<FixItHint> Hints) {
assert(Loc.isValid() && "must have a valid source location here");
// Produce a stack of macro backtraces.
SmallVector<SourceLocation, 8> LocationStack;
SmallVector<FullSourceLoc, 8> LocationStack;
unsigned IgnoredEnd = 0;
while (Loc.isMacroID()) {
// If this is the expansion of a macro argument, point the caret at the
// use of the argument in the definition of the macro, not the expansion.
if (SM.isMacroArgExpansion(Loc))
LocationStack.push_back(SM.getImmediateExpansionRange(Loc).first);
if (Loc.isMacroArgExpansion())
LocationStack.push_back(Loc.getImmediateExpansionRange().first);
else
LocationStack.push_back(Loc);
if (checkRangesForMacroArgExpansion(Loc, Ranges, SM))
if (checkRangesForMacroArgExpansion(Loc, Ranges))
IgnoredEnd = LocationStack.size();
Loc = SM.getImmediateMacroCallerLoc(Loc);
Loc = Loc.getImmediateMacroCallerLoc();
// Once the location no longer points into a macro, try stepping through
// the last found location. This sometimes produces additional useful
// backtraces.
if (Loc.isFileID())
Loc = SM.getImmediateMacroCallerLoc(LocationStack.back());
Loc = LocationStack.back().getImmediateMacroCallerLoc();
assert(Loc.isValid() && "must have a valid source location here");
}
@ -555,7 +537,7 @@ void DiagnosticRenderer::emitMacroExpansions(SourceLocation Loc,
if (MacroDepth <= MacroLimit || MacroLimit == 0) {
for (auto I = LocationStack.rbegin(), E = LocationStack.rend();
I != E; ++I)
emitSingleMacroExpansion(*I, Level, Ranges, SM);
emitSingleMacroExpansion(*I, Level, Ranges);
return;
}
@ -565,7 +547,7 @@ void DiagnosticRenderer::emitMacroExpansions(SourceLocation Loc,
for (auto I = LocationStack.rbegin(),
E = LocationStack.rbegin() + MacroStartMessages;
I != E; ++I)
emitSingleMacroExpansion(*I, Level, Ranges, SM);
emitSingleMacroExpansion(*I, Level, Ranges);
SmallString<200> MessageStorage;
llvm::raw_svector_ostream Message(MessageStorage);
@ -577,26 +559,24 @@ void DiagnosticRenderer::emitMacroExpansions(SourceLocation Loc,
for (auto I = LocationStack.rend() - MacroEndMessages,
E = LocationStack.rend();
I != E; ++I)
emitSingleMacroExpansion(*I, Level, Ranges, SM);
emitSingleMacroExpansion(*I, Level, Ranges);
}
DiagnosticNoteRenderer::~DiagnosticNoteRenderer() {}
void DiagnosticNoteRenderer::emitIncludeLocation(SourceLocation Loc,
PresumedLoc PLoc,
const SourceManager &SM) {
void DiagnosticNoteRenderer::emitIncludeLocation(FullSourceLoc Loc,
PresumedLoc PLoc) {
// 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(), &SM);
emitNote(Loc, Message.str());
}
void DiagnosticNoteRenderer::emitImportLocation(SourceLocation Loc,
void DiagnosticNoteRenderer::emitImportLocation(FullSourceLoc Loc,
PresumedLoc PLoc,
StringRef ModuleName,
const SourceManager &SM) {
StringRef ModuleName) {
// Generate a note indicating the include location.
SmallString<200> MessageStorage;
llvm::raw_svector_ostream Message(MessageStorage);
@ -605,14 +585,12 @@ void DiagnosticNoteRenderer::emitImportLocation(SourceLocation Loc,
Message << "' imported from " << PLoc.getFilename() << ':'
<< PLoc.getLine();
Message << ":";
emitNote(Loc, Message.str(), &SM);
emitNote(Loc, Message.str());
}
void
DiagnosticNoteRenderer::emitBuildingModuleLocation(SourceLocation Loc,
PresumedLoc PLoc,
StringRef ModuleName,
const SourceManager &SM) {
void DiagnosticNoteRenderer::emitBuildingModuleLocation(FullSourceLoc Loc,
PresumedLoc PLoc,
StringRef ModuleName) {
// Generate a note indicating the include location.
SmallString<200> MessageStorage;
llvm::raw_svector_ostream Message(MessageStorage);
@ -621,5 +599,5 @@ DiagnosticNoteRenderer::emitBuildingModuleLocation(SourceLocation Loc,
<< PLoc.getFilename() << ':' << PLoc.getLine() << ":";
else
Message << "while building module '" << ModuleName << "':";
emitNote(Loc, Message.str(), &SM);
emitNote(Loc, Message.str());
}

View File

@ -63,27 +63,20 @@ public:
~SDiagsRenderer() override {}
protected:
void emitDiagnosticMessage(SourceLocation Loc,
PresumedLoc PLoc,
DiagnosticsEngine::Level Level,
StringRef Message,
void emitDiagnosticMessage(FullSourceLoc Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level, StringRef Message,
ArrayRef<CharSourceRange> Ranges,
const SourceManager *SM,
DiagOrStoredDiag D) override;
void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
void emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level,
ArrayRef<CharSourceRange> Ranges,
const SourceManager &SM) override {}
ArrayRef<CharSourceRange> Ranges) override {}
void emitNote(SourceLocation Loc, StringRef Message,
const SourceManager *SM) override;
void emitNote(FullSourceLoc Loc, StringRef Message) override;
void emitCodeContext(SourceLocation Loc,
DiagnosticsEngine::Level Level,
SmallVectorImpl<CharSourceRange>& Ranges,
ArrayRef<FixItHint> Hints,
const SourceManager &SM) override;
void emitCodeContext(FullSourceLoc Loc, DiagnosticsEngine::Level Level,
SmallVectorImpl<CharSourceRange> &Ranges,
ArrayRef<FixItHint> Hints) override;
void beginDiagnostic(DiagOrStoredDiag D,
DiagnosticsEngine::Level Level) override;
@ -193,11 +186,8 @@ private:
void ExitDiagBlock();
/// \brief Emit a DIAG record.
void EmitDiagnosticMessage(SourceLocation Loc,
PresumedLoc PLoc,
DiagnosticsEngine::Level Level,
StringRef Message,
const SourceManager *SM,
void EmitDiagnosticMessage(FullSourceLoc Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level, StringRef Message,
DiagOrStoredDiag D);
/// \brief Emit FIXIT and SOURCE_RANGE records for a diagnostic.
@ -220,16 +210,14 @@ private:
/// \brief Emit (lazily) the file string and retrieved the file identifier.
unsigned getEmitFile(const char *Filename);
/// \brief Add SourceLocation information the specified record.
void AddLocToRecord(SourceLocation Loc, const SourceManager *SM,
PresumedLoc PLoc, RecordDataImpl &Record,
unsigned TokSize = 0);
/// \brief Add SourceLocation information the specified record.
void AddLocToRecord(FullSourceLoc Loc, PresumedLoc PLoc,
RecordDataImpl &Record, unsigned TokSize = 0);
/// \brief Add SourceLocation information the specified record.
void AddLocToRecord(SourceLocation Loc, RecordDataImpl &Record,
const SourceManager *SM,
void AddLocToRecord(FullSourceLoc Loc, RecordDataImpl &Record,
unsigned TokSize = 0) {
AddLocToRecord(Loc, SM, SM ? SM->getPresumedLoc(Loc) : PresumedLoc(),
AddLocToRecord(Loc, Loc.hasManager() ? Loc.getPresumedLoc() : PresumedLoc(),
Record, TokSize);
}
@ -350,11 +338,8 @@ static void EmitRecordID(unsigned ID, const char *Name,
Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETRECORDNAME, Record);
}
void SDiagsWriter::AddLocToRecord(SourceLocation Loc,
const SourceManager *SM,
PresumedLoc PLoc,
RecordDataImpl &Record,
unsigned TokSize) {
void SDiagsWriter::AddLocToRecord(FullSourceLoc Loc, PresumedLoc PLoc,
RecordDataImpl &Record, unsigned TokSize) {
if (PLoc.isInvalid()) {
// Emit a "sentinel" location.
Record.push_back((unsigned)0); // File.
@ -367,19 +352,19 @@ void SDiagsWriter::AddLocToRecord(SourceLocation Loc,
Record.push_back(getEmitFile(PLoc.getFilename()));
Record.push_back(PLoc.getLine());
Record.push_back(PLoc.getColumn()+TokSize);
Record.push_back(SM->getFileOffset(Loc));
Record.push_back(Loc.getFileOffset());
}
void SDiagsWriter::AddCharSourceRangeToRecord(CharSourceRange Range,
RecordDataImpl &Record,
const SourceManager &SM) {
AddLocToRecord(Range.getBegin(), Record, &SM);
AddLocToRecord(FullSourceLoc(Range.getBegin(), SM), Record);
unsigned TokSize = 0;
if (Range.isTokenRange())
TokSize = Lexer::MeasureTokenLength(Range.getEnd(),
SM, *LangOpts);
AddLocToRecord(Range.getEnd(), Record, &SM, TokSize);
AddLocToRecord(FullSourceLoc(Range.getEnd(), SM), Record, TokSize);
}
unsigned SDiagsWriter::getEmitFile(const char *FileName){
@ -606,8 +591,8 @@ void SDiagsWriter::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
if (DiagLevel == DiagnosticsEngine::Note)
EnterDiagBlock();
EmitDiagnosticMessage(SourceLocation(), PresumedLoc(), DiagLevel,
State->diagBuf, nullptr, &Info);
EmitDiagnosticMessage(FullSourceLoc(), PresumedLoc(), DiagLevel,
State->diagBuf, &Info);
if (DiagLevel == DiagnosticsEngine::Note)
ExitDiagBlock();
@ -618,12 +603,9 @@ void SDiagsWriter::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
assert(Info.hasSourceManager() && LangOpts &&
"Unexpected diagnostic with valid location outside of a source file");
SDiagsRenderer Renderer(*this, *LangOpts, &*State->DiagOpts);
Renderer.emitDiagnostic(Info.getLocation(), DiagLevel,
State->diagBuf,
Info.getRanges(),
Info.getFixItHints(),
&Info.getSourceManager(),
&Info);
Renderer.emitDiagnostic(
FullSourceLoc(Info.getLocation(), Info.getSourceManager()), DiagLevel,
State->diagBuf, Info.getRanges(), Info.getFixItHints(), &Info);
}
static serialized_diags::Level getStableLevel(DiagnosticsEngine::Level Level) {
@ -641,11 +623,9 @@ static serialized_diags::Level getStableLevel(DiagnosticsEngine::Level Level) {
llvm_unreachable("invalid diagnostic level");
}
void SDiagsWriter::EmitDiagnosticMessage(SourceLocation Loc,
PresumedLoc PLoc,
void SDiagsWriter::EmitDiagnosticMessage(FullSourceLoc Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level,
StringRef Message,
const SourceManager *SM,
DiagOrStoredDiag D) {
llvm::BitstreamWriter &Stream = State->Stream;
RecordData &Record = State->Record;
@ -655,7 +635,7 @@ void SDiagsWriter::EmitDiagnosticMessage(SourceLocation Loc,
Record.clear();
Record.push_back(RECORD_DIAG);
Record.push_back(getStableLevel(Level));
AddLocToRecord(Loc, SM, PLoc, Record);
AddLocToRecord(Loc, PLoc, Record);
if (const Diagnostic *Info = D.dyn_cast<const Diagnostic*>()) {
// Emit the category string lazily and get the category ID.
@ -672,15 +652,11 @@ void SDiagsWriter::EmitDiagnosticMessage(SourceLocation Loc,
Stream.EmitRecordWithBlob(Abbrevs.get(RECORD_DIAG), Record, Message);
}
void
SDiagsRenderer::emitDiagnosticMessage(SourceLocation Loc,
PresumedLoc PLoc,
DiagnosticsEngine::Level Level,
StringRef Message,
ArrayRef<clang::CharSourceRange> Ranges,
const SourceManager *SM,
DiagOrStoredDiag D) {
Writer.EmitDiagnosticMessage(Loc, PLoc, Level, Message, SM, D);
void SDiagsRenderer::emitDiagnosticMessage(
FullSourceLoc Loc, PresumedLoc PLoc, DiagnosticsEngine::Level Level,
StringRef Message, ArrayRef<clang::CharSourceRange> Ranges,
DiagOrStoredDiag D) {
Writer.EmitDiagnosticMessage(Loc, PLoc, Level, Message, D);
}
void SDiagsWriter::EnterDiagBlock() {
@ -733,20 +709,18 @@ void SDiagsWriter::EmitCodeContext(SmallVectorImpl<CharSourceRange> &Ranges,
}
}
void SDiagsRenderer::emitCodeContext(SourceLocation Loc,
void SDiagsRenderer::emitCodeContext(FullSourceLoc Loc,
DiagnosticsEngine::Level Level,
SmallVectorImpl<CharSourceRange> &Ranges,
ArrayRef<FixItHint> Hints,
const SourceManager &SM) {
Writer.EmitCodeContext(Ranges, Hints, SM);
ArrayRef<FixItHint> Hints) {
Writer.EmitCodeContext(Ranges, Hints, Loc.getManager());
}
void SDiagsRenderer::emitNote(SourceLocation Loc, StringRef Message,
const SourceManager *SM) {
void SDiagsRenderer::emitNote(FullSourceLoc Loc, StringRef Message) {
Writer.EnterDiagBlock();
PresumedLoc PLoc = SM ? SM->getPresumedLoc(Loc) : PresumedLoc();
Writer.EmitDiagnosticMessage(Loc, PLoc, DiagnosticsEngine::Note,
Message, SM, DiagOrStoredDiag());
PresumedLoc PLoc = Loc.hasManager() ? Loc.getPresumedLoc() : PresumedLoc();
Writer.EmitDiagnosticMessage(Loc, PLoc, DiagnosticsEngine::Note, Message,
DiagOrStoredDiag());
Writer.ExitDiagBlock();
}

View File

@ -672,20 +672,16 @@ TextDiagnostic::TextDiagnostic(raw_ostream &OS,
TextDiagnostic::~TextDiagnostic() {}
void
TextDiagnostic::emitDiagnosticMessage(SourceLocation Loc,
PresumedLoc PLoc,
DiagnosticsEngine::Level Level,
StringRef Message,
ArrayRef<clang::CharSourceRange> Ranges,
const SourceManager *SM,
DiagOrStoredDiag D) {
void TextDiagnostic::emitDiagnosticMessage(
FullSourceLoc Loc, PresumedLoc PLoc, DiagnosticsEngine::Level Level,
StringRef Message, ArrayRef<clang::CharSourceRange> Ranges,
DiagOrStoredDiag D) {
uint64_t StartOfLocationInfo = OS.tell();
// Emit the location of this particular diagnostic.
if (Loc.isValid())
emitDiagnosticLoc(Loc, PLoc, Level, Ranges, *SM);
emitDiagnosticLoc(Loc, PLoc, Level, Ranges);
if (DiagOpts->ShowColors)
OS.resetColor();
@ -787,17 +783,16 @@ void TextDiagnostic::emitFilename(StringRef Filename, const SourceManager &SM) {
/// This includes extracting as much location information as is present for
/// the diagnostic and printing it, as well as any include stack or source
/// ranges necessary.
void TextDiagnostic::emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
void TextDiagnostic::emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level,
ArrayRef<CharSourceRange> Ranges,
const SourceManager &SM) {
ArrayRef<CharSourceRange> Ranges) {
if (PLoc.isInvalid()) {
// At least print the file name if available:
FileID FID = SM.getFileID(Loc);
FileID FID = Loc.getFileID();
if (FID.isValid()) {
const FileEntry* FE = SM.getFileEntryForID(FID);
const FileEntry *FE = Loc.getFileEntry();
if (FE && FE->isValid()) {
emitFilename(FE->getName(), SM);
emitFilename(FE->getName(), Loc.getManager());
if (FE->isInPCH())
OS << " (in PCH)";
OS << ": ";
@ -813,7 +808,7 @@ void TextDiagnostic::emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
if (DiagOpts->ShowColors)
OS.changeColor(savedColor, true);
emitFilename(PLoc.getFilename(), SM);
emitFilename(PLoc.getFilename(), Loc.getManager());
switch (DiagOpts->getFormat()) {
case DiagnosticOptions::Clang: OS << ':' << LineNo; break;
case DiagnosticOptions::MSVC: OS << '(' << LineNo; break;
@ -848,8 +843,7 @@ void TextDiagnostic::emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
}
if (DiagOpts->ShowSourceRanges && !Ranges.empty()) {
FileID CaretFileID =
SM.getFileID(SM.getExpansionLoc(Loc));
FileID CaretFileID = Loc.getExpansionLoc().getFileID();
bool PrintedRange = false;
for (ArrayRef<CharSourceRange>::const_iterator RI = Ranges.begin(),
@ -858,8 +852,10 @@ void TextDiagnostic::emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
// Ignore invalid ranges.
if (!RI->isValid()) continue;
SourceLocation B = SM.getExpansionLoc(RI->getBegin());
SourceLocation E = SM.getExpansionLoc(RI->getEnd());
FullSourceLoc B =
FullSourceLoc(RI->getBegin(), Loc.getManager()).getExpansionLoc();
FullSourceLoc E =
FullSourceLoc(RI->getEnd(), Loc.getManager()).getExpansionLoc();
// If the End location and the start location are the same and are a
// macro location, then the range was something that came from a
@ -867,10 +863,12 @@ void TextDiagnostic::emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
// best we can do is to highlight the range. If this is a
// function-like macro, we'd also like to highlight the arguments.
if (B == E && RI->getEnd().isMacroID())
E = SM.getExpansionRange(RI->getEnd()).second;
E = FullSourceLoc(RI->getEnd(), Loc.getManager())
.getExpansionRange()
.second;
std::pair<FileID, unsigned> BInfo = SM.getDecomposedLoc(B);
std::pair<FileID, unsigned> EInfo = SM.getDecomposedLoc(E);
std::pair<FileID, unsigned> BInfo = B.getDecomposedLoc();
std::pair<FileID, unsigned> EInfo = E.getDecomposedLoc();
// If the start or end of the range is in another file, just discard
// it.
@ -881,13 +879,10 @@ void TextDiagnostic::emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
// tokens.
unsigned TokSize = 0;
if (RI->isTokenRange())
TokSize = Lexer::MeasureTokenLength(E, SM, LangOpts);
TokSize = Lexer::MeasureTokenLength(E, E.getManager(), LangOpts);
OS << '{' << SM.getLineNumber(BInfo.first, BInfo.second) << ':'
<< SM.getColumnNumber(BInfo.first, BInfo.second) << '-'
<< SM.getLineNumber(EInfo.first, EInfo.second) << ':'
<< (SM.getColumnNumber(EInfo.first, EInfo.second)+TokSize)
<< '}';
OS << '{' << B.getLineNumber() << ':' << B.getColumnNumber() << '-'
<< E.getLineNumber() << ':' << (E.getColumnNumber() + TokSize) << '}';
PrintedRange = true;
}
@ -897,9 +892,7 @@ void TextDiagnostic::emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
OS << ' ';
}
void TextDiagnostic::emitIncludeLocation(SourceLocation Loc,
PresumedLoc PLoc,
const SourceManager &SM) {
void TextDiagnostic::emitIncludeLocation(FullSourceLoc Loc, PresumedLoc PLoc) {
if (DiagOpts->ShowLocation && PLoc.isValid())
OS << "In file included from " << PLoc.getFilename() << ':'
<< PLoc.getLine() << ":\n";
@ -907,9 +900,8 @@ void TextDiagnostic::emitIncludeLocation(SourceLocation Loc,
OS << "In included file:\n";
}
void TextDiagnostic::emitImportLocation(SourceLocation Loc, PresumedLoc PLoc,
StringRef ModuleName,
const SourceManager &SM) {
void TextDiagnostic::emitImportLocation(FullSourceLoc Loc, PresumedLoc PLoc,
StringRef ModuleName) {
if (DiagOpts->ShowLocation && PLoc.isValid())
OS << "In module '" << ModuleName << "' imported from "
<< PLoc.getFilename() << ':' << PLoc.getLine() << ":\n";
@ -917,10 +909,9 @@ void TextDiagnostic::emitImportLocation(SourceLocation Loc, PresumedLoc PLoc,
OS << "In module '" << ModuleName << "':\n";
}
void TextDiagnostic::emitBuildingModuleLocation(SourceLocation Loc,
void TextDiagnostic::emitBuildingModuleLocation(FullSourceLoc Loc,
PresumedLoc PLoc,
StringRef ModuleName,
const SourceManager &SM) {
StringRef ModuleName) {
if (DiagOpts->ShowLocation && PLoc.isValid())
OS << "While building module '" << ModuleName << "' imported from "
<< PLoc.getFilename() << ':' << PLoc.getLine() << ":\n";
@ -1134,10 +1125,8 @@ static std::string buildFixItInsertionLine(unsigned LineNo,
/// \param Ranges The underlined ranges for this code snippet.
/// \param Hints The FixIt hints active for this diagnostic.
void TextDiagnostic::emitSnippetAndCaret(
SourceLocation Loc, DiagnosticsEngine::Level Level,
SmallVectorImpl<CharSourceRange>& Ranges,
ArrayRef<FixItHint> Hints,
const SourceManager &SM) {
FullSourceLoc Loc, DiagnosticsEngine::Level Level,
SmallVectorImpl<CharSourceRange> &Ranges, ArrayRef<FixItHint> Hints) {
assert(Loc.isValid() && "must have a valid source location here");
assert(Loc.isFileID() && "must have a file location here");
@ -1154,18 +1143,18 @@ void TextDiagnostic::emitSnippetAndCaret(
return;
// Decompose the location into a FID/Offset pair.
std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
std::pair<FileID, unsigned> LocInfo = Loc.getDecomposedLoc();
FileID FID = LocInfo.first;
unsigned CaretFileOffset = LocInfo.second;
const SourceManager &SM = Loc.getManager();
// Get information about the buffer it points into.
bool Invalid = false;
StringRef BufData = SM.getBufferData(FID, &Invalid);
StringRef BufData = Loc.getBufferData(&Invalid);
if (Invalid)
return;
unsigned CaretLineNo = SM.getLineNumber(FID, CaretFileOffset);
unsigned CaretColNo = SM.getColumnNumber(FID, CaretFileOffset);
unsigned CaretLineNo = Loc.getLineNumber();
unsigned CaretColNo = Loc.getColumnNumber();
// Arbitrarily stop showing snippets when the line is too long.
static const size_t MaxLineLengthToPrint = 4096;

View File

@ -150,10 +150,9 @@ void TextDiagnosticPrinter::HandleDiagnostic(DiagnosticsEngine::Level Level,
"Unexpected diagnostic with no source manager");
assert(TextDiag && "Unexpected diagnostic outside source file processing");
TextDiag->emitDiagnostic(Info.getLocation(), Level, DiagMessageStream.str(),
Info.getRanges(),
Info.getFixItHints(),
&Info.getSourceManager());
TextDiag->emitDiagnostic(
FullSourceLoc(Info.getLocation(), Info.getSourceManager()), Level,
DiagMessageStream.str(), Info.getRanges(), Info.getFixItHints());
OS.flush();
}

View File

@ -110,40 +110,34 @@ public:
CurrentSet = &CD.getChildDiagnostics();
}
void emitDiagnosticMessage(SourceLocation Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level,
StringRef Message,
void emitDiagnosticMessage(FullSourceLoc Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level, StringRef Message,
ArrayRef<CharSourceRange> Ranges,
const SourceManager *SM,
DiagOrStoredDiag D) override {
if (!D.isNull())
return;
CXSourceLocation L;
if (SM)
L = translateSourceLocation(*SM, LangOpts, Loc);
if (Loc.hasManager())
L = translateSourceLocation(Loc.getManager(), LangOpts, Loc);
else
L = clang_getNullLocation();
CurrentSet->appendDiagnostic(
llvm::make_unique<CXDiagnosticCustomNoteImpl>(Message, L));
}
void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
void emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level,
ArrayRef<CharSourceRange> Ranges,
const SourceManager &SM) override {}
ArrayRef<CharSourceRange> Ranges) override {}
void emitCodeContext(SourceLocation Loc,
DiagnosticsEngine::Level Level,
SmallVectorImpl<CharSourceRange>& Ranges,
ArrayRef<FixItHint> Hints,
const SourceManager &SM) override {}
void emitCodeContext(FullSourceLoc Loc, DiagnosticsEngine::Level Level,
SmallVectorImpl<CharSourceRange> &Ranges,
ArrayRef<FixItHint> Hints) override {}
void emitNote(SourceLocation Loc, StringRef Message,
const SourceManager *SM) override {
void emitNote(FullSourceLoc Loc, StringRef Message) override {
CXSourceLocation L;
if (SM)
L = translateSourceLocation(*SM, LangOpts, Loc);
if (Loc.hasManager())
L = translateSourceLocation(Loc.getManager(), LangOpts, Loc);
else
L = clang_getNullLocation();
CurrentSet->appendDiagnostic(