37 const exprt &given_alignment=
38 static_cast<const exprt &
>(type.
find(ID_C_alignment));
45 const auto a = numeric_cast<mp_integer>(given_alignment);
51 if(a_int>0 && !type.
get_bool(ID_C_packed))
54 else if(a_int==0 && type.
get_bool(ID_C_packed))
60 if(type.
id()==ID_array)
62 else if(type.
id()==ID_struct || type.
id()==ID_union)
69 result = std::max(result,
alignment(c.type(), ns));
71 else if(type.
id()==ID_unsignedbv ||
72 type.
id()==ID_signedbv ||
73 type.
id()==ID_fixedbv ||
74 type.
id()==ID_floatbv ||
75 type.
id()==ID_c_bool ||
76 type.
id()==ID_pointer)
80 else if(type.
id()==ID_c_enum)
82 else if(type.
id()==ID_c_enum_tag)
84 else if(type.
id() == ID_struct_tag)
86 else if(type.
id() == ID_union_tag)
88 else if(type.
id()==ID_c_bit_field)
98 if(a_int>0 && a_int<result)
104 static std::optional<std::size_t>
109 if(underlying_type.
id() == ID_bool)
115 underlying_type.
id() == ID_signedbv ||
116 underlying_type.
id() == ID_unsignedbv || underlying_type.
id() == ID_c_bool)
120 else if(underlying_type.
id() == ID_c_enum_tag)
125 const auto &c_enum_type =
128 if(!c_enum_type.is_incomplete())
139 struct_typet::componentst::iterator where,
140 std::size_t pad_bits)
151 return std::next(components.insert(where,
component));
154 static struct_typet::componentst::iterator
pad(
156 struct_typet::componentst::iterator where,
157 std::size_t pad_bits)
167 return std::next(components.insert(where,
component));
174 std::size_t bit_field_bits = 0, underlying_bits = 0;
177 bool is_packed = type.
get_bool(ID_C_packed);
179 for(struct_typet::componentst::iterator it = components.begin();
180 it != components.end();
187 it->type().id() == ID_c_bit_field &&
194 bit_field_bits += width;
203 if(underlying_bits != 0 && (bit_field_bits % underlying_bits) != 0)
205 const std::size_t pad_bits =
206 underlying_bits - (bit_field_bits % underlying_bits);
209 underlying_bits = bit_field_bits = 0;
214 underlying_bits = bit_field_bits = 0;
225 if(displacement != 0)
227 const mp_integer pad_bytes = a - displacement;
228 std::size_t pad_bits =
230 it =
pad(components, it, pad_bits);
237 if(it->type().id() == ID_c_bit_field)
242 bit_field_bits += width;
244 else if(it->is_boolean())
253 if(size.has_value() && *size >= 1)
261 if(underlying_bits != 0 && (bit_field_bits % underlying_bits) != 0)
263 const std::size_t
pad =
264 underlying_bits - (bit_field_bits % underlying_bits);
276 if(displacement != 0)
278 const mp_integer pad_bytes = a - displacement;
279 const std::size_t pad_bits =
281 pad(components, components.end(), pad_bits);
292 std::size_t bit_field_bits=0;
294 for(struct_typet::componentst::iterator
295 it=components.begin();
296 it!=components.end();
299 if(it->type().id()==ID_c_bit_field &&
304 bit_field_bits+=width;
306 else if(it->is_boolean())
310 else if(bit_field_bits!=0)
327 const std::size_t
pad =
335 std::size_t bit_field_bits=0;
336 const bool struct_is_packed = type.
get_bool(ID_C_packed);
338 for(struct_typet::componentst::iterator
339 it=components.begin();
340 it!=components.end();
343 const typet it_type=it->type();
346 if(it_type.
id()==ID_c_bit_field)
369 else if(it_type.
id() == ID_bool)
372 if(max_alignment < a)
385 bit_field_bits == 0,
"padding ensures offset at byte boundaries");
390 (it_type.
id() != ID_struct_tag ||
392 (it_type.
id() != ID_union_tag ||
410 const mp_integer pad_bytes = a - displacement;
411 const std::size_t pad_bits =
413 it =
pad(components, it, pad_bits);
426 static_cast<const exprt &
>(type.
find(ID_C_alignment));
433 if(tmp_i.has_value() && *tmp_i > max_alignment)
434 max_alignment = *tmp_i;
438 else if(struct_is_packed)
451 mp_integer pad_bytes = max_alignment - displacement;
452 std::size_t pad_bits =
454 pad(components, components.end(), pad_bits);
479 size_bits = std::max(size_bits, *s);
494 if(c.type().id() == ID_c_bit_field)
497 if(w.has_value() && w.value() > max_alignment_bits)
498 max_alignment_bits = w.value();
505 if(size_bits%max_alignment_bits!=0)
508 max_alignment_bits-(size_bits%max_alignment_bits);
511 numeric_cast_v<std::size_t>(size_bits + padding_bits));
const bitvector_typet & to_bitvector_type(const typet &type)
Cast a typet to a bitvector_typet.
const c_enum_typet & to_c_enum_type(const typet &type)
Cast a typet to a c_enum_typet.
const union_tag_typet & to_union_tag_type(const typet &type)
Cast a typet to a union_tag_typet.
const c_bit_field_typet & to_c_bit_field_type(const typet &type)
Cast a typet to a c_bit_field_typet.
const c_enum_tag_typet & to_c_enum_tag_type(const typet &type)
Cast a typet to a c_enum_tag_typet.
std::size_t get_width() const
Type for C bit fields These are both 'bitvector_typet' (they have a width) and 'type_with_subtypet' (...
const typet & underlying_type() const
struct configt::ansi_ct ansi_c
Base class for all expressions.
bool get_bool(const irep_idt &name) const
const irept & find(const irep_idt &name) const
const irep_idt & id() const
const union_typet & follow_tag(const union_tag_typet &) const
Follow type tag of union type.
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Structure type, corresponds to C style structs.
const componentst & components() const
std::vector< componentt > componentst
The type of an expression, extends irept.
Fixed-width bit-vector with unsigned binary interpretation.
mp_integer alignment(const typet &type, const namespacet &ns)
static void add_padding_msvc(struct_typet &type, const namespacet &ns)
static void add_padding_gcc(struct_typet &type, const namespacet &ns)
void add_padding(struct_typet &type, const namespacet &ns)
static std::optional< std::size_t > underlying_width(const c_bit_field_typet &type, const namespacet &ns)
static struct_typet::componentst::iterator pad(struct_typet::componentst &components, struct_typet::componentst::iterator where, std::size_t pad_bits)
static struct_typet::componentst::iterator pad_bit_field(struct_typet::componentst &components, struct_typet::componentst::iterator where, std::size_t pad_bits)
ANSI-C Language Type Checking.
std::optional< mp_integer > pointer_offset_bits(const typet &type, const namespacet &ns)
std::optional< mp_integer > pointer_offset_size(const typet &type, const namespacet &ns)
Compute the size of a type in bytes, rounding up to full bytes.
exprt simplify_expr(exprt src, const namespacet &ns)
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
auto component(T &struct_expr, const irep_idt &name, const namespacet &ns) -> decltype(struct_expr.op0())
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
const struct_union_typet & to_struct_union_type(const typet &type)
Cast a typet to a struct_union_typet.
const struct_tag_typet & to_struct_tag_type(const typet &type)
Cast a typet to a struct_tag_typet.
std::string to_string(const string_not_contains_constraintt &expr)
Used for debug printing.