Coverage Report

Created: 2018-09-23 03:40

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/include/clang/Frontend/DiagnosticRenderer.h
Line
Count
Source
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
23.2k
                               DiagnosticsEngine::Level Level) {}
100
  virtual void endDiagnostic(DiagOrStoredDiag D,
101
23.8k
                             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
526
      : 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