Branch data Line data Source code
1 : : /* Concrete classes for selftests involving diagnostic paths.
2 : : Copyright (C) 2019-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 : :
22 : : #include "config.h"
23 : : #define INCLUDE_VECTOR
24 : : #include "system.h"
25 : : #include "coretypes.h"
26 : : #include "version.h"
27 : : #include "demangle.h"
28 : : #include "backtrace.h"
29 : : #include "diagnostic.h"
30 : : #include "selftest-diagnostic-path.h"
31 : :
32 : : #if CHECKING_P
33 : :
34 : : namespace selftest {
35 : :
36 : : /* class test_diagnostic_path : public diagnostic_path. */
37 : :
38 : 1652 : test_diagnostic_path::test_diagnostic_path (pretty_printer *event_pp)
39 : : : diagnostic_path (m_test_logical_loc_mgr),
40 : 1652 : m_event_pp (event_pp)
41 : : {
42 : 1652 : add_thread ("main");
43 : 1652 : }
44 : :
45 : : /* Implementation of diagnostic_path::num_events vfunc for
46 : : test_diagnostic_path: simply get the number of events in the vec. */
47 : :
48 : : unsigned
49 : 5720 : test_diagnostic_path::num_events () const
50 : : {
51 : 5720 : return m_events.length ();
52 : : }
53 : :
54 : : /* Implementation of diagnostic_path::get_event vfunc for
55 : : test_diagnostic_path: simply return the event in the vec. */
56 : :
57 : : const diagnostic_event &
58 : 18952 : test_diagnostic_path::get_event (int idx) const
59 : : {
60 : 18952 : return *m_events[idx];
61 : : }
62 : :
63 : : unsigned
64 : 0 : test_diagnostic_path::num_threads () const
65 : : {
66 : 0 : return m_threads.length ();
67 : : }
68 : :
69 : : const diagnostic_thread &
70 : 1280 : test_diagnostic_path::get_thread (diagnostic_thread_id_t idx) const
71 : : {
72 : 1280 : return *m_threads[idx];
73 : : }
74 : :
75 : : bool
76 : 6240 : test_diagnostic_path::same_function_p (int event_idx_a,
77 : : int event_idx_b) const
78 : : {
79 : 6240 : return (m_events[event_idx_a]->get_logical_location ()
80 : 6240 : == m_events[event_idx_b]->get_logical_location ());
81 : : }
82 : :
83 : : diagnostic_thread_id_t
84 : 1652 : test_diagnostic_path::add_thread (const char *name)
85 : : {
86 : 1652 : m_threads.safe_push (new test_diagnostic_thread (name));
87 : 1652 : return m_threads.length () - 1;
88 : : }
89 : :
90 : : /* Add an event to this path at LOC within function FNDECL at
91 : : stack depth DEPTH.
92 : :
93 : : Use m_context's printer to format FMT, as the text of the new
94 : : event.
95 : :
96 : : Return the id of the new event. */
97 : :
98 : : diagnostic_event_id_t
99 : 4532 : test_diagnostic_path::add_event (location_t loc,
100 : : const char *funcname,
101 : : int depth,
102 : : const char *fmt, ...)
103 : : {
104 : 4532 : pretty_printer *pp = m_event_pp;
105 : 4532 : pp_clear_output_area (pp);
106 : :
107 : 4532 : rich_location rich_loc (line_table, UNKNOWN_LOCATION);
108 : :
109 : 4532 : va_list ap;
110 : :
111 : 4532 : va_start (ap, fmt);
112 : :
113 : : /* No localization is done on FMT. */
114 : 4532 : text_info ti (fmt, &ap, 0, nullptr, &rich_loc);
115 : 4532 : pp_format (pp, &ti);
116 : 4532 : pp_output_formatted_text (pp);
117 : :
118 : 4532 : va_end (ap);
119 : :
120 : 4532 : test_diagnostic_event *new_event
121 : : = new test_diagnostic_event (loc,
122 : : logical_location_from_funcname (funcname),
123 : : depth,
124 : 4532 : pp_formatted_text (pp));
125 : 4532 : m_events.safe_push (new_event);
126 : :
127 : 4532 : pp_clear_output_area (pp);
128 : :
129 : 9064 : return diagnostic_event_id_t (m_events.length () - 1);
130 : 4532 : }
131 : :
132 : : diagnostic_event_id_t
133 : 120 : test_diagnostic_path::add_thread_event (diagnostic_thread_id_t thread_id,
134 : : location_t loc,
135 : : const char *funcname,
136 : : int depth,
137 : : const char *fmt, ...)
138 : : {
139 : 120 : pretty_printer *pp = m_event_pp;
140 : 120 : pp_clear_output_area (pp);
141 : :
142 : 120 : rich_location rich_loc (line_table, UNKNOWN_LOCATION);
143 : :
144 : 120 : va_list ap;
145 : :
146 : 120 : va_start (ap, fmt);
147 : :
148 : : /* No localization is done on FMT. */
149 : 120 : text_info ti (fmt, &ap, 0, nullptr, &rich_loc);
150 : :
151 : 120 : pp_format (pp, &ti);
152 : 120 : pp_output_formatted_text (pp);
153 : :
154 : 120 : va_end (ap);
155 : :
156 : 120 : test_diagnostic_event *new_event
157 : : = new test_diagnostic_event (loc,
158 : : logical_location_from_funcname (funcname),
159 : : depth,
160 : : pp_formatted_text (pp),
161 : 120 : thread_id);
162 : 120 : m_events.safe_push (new_event);
163 : :
164 : 120 : pp_clear_output_area (pp);
165 : :
166 : 240 : return diagnostic_event_id_t (m_events.length () - 1);
167 : 120 : }
168 : :
169 : : /* Mark the most recent event on this path (which must exist) as being
170 : : connected to the next one to be added. */
171 : :
172 : : void
173 : 2016 : test_diagnostic_path::connect_to_next_event ()
174 : : {
175 : 2016 : gcc_assert (m_events.length () > 0);
176 : 2016 : m_events[m_events.length () - 1]->connect_to_next_event ();
177 : 2016 : }
178 : :
179 : : void
180 : 60 : test_diagnostic_path::add_entry (const char *callee_name,
181 : : int stack_depth,
182 : : diagnostic_thread_id_t thread_id)
183 : : {
184 : 60 : add_thread_event (thread_id, UNKNOWN_LOCATION, callee_name, stack_depth,
185 : : "entering %qs", callee_name);
186 : 60 : }
187 : :
188 : : void
189 : 12 : test_diagnostic_path::add_return (const char *caller_name,
190 : : int stack_depth,
191 : : diagnostic_thread_id_t thread_id)
192 : : {
193 : 12 : add_thread_event (thread_id, UNKNOWN_LOCATION, caller_name, stack_depth,
194 : : "returning to %qs", caller_name);
195 : 12 : }
196 : :
197 : : void
198 : 48 : test_diagnostic_path::add_call (const char *caller_name,
199 : : int caller_stack_depth,
200 : : const char *callee_name,
201 : : diagnostic_thread_id_t thread_id)
202 : : {
203 : 48 : add_thread_event (thread_id, UNKNOWN_LOCATION,
204 : : caller_name, caller_stack_depth,
205 : : "calling %qs", callee_name);
206 : 48 : add_entry (callee_name, caller_stack_depth + 1, thread_id);
207 : 48 : }
208 : :
209 : : logical_location
210 : 4652 : test_diagnostic_path::logical_location_from_funcname (const char *funcname)
211 : : {
212 : 4652 : return m_test_logical_loc_mgr.logical_location_from_funcname (funcname);
213 : : }
214 : :
215 : : /* struct test_diagnostic_event. */
216 : :
217 : : /* test_diagnostic_event's ctor. */
218 : :
219 : 4652 : test_diagnostic_event::
220 : : test_diagnostic_event (location_t loc,
221 : : logical_location logical_loc,
222 : : int depth,
223 : : const char *desc,
224 : 4652 : diagnostic_thread_id_t thread_id)
225 : 4652 : : m_loc (loc),
226 : 4652 : m_logical_loc (logical_loc),
227 : 4652 : m_depth (depth), m_desc (xstrdup (desc)),
228 : 4652 : m_connected_to_next_event (false),
229 : 4652 : m_thread_id (thread_id)
230 : : {
231 : 4652 : }
232 : :
233 : : /* test_diagnostic_event's dtor. */
234 : :
235 : 9304 : test_diagnostic_event::~test_diagnostic_event ()
236 : : {
237 : 4652 : free (m_desc);
238 : 9304 : }
239 : :
240 : : } // namespace selftest
241 : :
242 : : #endif /* #if CHECKING_P */
|