forked from OSchip/llvm-project
Persist the TextDiagnostic object across multiple diagnostics as long as
the SourceManager doesn't change, and the source files don't change. This greatly simplifies the interfaces and interactions. The lifetime of the TextDiagnostic object forms the 'session' over which we attempt to condense and deduplicate information in diagnostics. llvm-svn: 142104
This commit is contained in:
parent
bccadaf1a3
commit
3eb8b54e71
|
@ -70,20 +70,7 @@ public:
|
||||||
TextDiagnostic(raw_ostream &OS,
|
TextDiagnostic(raw_ostream &OS,
|
||||||
const SourceManager &SM,
|
const SourceManager &SM,
|
||||||
const LangOptions &LangOpts,
|
const LangOptions &LangOpts,
|
||||||
const DiagnosticOptions &DiagOpts,
|
const DiagnosticOptions &DiagOpts);
|
||||||
FullSourceLoc LastLoc = FullSourceLoc(),
|
|
||||||
FullSourceLoc LastIncludeLoc = FullSourceLoc(),
|
|
||||||
DiagnosticsEngine::Level LastLevel
|
|
||||||
= DiagnosticsEngine::Level());
|
|
||||||
|
|
||||||
/// \brief Get the last diagnostic location emitted.
|
|
||||||
SourceLocation getLastLoc() const { return LastLoc; }
|
|
||||||
|
|
||||||
/// \brief Get the last emitted include stack location.
|
|
||||||
SourceLocation getLastIncludeLoc() const { return LastIncludeLoc; }
|
|
||||||
|
|
||||||
/// \brief Get the last diagnostic level.
|
|
||||||
DiagnosticsEngine::Level getLastLevel() const { return LastLevel; }
|
|
||||||
|
|
||||||
void emitDiagnostic(SourceLocation Loc, DiagnosticsEngine::Level Level,
|
void emitDiagnostic(SourceLocation Loc, DiagnosticsEngine::Level Level,
|
||||||
StringRef Message, ArrayRef<CharSourceRange> Ranges,
|
StringRef Message, ArrayRef<CharSourceRange> Ranges,
|
||||||
|
|
|
@ -16,25 +16,28 @@
|
||||||
#define LLVM_CLANG_FRONTEND_TEXT_DIAGNOSTIC_PRINTER_H_
|
#define LLVM_CLANG_FRONTEND_TEXT_DIAGNOSTIC_PRINTER_H_
|
||||||
|
|
||||||
#include "clang/Basic/Diagnostic.h"
|
#include "clang/Basic/Diagnostic.h"
|
||||||
#include "clang/Basic/SourceLocation.h"
|
#include "clang/Basic/LLVM.h"
|
||||||
|
#include "llvm/ADT/OwningPtr.h"
|
||||||
|
|
||||||
namespace clang {
|
namespace clang {
|
||||||
class DiagnosticOptions;
|
class DiagnosticOptions;
|
||||||
class LangOptions;
|
class LangOptions;
|
||||||
|
class TextDiagnostic;
|
||||||
|
|
||||||
class TextDiagnosticPrinter : public DiagnosticConsumer {
|
class TextDiagnosticPrinter : public DiagnosticConsumer {
|
||||||
raw_ostream &OS;
|
raw_ostream &OS;
|
||||||
const LangOptions *LangOpts;
|
const LangOptions *LangOpts;
|
||||||
const DiagnosticOptions *DiagOpts;
|
const DiagnosticOptions *DiagOpts;
|
||||||
|
const SourceManager *SM;
|
||||||
|
|
||||||
FullSourceLoc LastLoc;
|
/// \brief Handle to the currently active text diagnostic emitter.
|
||||||
FullSourceLoc LastIncludeLoc;
|
llvm::OwningPtr<TextDiagnostic> TextDiag;
|
||||||
DiagnosticsEngine::Level LastLevel;
|
|
||||||
unsigned OwnsOutputStream : 1;
|
|
||||||
|
|
||||||
/// A string to prefix to error messages.
|
/// A string to prefix to error messages.
|
||||||
std::string Prefix;
|
std::string Prefix;
|
||||||
|
|
||||||
|
unsigned OwnsOutputStream : 1;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TextDiagnosticPrinter(raw_ostream &os, const DiagnosticOptions &diags,
|
TextDiagnosticPrinter(raw_ostream &os, const DiagnosticOptions &diags,
|
||||||
bool OwnsOutputStream = false);
|
bool OwnsOutputStream = false);
|
||||||
|
@ -45,17 +48,9 @@ public:
|
||||||
/// used.
|
/// used.
|
||||||
void setPrefix(std::string Value) { Prefix = Value; }
|
void setPrefix(std::string Value) { Prefix = Value; }
|
||||||
|
|
||||||
void BeginSourceFile(const LangOptions &LO, const Preprocessor *PP) {
|
void BeginSourceFile(const LangOptions &LO, const Preprocessor *PP);
|
||||||
LangOpts = &LO;
|
void EndSourceFile();
|
||||||
}
|
void HandleDiagnostic(DiagnosticsEngine::Level Level, const Diagnostic &Info);
|
||||||
|
|
||||||
void EndSourceFile() {
|
|
||||||
LangOpts = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void HandleDiagnostic(DiagnosticsEngine::Level Level,
|
|
||||||
const Diagnostic &Info);
|
|
||||||
|
|
||||||
DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const;
|
DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -392,17 +392,9 @@ static bool printWordWrapped(raw_ostream &OS, StringRef Str,
|
||||||
TextDiagnostic::TextDiagnostic(raw_ostream &OS,
|
TextDiagnostic::TextDiagnostic(raw_ostream &OS,
|
||||||
const SourceManager &SM,
|
const SourceManager &SM,
|
||||||
const LangOptions &LangOpts,
|
const LangOptions &LangOpts,
|
||||||
const DiagnosticOptions &DiagOpts,
|
const DiagnosticOptions &DiagOpts)
|
||||||
FullSourceLoc LastLoc,
|
: OS(OS), SM(SM), LangOpts(LangOpts), DiagOpts(DiagOpts), LastLevel() {
|
||||||
FullSourceLoc LastIncludeLoc,
|
}
|
||||||
DiagnosticsEngine::Level LastLevel)
|
|
||||||
: OS(OS), SM(SM), LangOpts(LangOpts), DiagOpts(DiagOpts),
|
|
||||||
LastLoc(LastLoc), LastIncludeLoc(LastIncludeLoc), LastLevel(LastLevel) {
|
|
||||||
if (LastLoc.isValid() && &SM != &LastLoc.getManager())
|
|
||||||
this->LastLoc = SourceLocation();
|
|
||||||
if (LastIncludeLoc.isValid() && &SM != &LastIncludeLoc.getManager())
|
|
||||||
this->LastIncludeLoc = SourceLocation();
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextDiagnostic::emitDiagnostic(SourceLocation Loc,
|
void TextDiagnostic::emitDiagnostic(SourceLocation Loc,
|
||||||
DiagnosticsEngine::Level Level,
|
DiagnosticsEngine::Level Level,
|
||||||
|
|
|
@ -27,7 +27,7 @@ using namespace clang;
|
||||||
TextDiagnosticPrinter::TextDiagnosticPrinter(raw_ostream &os,
|
TextDiagnosticPrinter::TextDiagnosticPrinter(raw_ostream &os,
|
||||||
const DiagnosticOptions &diags,
|
const DiagnosticOptions &diags,
|
||||||
bool _OwnsOutputStream)
|
bool _OwnsOutputStream)
|
||||||
: OS(os), LangOpts(0), DiagOpts(&diags), LastLevel(),
|
: OS(os), LangOpts(0), DiagOpts(&diags), SM(0),
|
||||||
OwnsOutputStream(_OwnsOutputStream) {
|
OwnsOutputStream(_OwnsOutputStream) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +36,16 @@ TextDiagnosticPrinter::~TextDiagnosticPrinter() {
|
||||||
delete &OS;
|
delete &OS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextDiagnosticPrinter::BeginSourceFile(const LangOptions &LO,
|
||||||
|
const Preprocessor *PP) {
|
||||||
|
LangOpts = &LO;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextDiagnosticPrinter::EndSourceFile() {
|
||||||
|
LangOpts = 0;
|
||||||
|
TextDiag.reset(0);
|
||||||
|
}
|
||||||
|
|
||||||
/// \brief Print the diagnostic name to a raw_ostream.
|
/// \brief Print the diagnostic name to a raw_ostream.
|
||||||
///
|
///
|
||||||
/// This prints the diagnostic name to a raw_ostream if it has one. It formats
|
/// This prints the diagnostic name to a raw_ostream if it has one. It formats
|
||||||
|
@ -158,23 +168,18 @@ void TextDiagnosticPrinter::HandleDiagnostic(DiagnosticsEngine::Level Level,
|
||||||
assert(DiagOpts && "Unexpected diagnostic without options set");
|
assert(DiagOpts && "Unexpected diagnostic without options set");
|
||||||
assert(Info.hasSourceManager() &&
|
assert(Info.hasSourceManager() &&
|
||||||
"Unexpected diagnostic with no source manager");
|
"Unexpected diagnostic with no source manager");
|
||||||
const SourceManager &SM = Info.getSourceManager();
|
|
||||||
TextDiagnostic TextDiag(OS, SM, *LangOpts, *DiagOpts,
|
|
||||||
LastLoc, LastIncludeLoc, LastLevel);
|
|
||||||
|
|
||||||
TextDiag.emitDiagnostic(Info.getLocation(), Level, DiagMessageStream.str(),
|
// Rebuild the TextDiagnostic utility if missing or the source manager has
|
||||||
Info.getRanges(),
|
// changed.
|
||||||
llvm::makeArrayRef(Info.getFixItHints(),
|
if (!TextDiag || SM != &Info.getSourceManager()) {
|
||||||
Info.getNumFixItHints()));
|
SM = &Info.getSourceManager();
|
||||||
|
TextDiag.reset(new TextDiagnostic(OS, *SM, *LangOpts, *DiagOpts));
|
||||||
|
}
|
||||||
|
|
||||||
// Cache the LastLoc from the TextDiagnostic printing.
|
TextDiag->emitDiagnostic(Info.getLocation(), Level, DiagMessageStream.str(),
|
||||||
// FIXME: Rather than this, we should persist a TextDiagnostic object across
|
Info.getRanges(),
|
||||||
// diagnostics until the SourceManager changes. That will allow the
|
llvm::makeArrayRef(Info.getFixItHints(),
|
||||||
// TextDiagnostic object to form a 'session' of output where we can
|
Info.getNumFixItHints()));
|
||||||
// reasonably collapse redundant information.
|
|
||||||
LastLoc = FullSourceLoc(TextDiag.getLastLoc(), SM);
|
|
||||||
LastIncludeLoc = FullSourceLoc(TextDiag.getLastIncludeLoc(), SM);
|
|
||||||
LastLevel = TextDiag.getLastLevel();
|
|
||||||
|
|
||||||
OS.flush();
|
OS.flush();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue