1/*******************************************************************\
5Author: Daniel Kroening, kroening@kroening.com
7\*******************************************************************/
32 // the following optimization only works on structs,
51 "member expression type must match component type");
55 else // something else, get rid of it
63 // do this recursively
72 // WITH(s, .m, v).m -> v
86 // look at very first designator
87 if(designator.size()==1 &&
92 // UPDATE(s, .m, v).m -> v
95 // the following optimization only works on structs,
99 // UPDATE(s, .m1, v).m2 -> s.m2
103 // do this recursively
111 // pull out the right member
118 std::size_t number =
struct_type.component_number(component_name);
121 "struct expression must have sufficiently many operands");
124 "member expression type must match component type");
135 // This rewrites byte_extract(s, o, struct_type).member
136 // to byte_extract(s, o+member_offset, member_type)
152 // add member offset to index
173 // rewrite byte_extract(X, 0).member to X
174 // if the type of X is that of the member
199 if(target_size.has_value())
204 if(bits.has_value() &&
213 return std::move(*
tmp);
221 // Try to look through member(cast(x)) if the cast is between structurally
230 // Try to translate into an equivalent member (perhaps nested) of the type
231 // being cast (for example, this might turn ((struct A)x).field1 into
232 // x.substruct.othersubstruct.field2, if field1 and field2 have the same
233 // type and offset with respect to x.
247 // Guess: turning this into a byte-extract operation is not really an
262 // Push a member operator inside a let binding, to avoid the let bisecting
263 // structures we otherwise know how to analyse, such as
264 // (let x = 1 in ({x, x})).field1 --> let x = 1 in ({x, x}.field1) -->
291 if(
r_it.has_changed())
Expression classes for byte-level operators.
const byte_extract_exprt & to_byte_extract_expr(const exprt &expr)
const union_typet & to_union_type(const typet &type)
Cast a typet to a union_typet.
const union_tag_typet & to_union_tag_type(const typet &type)
Cast a typet to a union_tag_typet.
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
struct configt::ansi_ct ansi_c
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Base class for all expressions.
std::vector< exprt > operandst
typet & type()
Return the type of the expression.
The trinary if-then-else operator.
const irep_idt & get(const irep_idt &name) const
const irep_idt & id() const
Extract member of struct or union.
const exprt & compound() const
The plus expression Associativity is not specified.
resultt simplify_byte_extract(const byte_extract_exprt &)
resultt simplify_member_preorder(const member_exprt &)
static resultt changed(resultt<> result)
resultt simplify_rec(const exprt &)
resultt simplify_member(const member_exprt &)
static resultt unchanged(exprt expr)
resultt simplify_plus(const plus_exprt &)
resultt simplify_if_preorder(const if_exprt &expr)
Structure type, corresponds to C style structs.
The type of an expression, extends irept.
Operator to update elements in structs and arrays.
Operator to update elements in structs and arrays.
if_exprt lift_if(const exprt &src, std::size_t operand_number)
lift up an if_exprt one level
Deprecated expression utility functions.
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.
std::optional< exprt > get_subexpression_at_offset(const exprt &expr, const mp_integer &offset_bytes, const typet &target_type_raw, const namespacet &ns)
std::optional< mp_integer > member_offset(const struct_typet &type, const irep_idt &member, const namespacet &ns)
std::optional< exprt > bits2expr(const std::string &bits, const typet &type, bool little_endian, const namespacet &ns)
std::optional< std::string > expr2bits(const exprt &expr, bool little_endian, 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())
API to expression classes.
const typecast_exprt & to_typecast_expr(const exprt &expr)
Cast an exprt to a typecast_exprt.
const let_exprt & to_let_expr(const exprt &expr)
Cast an exprt to a let_exprt.
const member_exprt & to_member_expr(const exprt &expr)
Cast an exprt to a member_exprt.
const union_exprt & to_union_expr(const exprt &expr)
Cast an exprt to a union_exprt.
const with_exprt & to_with_expr(const exprt &expr)
Cast an exprt to a with_exprt.
const update_exprt & to_update_expr(const exprt &expr)
Cast an exprt to an update_exprt.
const struct_typet & to_struct_type(const typet &type)
Cast a typet to a struct_typet.
const struct_tag_typet & to_struct_tag_type(const typet &type)
Cast a typet to a struct_tag_typet.