Branch data Line data Source code
1 : : /* Text art visualizations within -fanalyzer.
2 : : Copyright (C) 2023-2024 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
8 : : under the terms of the GNU General Public License as published by
9 : : the Free Software Foundation; either version 3, or (at your option)
10 : : any later version.
11 : :
12 : : GCC is distributed in the hope that it will be useful, but
13 : : WITHOUT ANY WARRANTY; without even the implied warranty of
14 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : : General Public License 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 : : #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 : :
30 : : namespace ana {
31 : :
32 : : class bit_size_expr
33 : : {
34 : : public:
35 : 30 : 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 : :
51 : : private:
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 : :
58 : : struct access_range
59 : : {
60 : 1291 : access_range ()
61 : 1291 : : m_start (), m_next ()
62 : : {
63 : 1291 : }
64 : 1915 : access_range (region_offset start, region_offset next,
65 : : region_model_manager &mgr)
66 : 1915 : : m_start (strip_types (start, mgr)), m_next (strip_types (next, mgr))
67 : 1915 : {}
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 ®, region_model_manager *);
71 : :
72 : 1066 : bool concrete_p () const
73 : : {
74 : 1031 : 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 : 455 : bool get_size_in_bits (bit_size_t *out) const
82 : : {
83 : 455 : if (concrete_p ())
84 : : {
85 : 387 : *out = m_next.get_bit_offset () - m_start.get_bit_offset ();
86 : 387 : return true;
87 : : }
88 : : return false;
89 : : }
90 : :
91 : 611 : bool as_concrete_bit_range (bit_range *out) const
92 : : {
93 : 611 : if (!concrete_p ())
94 : : return false;
95 : 509 : bit_size_t size = m_next.get_bit_offset () - m_start.get_bit_offset ();
96 : 509 : *out = bit_range (m_start.get_bit_offset (), size);
97 : 509 : return true;
98 : : }
99 : 60 : bool as_concrete_byte_range (byte_range *out) const
100 : : {
101 : 60 : bit_range bits (0, 0);
102 : 60 : if (!as_concrete_bit_range (&bits))
103 : : return false;
104 : 60 : 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 : :
117 : : struct access_operation
118 : : {
119 : 551 : access_operation (const region_model &model,
120 : : enum access_direction dir,
121 : : const region ®,
122 : : const svalue *sval_hint)
123 : 551 : : m_model (model),
124 : 551 : m_dir (dir),
125 : 551 : m_reg (reg),
126 : 551 : m_sval_hint (sval_hint),
127 : 551 : m_base_region (reg.get_base_region ())
128 : : {}
129 : :
130 : 2356 : region_model_manager *get_manager () const
131 : : {
132 : 2356 : 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 : :
151 : 72 : class access_diagram : public text_art::wrapper_widget
152 : : {
153 : : public:
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 : 0 : const char *get_desc () const override
160 : : {
161 : 0 : return "access_diagram";
162 : : }
163 : : };
164 : :
165 : : } // namespace ana
166 : :
167 : : #endif /* GCC_ANALYZER_ACCESS_DIAGRAM_H */
|