Branch data Line data Source code
1 : : /* Support for the DSL of -fdiagnostics-add-output= and
2 : : -fdiagnostics-set-output=.
3 : : Copyright (C) 2024-2025 Free Software Foundation, Inc.
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_OUTPUT_SPEC_H
22 : : #define GCC_DIAGNOSTICS_OUTPUT_SPEC_H
23 : :
24 : : #include "diagnostics/sink.h"
25 : : #include "diagnostics/output-file.h"
26 : :
27 : : namespace diagnostics {
28 : : namespace output_spec {
29 : :
30 : : class context;
31 : :
32 : : /* An abstract base class for schemes, and for client-specific keys. */
33 : :
34 : 4 : class key_handler
35 : : {
36 : : public:
37 : : enum class result
38 : : {
39 : : ok,
40 : : unrecognized,
41 : : malformed_value
42 : : };
43 : :
44 : : /* Attempt to decode KEY and VALUE, storing the decoded value. */
45 : : virtual enum result
46 : : maybe_handle_kv (const context &ctxt,
47 : : const std::string &key,
48 : : const std::string &value) = 0;
49 : :
50 : : virtual void
51 : : get_keys (auto_vec<const char *> &out) const = 0;
52 : :
53 : : enum result
54 : : parse_bool_value (const context &ctxt,
55 : : const std::string &key,
56 : : const std::string &value,
57 : : bool &out) const;
58 : :
59 : : template <typename EnumType, size_t NumValues>
60 : : enum result
61 : : parse_enum_value (const context &ctxt,
62 : : const std::string &key,
63 : : const std::string &value,
64 : : const std::array<std::pair<const char *, EnumType>,
65 : : NumValues> &value_names,
66 : : EnumType &out) const;
67 : : };
68 : :
69 : : /* Abstract subclass for handling particular schemes and their keys. */
70 : :
71 : : class scheme_handler : public key_handler
72 : : {
73 : : public:
74 : 123 : scheme_handler (std::string scheme_name)
75 : 123 : : m_scheme_name (std::move (scheme_name))
76 : : {}
77 : : virtual ~scheme_handler () {}
78 : :
79 : 79 : const std::string &get_scheme_name () const { return m_scheme_name; }
80 : :
81 : : virtual std::unique_ptr<sink>
82 : : make_sink (const context &ctxt,
83 : : diagnostics::context &dc) = 0;
84 : :
85 : : private:
86 : : const std::string m_scheme_name;
87 : : };
88 : :
89 : : /* An abstract base class for handling the DSL of -fdiagnostics-add-output=
90 : : and -fdiagnostics-set-output=. */
91 : :
92 : : class context
93 : : {
94 : : public:
95 : : std::unique_ptr<sink>
96 : : parse_and_make_sink (diagnostics::context &dc);
97 : :
98 : : void
99 : : report_error (const char *gmsgid, ...) const
100 : : ATTRIBUTE_GCC_DIAG(2,3);
101 : :
102 : : void
103 : : report_unknown_key (const std::string &key,
104 : : const scheme_handler &scheme) const;
105 : :
106 : : void
107 : : report_missing_key (const std::string &key,
108 : : const std::string &scheme_name,
109 : : const char *metavar) const;
110 : :
111 : : output_file
112 : : open_output_file (label_text &&filename) const;
113 : :
114 : : const char *
115 : 16 : get_option_name () const { return m_option_name; }
116 : :
117 : : const char *
118 : 85 : get_unparsed_spec () const { return m_unparsed_spec; }
119 : :
120 : : line_maps *
121 : 48 : get_affected_location_mgr () const { return m_affected_location_mgr; }
122 : :
123 : 69 : virtual ~context () {}
124 : :
125 : : virtual void
126 : : report_error_va (const char *gmsgid, va_list *ap) const = 0;
127 : :
128 : : virtual const char *
129 : : get_base_filename () const = 0;
130 : :
131 : : bool
132 : : handle_kv (const std::string &key,
133 : : const std::string &value,
134 : : scheme_handler &scheme) const;
135 : :
136 : : protected:
137 : 69 : context (const char *option_name,
138 : : const char *unparsed_spec,
139 : : key_handler *client_keys,
140 : : line_maps *affected_location_mgr)
141 : 69 : : m_option_name (option_name),
142 : 69 : m_unparsed_spec (unparsed_spec),
143 : 69 : m_client_keys (client_keys),
144 : 69 : m_affected_location_mgr (affected_location_mgr)
145 : : {
146 : : }
147 : :
148 : : // e.g. "-fdiagnostics-add-output="
149 : : const char *m_option_name;
150 : :
151 : : // e.g. "scheme:foo=bar,key=value"
152 : : const char *m_unparsed_spec;
153 : :
154 : : // Optional borrowed ptr to client-specific keys
155 : : key_handler *m_client_keys;
156 : :
157 : : line_maps *m_affected_location_mgr;
158 : : };
159 : :
160 : : /* A subclass that implements reporting errors via a diagnostics::context. */
161 : :
162 : 69 : struct dc_spec_context : public output_spec::context
163 : : {
164 : : public:
165 : 69 : dc_spec_context (const char *option_name,
166 : : const char *unparsed_spec,
167 : : key_handler *client_keys,
168 : : line_maps *affected_location_mgr,
169 : : diagnostics::context &dc,
170 : : line_maps *control_location_mgr,
171 : : location_t loc)
172 : 69 : : context (option_name,
173 : : unparsed_spec,
174 : : client_keys,
175 : : affected_location_mgr),
176 : 69 : m_dc (dc),
177 : 69 : m_control_location_mgr (control_location_mgr),
178 : 69 : m_loc (loc)
179 : : {}
180 : :
181 : 16 : void report_error_va (const char *gmsgid, va_list *ap) const final override
182 : : ATTRIBUTE_GCC_DIAG(2, 0)
183 : : {
184 : 16 : m_dc.begin_group ();
185 : 16 : rich_location richloc (m_control_location_mgr, m_loc);
186 : 16 : m_dc.diagnostic_impl (&richloc, nullptr, -1, gmsgid, ap, kind::error);
187 : 16 : m_dc.end_group ();
188 : 16 : }
189 : :
190 : : diagnostics::context &m_dc;
191 : : line_maps *m_control_location_mgr;
192 : : location_t m_loc;
193 : : };
194 : :
195 : : } // namespace output_spec
196 : : } // namespace diagnostics
197 : :
198 : : #endif // #ifndef GCC_DIAGNOSTICS_OUTPUT_SPEC_H
|