Branch data Line data Source code
1 : : /* Implementation of class record_layout.
2 : : Copyright (C) 2022-2025 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 : : #include "analyzer/common.h"
22 : :
23 : : #include "tree-diagnostic.h"
24 : :
25 : : #include "analyzer/record-layout.h"
26 : :
27 : : #if ENABLE_ANALYZER
28 : :
29 : : namespace ana {
30 : :
31 : : /* class record_layout. */
32 : :
33 : 17 : record_layout::record_layout (tree record_type)
34 : : {
35 : 17 : gcc_assert (TREE_CODE (record_type) == RECORD_TYPE);
36 : :
37 : 94 : for (tree iter = TYPE_FIELDS (record_type); iter != NULL_TREE;
38 : 77 : iter = DECL_CHAIN (iter))
39 : : {
40 : 77 : if (TREE_CODE (iter) == FIELD_DECL)
41 : : {
42 : 77 : int iter_field_offset = int_bit_position (iter);
43 : 77 : bit_size_t size_in_bits;
44 : 77 : if (!int_size_in_bits (TREE_TYPE (iter), &size_in_bits))
45 : 0 : size_in_bits = 0;
46 : :
47 : 77 : maybe_pad_to (iter_field_offset);
48 : :
49 : : /* Add field. */
50 : 77 : m_items.safe_push (item (bit_range (iter_field_offset,
51 : 77 : size_in_bits),
52 : 77 : iter, false));
53 : : }
54 : : }
55 : :
56 : : /* Add any trailing padding. */
57 : 17 : bit_size_t size_in_bits;
58 : 17 : if (int_size_in_bits (record_type, &size_in_bits))
59 : 17 : maybe_pad_to (size_in_bits);
60 : 17 : }
61 : :
62 : : void
63 : 0 : record_layout::dump_to_pp (pretty_printer *pp) const
64 : : {
65 : 0 : unsigned i;
66 : 0 : item *it;
67 : 0 : FOR_EACH_VEC_ELT (m_items, i, it)
68 : : {
69 : 0 : it->dump_to_pp (pp);
70 : 0 : pp_newline (pp);
71 : : }
72 : 0 : }
73 : :
74 : : void
75 : 0 : record_layout::dump () const
76 : : {
77 : 0 : tree_dump_pretty_printer pp (stderr);
78 : 0 : dump_to_pp (&pp);
79 : 0 : }
80 : :
81 : : const record_layout::item *
82 : 55 : record_layout::get_item_at (bit_offset_t offset) const
83 : : {
84 : 55 : unsigned i;
85 : 55 : item *it;
86 : 841 : FOR_EACH_VEC_ELT (m_items, i, it)
87 : 841 : if (it->contains_p (offset))
88 : : return it;
89 : : return NULL;
90 : : }
91 : :
92 : : /* Subroutine of ctor. Add padding item to NEXT_OFFSET if necessary. */
93 : :
94 : : void
95 : 94 : record_layout::maybe_pad_to (bit_offset_t next_offset)
96 : : {
97 : 94 : if (m_items.length () > 0)
98 : : {
99 : 77 : const item &last_item = m_items[m_items.length () - 1];
100 : 77 : bit_offset_t offset_after_last_item
101 : 77 : = last_item.get_next_bit_offset ();
102 : 77 : if (next_offset > offset_after_last_item)
103 : : {
104 : 11 : bit_size_t padding_size
105 : 11 : = next_offset - offset_after_last_item;
106 : 11 : m_items.safe_push (item (bit_range (offset_after_last_item,
107 : 11 : padding_size),
108 : 11 : last_item.m_field, true));
109 : : }
110 : : }
111 : 94 : }
112 : :
113 : : } // namespace ana
114 : :
115 : : #endif /* #if ENABLE_ANALYZER */
|