]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/llvm/tools/clang/include/clang/Frontend/DiagnosticRenderer.h
MFC r244628:
[FreeBSD/stable/9.git] / contrib / llvm / tools / clang / include / clang / Frontend / DiagnosticRenderer.h
1 //===--- DiagnosticRenderer.h - Diagnostic Pretty-Printing ------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This is a utility class that provides support for pretty-printing of
11 // diagnostics. It is used to implement the different code paths which require
12 // such functionality in a consistent way.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #ifndef LLVM_CLANG_FRONTEND_DIAGNOSTIC_RENDERER_H_
17 #define LLVM_CLANG_FRONTEND_DIAGNOSTIC_RENDERER_H_
18
19 #include "clang/Basic/Diagnostic.h"
20 #include "clang/Basic/LLVM.h"
21 #include "clang/Basic/SourceLocation.h"
22 #include "llvm/ADT/PointerUnion.h"
23
24 namespace clang {
25
26 class DiagnosticOptions;
27 class LangOptions;
28 class SourceManager;
29
30 typedef llvm::PointerUnion<const Diagnostic *,
31                            const StoredDiagnostic *> DiagOrStoredDiag;
32   
33 /// \brief Class to encapsulate the logic for formatting a diagnostic message.
34 ///  Actual "printing" logic is implemented by subclasses.
35 ///
36 /// This class provides an interface for building and emitting
37 /// diagnostic, including all of the macro backtraces, caret diagnostics, FixIt
38 /// Hints, and code snippets. In the presence of macros this involves
39 /// a recursive process, synthesizing notes for each macro expansion.
40 ///
41 /// A brief worklist:
42 /// FIXME: Sink the recursive printing of template instantiations into this
43 /// class.
44 class DiagnosticRenderer {
45 protected:
46   const LangOptions &LangOpts;
47   IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
48   
49   /// \brief The location of the previous diagnostic if known.
50   ///
51   /// This will be invalid in cases where there is no (known) previous
52   /// diagnostic location, or that location itself is invalid or comes from
53   /// a different source manager than SM.
54   SourceLocation LastLoc;
55   
56   /// \brief The location of the last include whose stack was printed if known.
57   ///
58   /// Same restriction as \see LastLoc essentially, but tracking include stack
59   /// root locations rather than diagnostic locations.
60   SourceLocation LastIncludeLoc;
61   
62   /// \brief The level of the last diagnostic emitted.
63   ///
64   /// The level of the last diagnostic emitted. Used to detect level changes
65   /// which change the amount of information displayed.
66   DiagnosticsEngine::Level LastLevel;
67
68   DiagnosticRenderer(const LangOptions &LangOpts,
69                      DiagnosticOptions *DiagOpts);
70   
71   virtual ~DiagnosticRenderer();
72   
73   virtual void emitDiagnosticMessage(SourceLocation Loc, PresumedLoc PLoc,
74                                      DiagnosticsEngine::Level Level,
75                                      StringRef Message,
76                                      ArrayRef<CharSourceRange> Ranges,
77                                      const SourceManager *SM,
78                                      DiagOrStoredDiag Info) = 0;
79   
80   virtual void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
81                                  DiagnosticsEngine::Level Level,
82                                  ArrayRef<CharSourceRange> Ranges,
83                                  const SourceManager &SM) = 0;
84   
85   virtual void emitBasicNote(StringRef Message) = 0;
86   
87   virtual void emitCodeContext(SourceLocation Loc,
88                                DiagnosticsEngine::Level Level,
89                                SmallVectorImpl<CharSourceRange>& Ranges,
90                                ArrayRef<FixItHint> Hints,
91                                const SourceManager &SM) = 0;
92   
93   virtual void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc,
94                                    const SourceManager &SM) = 0;
95   
96   virtual void beginDiagnostic(DiagOrStoredDiag D,
97                                DiagnosticsEngine::Level Level) {}
98   virtual void endDiagnostic(DiagOrStoredDiag D,
99                              DiagnosticsEngine::Level Level) {}
100
101   
102 private:
103   void emitIncludeStack(SourceLocation Loc, DiagnosticsEngine::Level Level,
104                         const SourceManager &SM);
105   void emitIncludeStackRecursively(SourceLocation Loc, const SourceManager &SM);
106   void emitMacroExpansionsAndCarets(SourceLocation Loc,
107                                     DiagnosticsEngine::Level Level,
108                                     SmallVectorImpl<CharSourceRange>& Ranges,
109                                     ArrayRef<FixItHint> Hints,
110                                     const SourceManager &SM,
111                                     unsigned &MacroDepth,
112                                     unsigned OnMacroInst = 0);
113 public:
114   /// \brief Emit a diagnostic.
115   ///
116   /// This is the primary entry point for emitting diagnostic messages.
117   /// It handles formatting and rendering the message as well as any ancillary
118   /// information needed based on macros whose expansions impact the
119   /// diagnostic.
120   ///
121   /// \param Loc The location for this caret.
122   /// \param Level The level of the diagnostic to be emitted.
123   /// \param Message The diagnostic message to emit.
124   /// \param Ranges The underlined ranges for this code snippet.
125   /// \param FixItHints The FixIt hints active for this diagnostic.
126   /// \param SM The SourceManager; will be null if the diagnostic came from the
127   ///        frontend, thus \p Loc will be invalid.
128   void emitDiagnostic(SourceLocation Loc, DiagnosticsEngine::Level Level,
129                       StringRef Message, ArrayRef<CharSourceRange> Ranges,
130                       ArrayRef<FixItHint> FixItHints,
131                       const SourceManager *SM,
132                       DiagOrStoredDiag D = (Diagnostic *)0);
133
134   void emitStoredDiagnostic(StoredDiagnostic &Diag);
135 };
136   
137 /// Subclass of DiagnosticRender that turns all subdiagostics into explicit
138 /// notes.  It is up to subclasses to further define the behavior.
139 class DiagnosticNoteRenderer : public DiagnosticRenderer {
140 public:
141   DiagnosticNoteRenderer(const LangOptions &LangOpts,
142                          DiagnosticOptions *DiagOpts)
143     : DiagnosticRenderer(LangOpts, DiagOpts) {}
144   
145   virtual ~DiagnosticNoteRenderer();
146   
147   virtual void emitBasicNote(StringRef Message);
148     
149   virtual void emitIncludeLocation(SourceLocation Loc,
150                                    PresumedLoc PLoc,
151                                    const SourceManager &SM);
152   
153   virtual void emitNote(SourceLocation Loc, StringRef Message,
154                         const SourceManager *SM) = 0;
155 };
156 } // end clang namespace
157 #endif