TextDiagnostic(raw_ostream &OS,
const SourceManager &SM,
const LangOptions &LangOpts,
- 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; }
+ const DiagnosticOptions &DiagOpts);
void emitDiagnostic(SourceLocation Loc, DiagnosticsEngine::Level Level,
StringRef Message, ArrayRef<CharSourceRange> Ranges,
#define LLVM_CLANG_FRONTEND_TEXT_DIAGNOSTIC_PRINTER_H_
#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/OwningPtr.h"
namespace clang {
class DiagnosticOptions;
class LangOptions;
+class TextDiagnostic;
class TextDiagnosticPrinter : public DiagnosticConsumer {
raw_ostream &OS;
const LangOptions *LangOpts;
const DiagnosticOptions *DiagOpts;
+ const SourceManager *SM;
- FullSourceLoc LastLoc;
- FullSourceLoc LastIncludeLoc;
- DiagnosticsEngine::Level LastLevel;
- unsigned OwnsOutputStream : 1;
+ /// \brief Handle to the currently active text diagnostic emitter.
+ llvm::OwningPtr<TextDiagnostic> TextDiag;
/// A string to prefix to error messages.
std::string Prefix;
+ unsigned OwnsOutputStream : 1;
+
public:
TextDiagnosticPrinter(raw_ostream &os, const DiagnosticOptions &diags,
bool OwnsOutputStream = false);
/// used.
void setPrefix(std::string Value) { Prefix = Value; }
- void BeginSourceFile(const LangOptions &LO, const Preprocessor *PP) {
- LangOpts = &LO;
- }
-
- void EndSourceFile() {
- LangOpts = 0;
- }
-
- virtual void HandleDiagnostic(DiagnosticsEngine::Level Level,
- const Diagnostic &Info);
-
+ void BeginSourceFile(const LangOptions &LO, const Preprocessor *PP);
+ void EndSourceFile();
+ void HandleDiagnostic(DiagnosticsEngine::Level Level, const Diagnostic &Info);
DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const;
};
TextDiagnostic::TextDiagnostic(raw_ostream &OS,
const SourceManager &SM,
const LangOptions &LangOpts,
- const DiagnosticOptions &DiagOpts,
- FullSourceLoc LastLoc,
- 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();
- }
+ const DiagnosticOptions &DiagOpts)
+ : OS(OS), SM(SM), LangOpts(LangOpts), DiagOpts(DiagOpts), LastLevel() {
+}
void TextDiagnostic::emitDiagnostic(SourceLocation Loc,
DiagnosticsEngine::Level Level,
TextDiagnosticPrinter::TextDiagnosticPrinter(raw_ostream &os,
const DiagnosticOptions &diags,
bool _OwnsOutputStream)
- : OS(os), LangOpts(0), DiagOpts(&diags), LastLevel(),
+ : OS(os), LangOpts(0), DiagOpts(&diags), SM(0),
OwnsOutputStream(_OwnsOutputStream) {
}
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.
///
/// This prints the diagnostic name to a raw_ostream if it has one. It formats
assert(DiagOpts && "Unexpected diagnostic without options set");
assert(Info.hasSourceManager() &&
"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(),
- Info.getRanges(),
- llvm::makeArrayRef(Info.getFixItHints(),
- Info.getNumFixItHints()));
-
- // Cache the LastLoc from the TextDiagnostic printing.
- // FIXME: Rather than this, we should persist a TextDiagnostic object across
- // diagnostics until the SourceManager changes. That will allow the
- // TextDiagnostic object to form a 'session' of output where we can
- // reasonably collapse redundant information.
- LastLoc = FullSourceLoc(TextDiag.getLastLoc(), SM);
- LastIncludeLoc = FullSourceLoc(TextDiag.getLastIncludeLoc(), SM);
- LastLevel = TextDiag.getLastLevel();
+
+ // Rebuild the TextDiagnostic utility if missing or the source manager has
+ // changed.
+ if (!TextDiag || SM != &Info.getSourceManager()) {
+ SM = &Info.getSourceManager();
+ TextDiag.reset(new TextDiagnostic(OS, *SM, *LangOpts, *DiagOpts));
+ }
+
+ TextDiag->emitDiagnostic(Info.getLocation(), Level, DiagMessageStream.str(),
+ Info.getRanges(),
+ llvm::makeArrayRef(Info.getFixItHints(),
+ Info.getNumFixItHints()));
OS.flush();
}