Branch data Line data Source code
1 : : /* Support for buffering diagnostics before flushing them to output sinks.
2 : : Copyright (C) 2024-2025 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 : 11356 : int diagnostic_count (enum kind kind) const
70 : : {
71 : 7301 : 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 : 96227 : 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 */
|