tree-object-size: use size_for_offset in more cases
[official-gcc.git] / gcc / selftest-diagnostic-path.cc
blob6d21f2e55999c6b8f3a70677f6cb4723dcaf6130
1 /* Concrete classes for selftests involving diagnostic paths.
2 Copyright (C) 2019-2024 Free Software Foundation, Inc.
3 Contributed by David Malcolm <dmalcolm@redhat.com>
5 This file is part of GCC.
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.
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.
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/>. */
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"
32 #if CHECKING_P
34 namespace selftest {
36 /* class test_diagnostic_path : public diagnostic_path. */
38 test_diagnostic_path::test_diagnostic_path (pretty_printer *event_pp)
39 : m_event_pp (event_pp)
41 add_thread ("main");
44 /* Implementation of diagnostic_path::num_events vfunc for
45 test_diagnostic_path: simply get the number of events in the vec. */
47 unsigned
48 test_diagnostic_path::num_events () const
50 return m_events.length ();
53 /* Implementation of diagnostic_path::get_event vfunc for
54 test_diagnostic_path: simply return the event in the vec. */
56 const diagnostic_event &
57 test_diagnostic_path::get_event (int idx) const
59 return *m_events[idx];
62 unsigned
63 test_diagnostic_path::num_threads () const
65 return m_threads.length ();
68 const diagnostic_thread &
69 test_diagnostic_path::get_thread (diagnostic_thread_id_t idx) const
71 return *m_threads[idx];
74 bool
75 test_diagnostic_path::same_function_p (int event_idx_a,
76 int event_idx_b) const
78 const char *name_a = m_events[event_idx_a]->get_function_name ();
79 const char *name_b = m_events[event_idx_b]->get_function_name ();
81 if (name_a && name_b)
82 return 0 == strcmp (name_a, name_b);
83 return name_a == name_b;
86 diagnostic_thread_id_t
87 test_diagnostic_path::add_thread (const char *name)
89 m_threads.safe_push (new test_diagnostic_thread (name));
90 return m_threads.length () - 1;
93 /* Add an event to this path at LOC within function FNDECL at
94 stack depth DEPTH.
96 Use m_context's printer to format FMT, as the text of the new
97 event.
99 Return the id of the new event. */
101 diagnostic_event_id_t
102 test_diagnostic_path::add_event (location_t loc,
103 const char *funcname,
104 int depth,
105 const char *fmt, ...)
107 pretty_printer *pp = m_event_pp;
108 pp_clear_output_area (pp);
110 rich_location rich_loc (line_table, UNKNOWN_LOCATION);
112 va_list ap;
114 va_start (ap, fmt);
116 /* No localization is done on FMT. */
117 text_info ti (fmt, &ap, 0, nullptr, &rich_loc);
118 pp_format (pp, &ti);
119 pp_output_formatted_text (pp);
121 va_end (ap);
123 test_diagnostic_event *new_event
124 = new test_diagnostic_event (loc, funcname, depth, pp_formatted_text (pp));
125 m_events.safe_push (new_event);
127 pp_clear_output_area (pp);
129 return diagnostic_event_id_t (m_events.length () - 1);
132 diagnostic_event_id_t
133 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, ...)
139 pretty_printer *pp = m_event_pp;
140 pp_clear_output_area (pp);
142 rich_location rich_loc (line_table, UNKNOWN_LOCATION);
144 va_list ap;
146 va_start (ap, fmt);
148 /* No localization is done on FMT. */
149 text_info ti (fmt, &ap, 0, nullptr, &rich_loc);
151 pp_format (pp, &ti);
152 pp_output_formatted_text (pp);
154 va_end (ap);
156 test_diagnostic_event *new_event
157 = new test_diagnostic_event (loc, funcname, depth, pp_formatted_text (pp),
158 thread_id);
159 m_events.safe_push (new_event);
161 pp_clear_output_area (pp);
163 return diagnostic_event_id_t (m_events.length () - 1);
166 /* Mark the most recent event on this path (which must exist) as being
167 connected to the next one to be added. */
169 void
170 test_diagnostic_path::connect_to_next_event ()
172 gcc_assert (m_events.length () > 0);
173 m_events[m_events.length () - 1]->connect_to_next_event ();
176 void
177 test_diagnostic_path::add_entry (const char *callee_name,
178 int stack_depth,
179 diagnostic_thread_id_t thread_id)
181 add_thread_event (thread_id, UNKNOWN_LOCATION, callee_name, stack_depth,
182 "entering %qs", callee_name);
185 void
186 test_diagnostic_path::add_return (const char *caller_name,
187 int stack_depth,
188 diagnostic_thread_id_t thread_id)
190 add_thread_event (thread_id, UNKNOWN_LOCATION, caller_name, stack_depth,
191 "returning to %qs", caller_name);
194 void
195 test_diagnostic_path::add_call (const char *caller_name,
196 int caller_stack_depth,
197 const char *callee_name,
198 diagnostic_thread_id_t thread_id)
200 add_thread_event (thread_id, UNKNOWN_LOCATION,
201 caller_name, caller_stack_depth,
202 "calling %qs", callee_name);
203 add_entry (callee_name, caller_stack_depth + 1, thread_id);
206 /* struct test_diagnostic_event. */
208 /* test_diagnostic_event's ctor. */
210 test_diagnostic_event::
211 test_diagnostic_event (location_t loc,
212 const char *funcname,
213 int depth,
214 const char *desc,
215 diagnostic_thread_id_t thread_id)
216 : m_loc (loc),
217 m_logical_loc (LOGICAL_LOCATION_KIND_FUNCTION, funcname),
218 m_depth (depth), m_desc (xstrdup (desc)),
219 m_connected_to_next_event (false),
220 m_thread_id (thread_id)
224 /* test_diagnostic_event's dtor. */
226 test_diagnostic_event::~test_diagnostic_event ()
228 free (m_desc);
231 } // namespace selftest
233 #endif /* #if CHECKING_P */