Line data Source code
1 : /* Support for buffering diagnostics before flushing them to output sinks.
2 : Copyright (C) 2024-2026 Free Software Foundation, Inc.
3 : Contributed by David Malcolm <dmalcolm@redhat.com>.
4 :
5 : This file is part of GCC.
6 :
7 : GCC is free software; you can redistribute it and/or modify it under
8 : the terms of the GNU General Public License as published by the Free
9 : Software Foundation; either version 3, or (at your option) any later
10 : version.
11 :
12 : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 : WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 : for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with GCC; see the file COPYING3. If not see
19 : <http://www.gnu.org/licenses/>. */
20 :
21 : #ifndef GCC_DIAGNOSTICS_BUFFERING_H
22 : #define GCC_DIAGNOSTICS_BUFFERING_H
23 :
24 : #include "diagnostics/counters.h"
25 :
26 : namespace diagnostics {
27 :
28 : class per_sink_buffer;
29 : class sink;
30 : class text_sink;
31 :
32 : /* Class representing a buffer of zero or more diagnostics that
33 : have been reported to a diagnostics::context, but which haven't
34 : yet been flushed.
35 :
36 : A diagnostics::buffer can be:
37 :
38 : * flushed to the diagnostics::context, which issues
39 : the diagnostics within the buffer to the output sinks
40 : and checks for limits such as -fmax-errors=, or
41 :
42 : * moved to another diagnostics::buffer, which moves the diagnostics
43 : within the first buffer to the other buffer, appending them after any
44 : existing diagnostics within the destination buffer, emptying the
45 : source buffer, or
46 :
47 : * cleared, which discards any diagnostics within the buffer
48 : without issuing them to the output sinks.
49 :
50 : Since a buffer needs to contain sink-specific data,
51 : it's not possible to change the output sink(s) of the
52 : diagnostics::context once any buffers are non-empty.
53 :
54 : To simplify implementing output sinks, it's not possible
55 : to change buffering on a diagnostics::context whilst within a
56 : diagnostic group. */
57 :
58 : class buffer
59 : {
60 : public:
61 : friend class context;
62 :
63 : buffer (context &ctxt);
64 : ~buffer ();
65 :
66 : void dump (FILE *out, int indent) const;
67 0 : void DEBUG_FUNCTION dump () const { dump (stderr, 0); }
68 :
69 11461 : int diagnostic_count (enum kind kind) const
70 : {
71 7387 : return m_diagnostic_counters.get_count (kind);
72 : }
73 :
74 : bool empty_p () const;
75 :
76 : void move_to (buffer &dest);
77 :
78 : private:
79 : void ensure_per_sink_buffers ();
80 :
81 : context &m_ctxt;
82 : auto_vec<per_sink_buffer *> *m_per_sink_buffers;
83 :
84 : /* The number of buffered diagnostics of each kind. */
85 : counters m_diagnostic_counters;
86 : };
87 :
88 : /* Implementation detail of diagnostics::buffer.
89 :
90 : Abstract base class describing how to represent zero of more
91 : buffered diagnostics for a particular diagnostics::sink
92 : (e.g. text vs SARIF).
93 :
94 : Each diagnostics::sink subclass should implement its own
95 : subclass for handling diagnostics::buffer. */
96 :
97 98076 : class per_sink_buffer
98 : {
99 : public:
100 : virtual ~per_sink_buffer () {}
101 :
102 : virtual void dump (FILE *out, int indent) const = 0;
103 0 : void DEBUG_FUNCTION dump () const { dump (stderr, 0); }
104 :
105 : virtual bool empty_p () const = 0;
106 : virtual void move_to (per_sink_buffer &dest) = 0;
107 : virtual void clear () = 0;
108 : virtual void flush () = 0;
109 : };
110 :
111 : } // namespace diagnostics
112 :
113 : #endif /* ! GCC_DIAGNOSTICS_BUFFERING_H */
|