Coverage Report

Created: 2023-11-11 10:31

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