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