Line data Source code
1 : /* Concrete classes for selftests involving diagnostic paths.
2 : Copyright (C) 2019-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 :
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 */
|