summaryrefslogtreecommitdiffstats
path: root/include/clang/Frontend/DiagnosticRenderer.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/Frontend/DiagnosticRenderer.h')
-rw-r--r--include/clang/Frontend/DiagnosticRenderer.h149
1 files changed, 149 insertions, 0 deletions
diff --git a/include/clang/Frontend/DiagnosticRenderer.h b/include/clang/Frontend/DiagnosticRenderer.h
new file mode 100644
index 0000000..5ad88a8
--- /dev/null
+++ b/include/clang/Frontend/DiagnosticRenderer.h
@@ -0,0 +1,149 @@
+//===--- DiagnosticRenderer.h - Diagnostic Pretty-Printing ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is a utility class that provides support for pretty-printing of
+// diagnostics. It is used to implement the different code paths which require
+// such functionality in a consistent way.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_DIAGNOSTIC_RENDERER_H_
+#define LLVM_CLANG_FRONTEND_DIAGNOSTIC_RENDERER_H_
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/PointerUnion.h"
+
+namespace clang {
+
+class DiagnosticOptions;
+class LangOptions;
+class SourceManager;
+
+typedef llvm::PointerUnion<const Diagnostic *,
+ const StoredDiagnostic *> DiagOrStoredDiag;
+
+/// \brief Class to encapsulate the logic for formatting a diagnostic message.
+/// Actual "printing" logic is implemented by subclasses.
+///
+/// This class provides an interface for building and emitting
+/// diagnostic, including all of the macro backtraces, caret diagnostics, FixIt
+/// Hints, and code snippets. In the presence of macros this involves
+/// a recursive process, synthesizing notes for each macro expansion.
+///
+/// A brief worklist:
+/// FIXME: Sink the recursive printing of template instantiations into this
+/// class.
+class DiagnosticRenderer {
+protected:
+ const SourceManager &SM;
+ const LangOptions &LangOpts;
+ const DiagnosticOptions &DiagOpts;
+
+ /// \brief The location of the previous diagnostic if known.
+ ///
+ /// This will be invalid in cases where there is no (known) previous
+ /// diagnostic location, or that location itself is invalid or comes from
+ /// a different source manager than SM.
+ SourceLocation LastLoc;
+
+ /// \brief The location of the last include whose stack was printed if known.
+ ///
+ /// Same restriction as \see LastLoc essentially, but tracking include stack
+ /// root locations rather than diagnostic locations.
+ SourceLocation LastIncludeLoc;
+
+ /// \brief The level of the last diagnostic emitted.
+ ///
+ /// The level of the last diagnostic emitted. Used to detect level changes
+ /// which change the amount of information displayed.
+ DiagnosticsEngine::Level LastLevel;
+
+ DiagnosticRenderer(const SourceManager &SM,
+ const LangOptions &LangOpts,
+ const DiagnosticOptions &DiagOpts);
+
+ virtual ~DiagnosticRenderer();
+
+ virtual void emitDiagnosticMessage(SourceLocation Loc, PresumedLoc PLoc,
+ DiagnosticsEngine::Level Level,
+ StringRef Message,
+ ArrayRef<CharSourceRange> Ranges,
+ DiagOrStoredDiag Info) = 0;
+
+ virtual void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
+ DiagnosticsEngine::Level Level,
+ ArrayRef<CharSourceRange> Ranges) = 0;
+
+ virtual void emitBasicNote(StringRef Message) = 0;
+
+ virtual void emitCodeContext(SourceLocation Loc,
+ DiagnosticsEngine::Level Level,
+ SmallVectorImpl<CharSourceRange>& Ranges,
+ ArrayRef<FixItHint> Hints) = 0;
+
+ virtual void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc) = 0;
+
+ virtual void beginDiagnostic(DiagOrStoredDiag D,
+ DiagnosticsEngine::Level Level) {}
+ virtual void endDiagnostic(DiagOrStoredDiag D,
+ DiagnosticsEngine::Level Level) {}
+
+
+private:
+ void emitIncludeStack(SourceLocation Loc, DiagnosticsEngine::Level Level);
+ void emitIncludeStackRecursively(SourceLocation Loc);
+ void emitMacroExpansionsAndCarets(SourceLocation Loc,
+ DiagnosticsEngine::Level Level,
+ SmallVectorImpl<CharSourceRange>& Ranges,
+ ArrayRef<FixItHint> Hints,
+ unsigned &MacroDepth,
+ unsigned OnMacroInst = 0);
+public:
+ /// \brief Emit a diagnostic.
+ ///
+ /// This is the primary entry point for emitting diagnostic messages.
+ /// It handles formatting and rendering the message as well as any ancillary
+ /// information needed based on macros whose expansions impact the
+ /// diagnostic.
+ ///
+ /// \param Loc The location for this caret.
+ /// \param Level The level of the diagnostic to be emitted.
+ /// \param Message The diagnostic message to emit.
+ /// \param Ranges The underlined ranges for this code snippet.
+ /// \param FixItHints The FixIt hints active for this diagnostic.
+ void emitDiagnostic(SourceLocation Loc, DiagnosticsEngine::Level Level,
+ StringRef Message, ArrayRef<CharSourceRange> Ranges,
+ ArrayRef<FixItHint> FixItHints,
+ DiagOrStoredDiag D = (Diagnostic *)0);
+
+ void emitStoredDiagnostic(StoredDiagnostic &Diag);
+};
+
+/// Subclass of DiagnosticRender that turns all subdiagostics into explicit
+/// notes. It is up to subclasses to further define the behavior.
+class DiagnosticNoteRenderer : public DiagnosticRenderer {
+public:
+ DiagnosticNoteRenderer(const SourceManager &SM,
+ const LangOptions &LangOpts,
+ const DiagnosticOptions &DiagOpts)
+ : DiagnosticRenderer(SM, LangOpts, DiagOpts) {}
+
+ virtual ~DiagnosticNoteRenderer();
+
+ virtual void emitBasicNote(StringRef Message);
+
+ virtual void emitIncludeLocation(SourceLocation Loc,
+ PresumedLoc PLoc);
+
+ virtual void emitNote(SourceLocation Loc, StringRef Message) = 0;
+};
+} // end clang namespace
+#endif
OpenPOWER on IntegriCloud