1/* Text art visualizations within -fanalyzer.
2 Copyright (C) 2023-2024 Free Software Foundation, Inc.
3 Contributed by David Malcolm <dmalcolm@redhat.com>.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it
8under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 3, or (at your option)
10any later version.
11
12GCC is distributed in the hope that it will be useful, but
13WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21#ifndef GCC_ANALYZER_ACCESS_DIAGRAM_H
22#define GCC_ANALYZER_ACCESS_DIAGRAM_H
23
24#include "text-art/canvas.h"
25#include "text-art/theme.h"
26#include "text-art/widget.h"
27#include "analyzer/analyzer.h"
28#include "analyzer/store.h"
29
30namespace ana {
31
32class bit_size_expr
33{
34public:
35 bit_size_expr (const svalue &num_bits) : m_num_bits (num_bits) {}
36
37 std::unique_ptr<text_art::styled_string>
38 maybe_get_formatted_str (text_art::style_manager &sm,
39 const region_model &model,
40 const char *concrete_single_bit_fmt,
41 const char *concrete_plural_bits_fmt,
42 const char *concrete_single_byte_fmt,
43 const char *concrete_plural_bytes_fmt,
44 const char *symbolic_bits_fmt,
45 const char *symbolic_bytes_fmt) const;
46 bool maybe_print_for_user (pretty_printer *pp,
47 const region_model &model) const;
48
49 const svalue *maybe_get_as_bytes (region_model_manager &mgr) const;
50
51private:
52 const svalue &m_num_bits;
53};
54
55/* A range of bits within a base region, where each endpoint
56 could be concrete or symbolic (not necessarily the same). */
57
58struct access_range
59{
60 access_range ()
61 : m_start (), m_next ()
62 {
63 }
64 access_range (region_offset start, region_offset next,
65 region_model_manager &mgr)
66 : m_start (strip_types (offset: start, mgr)), m_next (strip_types (offset: next, mgr))
67 {}
68 access_range (const region *base_region, const bit_range &bits);
69 access_range (const region *base_region, const byte_range &bytes);
70 access_range (const region &reg, region_model_manager *);
71
72 bool concrete_p () const
73 {
74 return m_start.concrete_p () && m_next.concrete_p ();
75 }
76
77 bool empty_p () const;
78
79 bit_size_expr get_size (region_model_manager *mgr) const;
80
81 bool get_size_in_bits (bit_size_t *out) const
82 {
83 if (concrete_p ())
84 {
85 *out = m_next.get_bit_offset () - m_start.get_bit_offset ();
86 return true;
87 }
88 return false;
89 }
90
91 bool as_concrete_bit_range (bit_range *out) const
92 {
93 if (!concrete_p ())
94 return false;
95 bit_size_t size = m_next.get_bit_offset () - m_start.get_bit_offset ();
96 *out = bit_range (m_start.get_bit_offset (), size);
97 return true;
98 }
99 bool as_concrete_byte_range (byte_range *out) const
100 {
101 bit_range bits (0, 0);
102 if (!as_concrete_bit_range (out: &bits))
103 return false;
104 return bits.as_byte_range (out);
105 }
106
107 bool contains_p (const access_range &other) const;
108
109 void dump_to_pp (pretty_printer *pp, bool) const;
110 void dump (bool) const;
111 void log (const char *title, logger &) const;
112
113 region_offset m_start;
114 region_offset m_next;
115};
116
117struct access_operation
118{
119 access_operation (const region_model &model,
120 enum access_direction dir,
121 const region &reg,
122 const svalue *sval_hint)
123 : m_model (model),
124 m_dir (dir),
125 m_reg (reg),
126 m_sval_hint (sval_hint),
127 m_base_region (reg.get_base_region ())
128 {}
129
130 region_model_manager *get_manager () const
131 {
132 return m_model.get_manager ();
133 }
134
135 /* Get the valid bits to access within the base region. */
136 access_range get_valid_bits () const;
137
138 /* Get the actual bits accessed within the base region. */
139 access_range get_actual_bits () const;
140
141 bool maybe_get_invalid_before_bits (access_range *out) const;
142 bool maybe_get_invalid_after_bits (access_range *out) const;
143
144 const region_model &m_model;
145 enum access_direction m_dir;
146 const region &m_reg;
147 const svalue *m_sval_hint;
148 const region *m_base_region;
149};
150
151class access_diagram : public text_art::wrapper_widget
152{
153public:
154 access_diagram (const access_operation &op,
155 diagnostic_event_id_t region_creation_event_id,
156 text_art::style_manager &sm,
157 const text_art::theme &theme,
158 logger *logger);
159 const char *get_desc () const override
160 {
161 return "access_diagram";
162 }
163};
164
165} // namespace ana
166
167#endif /* GCC_ANALYZER_ACCESS_DIAGRAM_H */
168

source code of gcc/analyzer/access-diagram.h