]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/Frontend/DiagnosticRenderer.h
Update clang to trunk r290819 and resolve conflicts.
[FreeBSD/FreeBSD.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_DIAGNOSTICRENDERER_H
17 #define LLVM_CLANG_FRONTEND_DIAGNOSTICRENDERER_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 ///
35 /// Actual "printing" logic is implemented by subclasses.
36 ///
37 /// This class provides an interface for building and emitting
38 /// diagnostic, including all of the macro backtraces, caret diagnostics, FixIt
39 /// Hints, and code snippets. In the presence of macros this involves
40 /// a recursive process, synthesizing notes for each macro expansion.
41 ///
42 /// A brief worklist:
43 /// FIXME: Sink the recursive printing of template instantiations into this
44 /// class.
45 class DiagnosticRenderer {
46 protected:
47   const LangOptions &LangOpts;
48   IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
49   
50   /// \brief The location of the previous diagnostic if known.
51   ///
52   /// This will be invalid in cases where there is no (known) previous
53   /// diagnostic location, or that location itself is invalid or comes from
54   /// a different source manager than SM.
55   SourceLocation LastLoc;
56   
57   /// \brief The location of the last include whose stack was printed if known.
58   ///
59   /// Same restriction as LastLoc essentially, but tracking include stack
60   /// root locations rather than diagnostic locations.
61   SourceLocation LastIncludeLoc;
62   
63   /// \brief The level of the last diagnostic emitted.
64   ///
65   /// The level of the last diagnostic emitted. Used to detect level changes
66   /// which change the amount of information displayed.
67   DiagnosticsEngine::Level LastLevel;
68
69   DiagnosticRenderer(const LangOptions &LangOpts,
70                      DiagnosticOptions *DiagOpts);
71   
72   virtual ~DiagnosticRenderer();
73   
74   virtual void emitDiagnosticMessage(SourceLocation Loc, PresumedLoc PLoc,
75                                      DiagnosticsEngine::Level Level,
76                                      StringRef Message,
77                                      ArrayRef<CharSourceRange> Ranges,
78                                      const SourceManager *SM,
79                                      DiagOrStoredDiag Info) = 0;
80   
81   virtual void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
82                                  DiagnosticsEngine::Level Level,
83                                  ArrayRef<CharSourceRange> Ranges,
84                                  const SourceManager &SM) = 0;
85
86   virtual void emitCodeContext(SourceLocation Loc,
87                                DiagnosticsEngine::Level Level,
88                                SmallVectorImpl<CharSourceRange>& Ranges,
89                                ArrayRef<FixItHint> Hints,
90                                const SourceManager &SM) = 0;
91   
92   virtual void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc,
93                                    const SourceManager &SM) = 0;
94   virtual void emitImportLocation(SourceLocation Loc, PresumedLoc PLoc,
95                                   StringRef ModuleName,
96                                   const SourceManager &SM) = 0;
97   virtual void emitBuildingModuleLocation(SourceLocation Loc, PresumedLoc PLoc,
98                                           StringRef ModuleName,
99                                           const SourceManager &SM) = 0;
100
101   virtual void beginDiagnostic(DiagOrStoredDiag D,
102                                DiagnosticsEngine::Level Level) {}
103   virtual void endDiagnostic(DiagOrStoredDiag D,
104                              DiagnosticsEngine::Level Level) {}
105
106   
107 private:
108   void emitBasicNote(StringRef Message);
109   void emitIncludeStack(SourceLocation Loc, PresumedLoc PLoc,
110                         DiagnosticsEngine::Level Level, const SourceManager &SM);
111   void emitIncludeStackRecursively(SourceLocation Loc, const SourceManager &SM);
112   void emitImportStack(SourceLocation Loc, const SourceManager &SM);
113   void emitImportStackRecursively(SourceLocation Loc, StringRef ModuleName,
114                                   const SourceManager &SM);
115   void emitModuleBuildStack(const SourceManager &SM);
116   void emitCaret(SourceLocation Loc, DiagnosticsEngine::Level Level,
117                  ArrayRef<CharSourceRange> Ranges, ArrayRef<FixItHint> Hints,
118                  const SourceManager &SM);
119   void emitSingleMacroExpansion(SourceLocation Loc,
120                                 DiagnosticsEngine::Level Level,
121                                 ArrayRef<CharSourceRange> Ranges,
122                                 const SourceManager &SM);
123   void emitMacroExpansions(SourceLocation Loc,
124                            DiagnosticsEngine::Level Level,
125                            ArrayRef<CharSourceRange> Ranges,
126                            ArrayRef<FixItHint> Hints,
127                            const SourceManager &SM);
128 public:
129   /// \brief Emit a diagnostic.
130   ///
131   /// This is the primary entry point for emitting diagnostic messages.
132   /// It handles formatting and rendering the message as well as any ancillary
133   /// information needed based on macros whose expansions impact the
134   /// diagnostic.
135   ///
136   /// \param Loc The location for this caret.
137   /// \param Level The level of the diagnostic to be emitted.
138   /// \param Message The diagnostic message to emit.
139   /// \param Ranges The underlined ranges for this code snippet.
140   /// \param FixItHints The FixIt hints active for this diagnostic.
141   /// \param SM The SourceManager; will be null if the diagnostic came from the
142   ///        frontend, thus \p Loc will be invalid.
143   void emitDiagnostic(SourceLocation Loc, DiagnosticsEngine::Level Level,
144                       StringRef Message, ArrayRef<CharSourceRange> Ranges,
145                       ArrayRef<FixItHint> FixItHints,
146                       const SourceManager *SM,
147                       DiagOrStoredDiag D = (Diagnostic *)nullptr);
148
149   void emitStoredDiagnostic(StoredDiagnostic &Diag);
150 };
151   
152 /// Subclass of DiagnosticRender that turns all subdiagostics into explicit
153 /// notes.  It is up to subclasses to further define the behavior.
154 class DiagnosticNoteRenderer : public DiagnosticRenderer {
155 public:
156   DiagnosticNoteRenderer(const LangOptions &LangOpts,
157                          DiagnosticOptions *DiagOpts)
158     : DiagnosticRenderer(LangOpts, DiagOpts) {}
159
160   ~DiagnosticNoteRenderer() override;
161
162   void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc,
163                            const SourceManager &SM) override;
164
165   void emitImportLocation(SourceLocation Loc, PresumedLoc PLoc,
166                           StringRef ModuleName,
167                           const SourceManager &SM) override;
168
169   void emitBuildingModuleLocation(SourceLocation Loc, PresumedLoc PLoc,
170                                   StringRef ModuleName,
171                                   const SourceManager &SM) override;
172
173   virtual void emitNote(SourceLocation Loc, StringRef Message,
174                         const SourceManager *SM) = 0;
175 };
176 } // end clang namespace
177 #endif