Line data Source code
1 : /* Implementation of class record_layout.
2 : Copyright (C) 2022-2026 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 57 : record_layout::record_layout (const_tree record_type)
34 : {
35 57 : gcc_assert (TREE_CODE (record_type) == RECORD_TYPE);
36 :
37 214 : for (tree iter = TYPE_FIELDS (record_type); iter != NULL_TREE;
38 157 : iter = DECL_CHAIN (iter))
39 : {
40 157 : if (TREE_CODE (iter) == FIELD_DECL)
41 : {
42 157 : int iter_field_offset = int_bit_position (iter);
43 157 : bit_size_t size_in_bits;
44 157 : if (!int_size_in_bits (TREE_TYPE (iter), &size_in_bits))
45 0 : size_in_bits = 0;
46 :
47 157 : maybe_pad_to (iter_field_offset);
48 :
49 : /* Add field. */
50 157 : m_items.safe_push (item (bit_range (iter_field_offset,
51 157 : size_in_bits),
52 157 : iter, false));
53 : }
54 : }
55 :
56 : /* Add any trailing padding. */
57 57 : bit_size_t size_in_bits;
58 57 : if (int_size_in_bits (record_type, &size_in_bits))
59 57 : maybe_pad_to (size_in_bits);
60 57 : }
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 nullptr;
90 : }
91 :
92 : /* Subroutine of ctor. Add padding item to NEXT_OFFSET if necessary. */
93 :
94 : void
95 214 : record_layout::maybe_pad_to (bit_offset_t next_offset)
96 : {
97 214 : if (m_items.length () > 0)
98 : {
99 157 : const item &last_item = m_items[m_items.length () - 1];
100 157 : bit_offset_t offset_after_last_item
101 157 : = last_item.get_next_bit_offset ();
102 157 : if (next_offset > offset_after_last_item)
103 : {
104 47 : bit_size_t padding_size
105 47 : = next_offset - offset_after_last_item;
106 47 : m_items.safe_push (item (bit_range (offset_after_last_item,
107 47 : padding_size),
108 47 : last_item.m_field, true));
109 : }
110 : }
111 214 : }
112 :
113 : } // namespace ana
114 :
115 : #endif /* #if ENABLE_ANALYZER */
|