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