[PATCH][v5] RISC-V: add option -m(no-)autovec-segment
[official-gcc.git] / gcc / simple-diagnostic-path.cc
blobe1fcd565c8a6e1ab95055e00857cdce8b7e1035c
1 /* Concrete classes for implementing 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_MEMORY
24 #define INCLUDE_VECTOR
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tree.h"
28 #include "version.h"
29 #include "demangle.h"
30 #include "intl.h"
31 #include "backtrace.h"
32 #include "diagnostic.h"
33 #include "simple-diagnostic-path.h"
34 #include "selftest.h"
36 /* class simple_diagnostic_path : public diagnostic_path. */
38 simple_diagnostic_path::simple_diagnostic_path (pretty_printer *event_pp)
39 : m_event_pp (event_pp),
40 m_localize_events (true)
42 add_thread ("main");
45 /* Implementation of diagnostic_path::num_events vfunc for
46 simple_diagnostic_path: simply get the number of events in the vec. */
48 unsigned
49 simple_diagnostic_path::num_events () const
51 return m_events.length ();
54 /* Implementation of diagnostic_path::get_event vfunc for
55 simple_diagnostic_path: simply return the event in the vec. */
57 const diagnostic_event &
58 simple_diagnostic_path::get_event (int idx) const
60 return *m_events[idx];
63 unsigned
64 simple_diagnostic_path::num_threads () const
66 return m_threads.length ();
69 const diagnostic_thread &
70 simple_diagnostic_path::get_thread (diagnostic_thread_id_t idx) const
72 return *m_threads[idx];
75 bool
76 simple_diagnostic_path::same_function_p (int event_idx_a,
77 int event_idx_b) const
79 return (m_events[event_idx_a]->get_fndecl ()
80 == m_events[event_idx_b]->get_fndecl ());
83 diagnostic_thread_id_t
84 simple_diagnostic_path::add_thread (const char *name)
86 m_threads.safe_push (new simple_diagnostic_thread (name));
87 return m_threads.length () - 1;
90 /* Add an event to this path at LOC within function FNDECL at
91 stack depth DEPTH.
93 Use m_context's printer to format FMT, as the text of the new
94 event. Localize FMT iff m_localize_events is set.
96 Return the id of the new event. */
98 diagnostic_event_id_t
99 simple_diagnostic_path::add_event (location_t loc, tree fndecl, int depth,
100 const char *fmt, ...)
102 pretty_printer *pp = m_event_pp;
103 pp_clear_output_area (pp);
105 rich_location rich_loc (line_table, UNKNOWN_LOCATION);
107 va_list ap;
109 va_start (ap, fmt);
111 text_info ti (m_localize_events ? _(fmt) : fmt,
112 &ap, 0, nullptr, &rich_loc);
113 pp_format (pp, &ti);
114 pp_output_formatted_text (pp);
116 va_end (ap);
118 simple_diagnostic_event *new_event
119 = new simple_diagnostic_event (loc, fndecl, depth, pp_formatted_text (pp));
120 m_events.safe_push (new_event);
122 pp_clear_output_area (pp);
124 return diagnostic_event_id_t (m_events.length () - 1);
127 diagnostic_event_id_t
128 simple_diagnostic_path::add_thread_event (diagnostic_thread_id_t thread_id,
129 location_t loc,
130 tree fndecl,
131 int depth,
132 const char *fmt, ...)
134 pretty_printer *pp = m_event_pp;
135 pp_clear_output_area (pp);
137 rich_location rich_loc (line_table, UNKNOWN_LOCATION);
139 va_list ap;
141 va_start (ap, fmt);
143 text_info ti (_(fmt), &ap, 0, nullptr, &rich_loc);
145 pp_format (pp, &ti);
146 pp_output_formatted_text (pp);
148 va_end (ap);
150 simple_diagnostic_event *new_event
151 = new simple_diagnostic_event (loc, fndecl, depth, pp_formatted_text (pp),
152 thread_id);
153 m_events.safe_push (new_event);
155 pp_clear_output_area (pp);
157 return diagnostic_event_id_t (m_events.length () - 1);
160 /* Mark the most recent event on this path (which must exist) as being
161 connected to the next one to be added. */
163 void
164 simple_diagnostic_path::connect_to_next_event ()
166 gcc_assert (m_events.length () > 0);
167 m_events[m_events.length () - 1]->connect_to_next_event ();
170 /* struct simple_diagnostic_event. */
172 /* simple_diagnostic_event's ctor. */
174 simple_diagnostic_event::
175 simple_diagnostic_event (location_t loc,
176 tree fndecl,
177 int depth,
178 const char *desc,
179 diagnostic_thread_id_t thread_id)
180 : m_loc (loc), m_fndecl (fndecl), m_logical_loc (fndecl),
181 m_depth (depth), m_desc (xstrdup (desc)),
182 m_connected_to_next_event (false),
183 m_thread_id (thread_id)
187 /* simple_diagnostic_event's dtor. */
189 simple_diagnostic_event::~simple_diagnostic_event ()
191 free (m_desc);
194 #if CHECKING_P
196 namespace selftest {
198 static void
199 test_intraprocedural_path (pretty_printer *event_pp)
201 tree fntype_void_void
202 = build_function_type_array (void_type_node, 0, NULL);
203 tree fndecl_foo = build_fn_decl ("foo", fntype_void_void);
205 simple_diagnostic_path path (event_pp);
206 path.add_event (UNKNOWN_LOCATION, fndecl_foo, 0, "first %qs", "free");
207 path.add_event (UNKNOWN_LOCATION, fndecl_foo, 0, "double %qs", "free");
209 ASSERT_EQ (path.num_events (), 2);
210 ASSERT_EQ (path.num_threads (), 1);
211 ASSERT_FALSE (path.interprocedural_p ());
212 ASSERT_STREQ (path.get_event (0).get_desc (false).get (), "first `free'");
213 ASSERT_STREQ (path.get_event (1).get_desc (false).get (), "double `free'");
216 /* Run all of the selftests within this file. */
218 void
219 simple_diagnostic_path_cc_tests ()
221 /* In a few places we use the global dc's printer to determine
222 colorization so ensure this off during the tests. */
223 pretty_printer *global_pp = global_dc->m_printer;
224 const bool saved_show_color = pp_show_color (global_pp);
225 pp_show_color (global_pp) = false;
227 auto_fix_quotes fix_quotes;
228 std::unique_ptr<pretty_printer> event_pp
229 = std::unique_ptr<pretty_printer> (global_pp->clone ());
231 test_intraprocedural_path (event_pp.get ());
233 pp_show_color (global_pp) = saved_show_color;
236 } // namespace selftest
238 #endif /* #if CHECKING_P */