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

source code of gcc/analyzer/record-layout.cc