CBMC
pointer_offset_size.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Pointer Logic
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
11 
12 #include "pointer_offset_size.h"
13 
14 #include "arith_tools.h"
15 #include "byte_operators.h"
16 #include "c_types.h"
17 #include "invariant.h"
18 #include "namespace.h"
19 #include "pointer_expr.h"
20 #include "simplify_expr.h"
21 #include "ssa_expr.h"
22 #include "std_expr.h"
23 
25  const struct_typet &type,
26  const irep_idt &member,
27  const namespacet &ns)
28 {
29  mp_integer result = 0;
30  std::size_t bit_field_bits = 0;
31 
32  for(const auto &comp : type.components())
33  {
34  if(comp.get_name() == member)
35  return result;
36 
37  if(comp.type().id() == ID_c_bit_field)
38  {
39  const std::size_t w = to_c_bit_field_type(comp.type()).get_width();
40  bit_field_bits += w;
41  result += bit_field_bits / 8;
42  bit_field_bits %= 8;
43  }
44  else if(comp.type().id() == ID_bool)
45  {
46  ++bit_field_bits;
47  result += bit_field_bits / 8;
48  bit_field_bits %= 8;
49  }
50  else
51  {
53  bit_field_bits == 0, "padding ensures offset at byte boundaries");
54  const auto sub_size = pointer_offset_size(comp.type(), ns);
55  if(!sub_size.has_value())
56  return {};
57  else
58  result += *sub_size;
59  }
60  }
61 
62  return result;
63 }
64 
66  const struct_typet &type,
67  const irep_idt &member,
68  const namespacet &ns)
69 {
70  mp_integer offset=0;
71  const struct_typet::componentst &components=type.components();
72 
73  for(const auto &comp : components)
74  {
75  if(comp.get_name()==member)
76  return offset;
77 
78  auto member_bits = pointer_offset_bits(comp.type(), ns);
79  if(!member_bits.has_value())
80  return {};
81 
82  offset += *member_bits;
83  }
84 
85  return {};
86 }
87 
90 pointer_offset_size(const typet &type, const namespacet &ns)
91 {
92  auto bits = pointer_offset_bits(type, ns);
93 
94  if(bits.has_value())
95  return (*bits + 7) / 8;
96  else
97  return {};
98 }
99 
101 pointer_offset_bits(const typet &type, const namespacet &ns)
102 {
103  if(type.id()==ID_array)
104  {
105  auto sub = pointer_offset_bits(to_array_type(type).element_type(), ns);
106  if(!sub.has_value())
107  return {};
108 
109  // get size - we can only distinguish the elements if the size is constant
110  const auto size = numeric_cast<mp_integer>(to_array_type(type).size());
111  if(!size.has_value())
112  return {};
113 
114  return (*sub) * (*size);
115  }
116  else if(type.id()==ID_vector)
117  {
118  auto sub = pointer_offset_bits(to_vector_type(type).element_type(), ns);
119  if(!sub.has_value())
120  return {};
121 
122  // get size
123  const mp_integer size =
124  numeric_cast_v<mp_integer>(to_vector_type(type).size());
125 
126  return (*sub) * size;
127  }
128  else if(type.id()==ID_complex)
129  {
130  auto sub = pointer_offset_bits(to_complex_type(type).subtype(), ns);
131 
132  if(sub.has_value())
133  return (*sub) * 2;
134  else
135  return {};
136  }
137  else if(type.id()==ID_struct)
138  {
139  const struct_typet &struct_type=to_struct_type(type);
140  mp_integer result=0;
141 
142  for(const auto &c : struct_type.components())
143  {
144  const typet &subtype = c.type();
145  auto sub_size = pointer_offset_bits(subtype, ns);
146 
147  if(!sub_size.has_value())
148  return {};
149 
150  result += *sub_size;
151  }
152 
153  return result;
154  }
155  else if(type.id()==ID_union)
156  {
157  const union_typet &union_type=to_union_type(type);
158 
159  if(union_type.components().empty())
160  return mp_integer{0};
161 
162  const auto widest_member = union_type.find_widest_union_component(ns);
163 
164  if(widest_member.has_value())
165  return widest_member->second;
166  else
167  return {};
168  }
169  else if(type.id()==ID_signedbv ||
170  type.id()==ID_unsignedbv ||
171  type.id()==ID_fixedbv ||
172  type.id()==ID_floatbv ||
173  type.id()==ID_bv ||
174  type.id()==ID_c_bool ||
175  type.id()==ID_c_bit_field)
176  {
177  return mp_integer(to_bitvector_type(type).get_width());
178  }
179  else if(type.id()==ID_c_enum)
180  {
181  return mp_integer(
182  to_bitvector_type(to_c_enum_type(type).underlying_type()).get_width());
183  }
184  else if(type.id()==ID_c_enum_tag)
185  {
186  return pointer_offset_bits(ns.follow_tag(to_c_enum_tag_type(type)), ns);
187  }
188  else if(type.id()==ID_bool)
189  {
190  return mp_integer(1);
191  }
192  else if(type.id()==ID_pointer)
193  {
194  // the following is an MS extension
195  if(type.get_bool(ID_C_ptr32))
196  return mp_integer(32);
197 
198  return mp_integer(to_bitvector_type(type).get_width());
199  }
200  else if(type.id() == ID_union_tag)
201  {
202  return pointer_offset_bits(ns.follow_tag(to_union_tag_type(type)), ns);
203  }
204  else if(type.id() == ID_struct_tag)
205  {
206  return pointer_offset_bits(ns.follow_tag(to_struct_tag_type(type)), ns);
207  }
208  else if(type.id()==ID_code)
209  {
210  return mp_integer(0);
211  }
212  else if(type.id()==ID_string)
213  {
214  return mp_integer(32);
215  }
216  else
217  return {};
218 }
219 
221 member_offset_expr(const member_exprt &member_expr, const namespacet &ns)
222 {
223  // need to distinguish structs and unions
224  const typet &type=ns.follow(member_expr.struct_op().type());
225  if(type.id()==ID_struct)
226  return member_offset_expr(
227  to_struct_type(type), member_expr.get_component_name(), ns);
228  else if(type.id()==ID_union)
229  return from_integer(0, size_type());
230  else
231  return {};
232 }
233 
235  const struct_typet &type,
236  const irep_idt &member,
237  const namespacet &ns)
238 {
239  PRECONDITION(size_type().get_width() != 0);
240  exprt result=from_integer(0, size_type());
241  std::size_t bit_field_bits=0;
242 
243  for(const auto &c : type.components())
244  {
245  if(c.get_name() == member)
246  break;
247 
248  if(c.type().id() == ID_c_bit_field)
249  {
250  std::size_t w = to_c_bit_field_type(c.type()).get_width();
251  bit_field_bits += w;
252  const std::size_t bytes = bit_field_bits / 8;
253  bit_field_bits %= 8;
254  if(bytes > 0)
255  result = plus_exprt(result, from_integer(bytes, result.type()));
256  }
257  else if(c.type().id() == ID_bool)
258  {
259  ++bit_field_bits;
260  const std::size_t bytes = bit_field_bits / 8;
261  bit_field_bits %= 8;
262  if(bytes > 0)
263  result = plus_exprt(result, from_integer(bytes, result.type()));
264  }
265  else
266  {
268  bit_field_bits == 0, "padding ensures offset at byte boundaries");
269  const typet &subtype = c.type();
270  auto sub_size = size_of_expr(subtype, ns);
271  if(!sub_size.has_value())
272  return {}; // give up
273  result = plus_exprt(result, sub_size.value());
274  }
275  }
276 
277  return simplify_expr(std::move(result), ns);
278 }
279 
281 {
282  if(type.id()==ID_array)
283  {
284  const auto &array_type = to_array_type(type);
285 
286  // special-case arrays of bits
287  if(array_type.element_type().id() == ID_bool)
288  {
289  auto bits = pointer_offset_bits(array_type, ns);
290 
291  if(bits.has_value())
292  return from_integer((*bits + 7) / 8, size_type());
293  }
294 
295  auto sub = size_of_expr(array_type.element_type(), ns);
296  if(!sub.has_value())
297  return {};
298 
299  const exprt &size = array_type.size();
300 
301  if(size.is_nil())
302  return {};
303 
304  const auto size_casted =
305  typecast_exprt::conditional_cast(size, sub.value().type());
306 
307  return simplify_expr(mult_exprt{size_casted, sub.value()}, ns);
308  }
309  else if(type.id()==ID_vector)
310  {
311  const auto &vector_type = to_vector_type(type);
312 
313  // special-case vectors of bits
314  if(vector_type.element_type().id() == ID_bool)
315  {
316  auto bits = pointer_offset_bits(vector_type, ns);
317 
318  if(bits.has_value())
319  return from_integer((*bits + 7) / 8, size_type());
320  }
321 
322  auto sub = size_of_expr(vector_type.element_type(), ns);
323  if(!sub.has_value())
324  return {};
325 
326  const exprt &size = to_vector_type(type).size();
327 
328  if(size.is_nil())
329  return {};
330 
331  const auto size_casted =
332  typecast_exprt::conditional_cast(size, sub.value().type());
333 
334  return simplify_expr(mult_exprt{size_casted, sub.value()}, ns);
335  }
336  else if(type.id()==ID_complex)
337  {
338  auto sub = size_of_expr(to_complex_type(type).subtype(), ns);
339  if(!sub.has_value())
340  return {};
341 
342  exprt size = from_integer(2, sub.value().type());
343  return simplify_expr(mult_exprt{std::move(size), sub.value()}, ns);
344  }
345  else if(type.id()==ID_struct)
346  {
347  const struct_typet &struct_type=to_struct_type(type);
348 
349  exprt result=from_integer(0, size_type());
350  std::size_t bit_field_bits=0;
351 
352  for(const auto &c : struct_type.components())
353  {
354  if(c.type().id() == ID_c_bit_field)
355  {
356  std::size_t w = to_c_bit_field_type(c.type()).get_width();
357  bit_field_bits += w;
358  const std::size_t bytes = bit_field_bits / 8;
359  bit_field_bits %= 8;
360  if(bytes > 0)
361  result = plus_exprt(result, from_integer(bytes, result.type()));
362  }
363  else if(c.type().id() == ID_bool)
364  {
365  ++bit_field_bits;
366  const std::size_t bytes = bit_field_bits / 8;
367  bit_field_bits %= 8;
368  if(bytes > 0)
369  result = plus_exprt(result, from_integer(bytes, result.type()));
370  }
371  else if(c.type().get_bool(ID_C_flexible_array_member))
372  {
373  // flexible array members do not change the sizeof result
374  continue;
375  }
376  else
377  {
379  bit_field_bits == 0, "padding ensures offset at byte boundaries");
380  const typet &subtype = c.type();
381  auto sub_size_opt = size_of_expr(subtype, ns);
382  if(!sub_size_opt.has_value())
383  return {};
384 
385  result = plus_exprt(result, sub_size_opt.value());
386  }
387  }
388 
389  return simplify_expr(std::move(result), ns);
390  }
391  else if(type.id()==ID_union)
392  {
393  const union_typet &union_type=to_union_type(type);
394 
395  mp_integer max_bytes=0;
396  exprt result=from_integer(0, size_type());
397 
398  // compute max
399 
400  for(const auto &c : union_type.components())
401  {
402  const typet &subtype = c.type();
403  exprt sub_size;
404 
405  auto sub_bits = pointer_offset_bits(subtype, ns);
406 
407  if(!sub_bits.has_value())
408  {
409  max_bytes=-1;
410 
411  auto sub_size_opt = size_of_expr(subtype, ns);
412  if(!sub_size_opt.has_value())
413  return {};
414  sub_size = sub_size_opt.value();
415  }
416  else
417  {
418  mp_integer sub_bytes = (*sub_bits + 7) / 8;
419 
420  if(max_bytes>=0)
421  {
422  if(max_bytes<sub_bytes)
423  {
424  max_bytes=sub_bytes;
425  result=from_integer(sub_bytes, size_type());
426  }
427 
428  continue;
429  }
430 
431  sub_size=from_integer(sub_bytes, size_type());
432  }
433 
434  result=if_exprt(
435  binary_relation_exprt(result, ID_lt, sub_size),
436  sub_size, result);
437 
438  simplify(result, ns);
439  }
440 
441  return result;
442  }
443  else if(type.id()==ID_signedbv ||
444  type.id()==ID_unsignedbv ||
445  type.id()==ID_fixedbv ||
446  type.id()==ID_floatbv ||
447  type.id()==ID_bv ||
448  type.id()==ID_c_bool ||
449  type.id()==ID_c_bit_field)
450  {
451  std::size_t width=to_bitvector_type(type).get_width();
452  std::size_t bytes=width/8;
453  if(bytes*8!=width)
454  bytes++;
455  return from_integer(bytes, size_type());
456  }
457  else if(type.id()==ID_c_enum)
458  {
459  std::size_t width =
460  to_bitvector_type(to_c_enum_type(type).underlying_type()).get_width();
461  std::size_t bytes=width/8;
462  if(bytes*8!=width)
463  bytes++;
464  return from_integer(bytes, size_type());
465  }
466  else if(type.id()==ID_c_enum_tag)
467  {
468  return size_of_expr(ns.follow_tag(to_c_enum_tag_type(type)), ns);
469  }
470  else if(type.id()==ID_bool)
471  {
472  return from_integer(1, size_type());
473  }
474  else if(type.id()==ID_pointer)
475  {
476  // the following is an MS extension
477  if(type.get_bool(ID_C_ptr32))
478  return from_integer(4, size_type());
479 
480  std::size_t width=to_bitvector_type(type).get_width();
481  std::size_t bytes=width/8;
482  if(bytes*8!=width)
483  bytes++;
484  return from_integer(bytes, size_type());
485  }
486  else if(type.id() == ID_union_tag)
487  {
488  return size_of_expr(ns.follow_tag(to_union_tag_type(type)), ns);
489  }
490  else if(type.id() == ID_struct_tag)
491  {
492  return size_of_expr(ns.follow_tag(to_struct_tag_type(type)), ns);
493  }
494  else if(type.id()==ID_code)
495  {
496  return from_integer(0, size_type());
497  }
498  else if(type.id()==ID_string)
499  {
500  return from_integer(32/8, size_type());
501  }
502  else
503  return {};
504 }
505 
507 compute_pointer_offset(const exprt &expr, const namespacet &ns)
508 {
509  if(expr.id()==ID_symbol)
510  {
511  if(is_ssa_expr(expr))
512  return compute_pointer_offset(
513  to_ssa_expr(expr).get_original_expr(), ns);
514  else
515  return mp_integer(0);
516  }
517  else if(expr.id()==ID_index)
518  {
519  const index_exprt &index_expr=to_index_expr(expr);
521  index_expr.array().type().id() == ID_array,
522  "index into array expected, found " +
523  index_expr.array().type().id_string());
524 
525  auto o = compute_pointer_offset(index_expr.array(), ns);
526 
527  if(o.has_value())
528  {
529  const auto &array_type = to_array_type(index_expr.array().type());
530  auto sub_size = pointer_offset_size(array_type.element_type(), ns);
531 
532  if(sub_size.has_value() && *sub_size > 0)
533  {
534  const auto i = numeric_cast<mp_integer>(index_expr.index());
535  if(i.has_value())
536  return (*o) + (*i) * (*sub_size);
537  }
538  }
539 
540  // don't know
541  }
542  else if(expr.id()==ID_member)
543  {
544  const member_exprt &member_expr=to_member_expr(expr);
545  const exprt &op=member_expr.struct_op();
546  const struct_union_typet &type=to_struct_union_type(ns.follow(op.type()));
547 
548  auto o = compute_pointer_offset(op, ns);
549 
550  if(o.has_value())
551  {
552  if(type.id()==ID_union)
553  return *o;
554 
556  to_struct_type(type), member_expr.get_component_name(), ns);
557 
558  if(member_offset.has_value())
559  return *o + *member_offset;
560  }
561  }
562  else if(expr.id()==ID_string_constant)
563  return mp_integer(0);
564 
565  return {}; // don't know
566 }
567 
569  const exprt &expr,
570  const mp_integer &offset_bytes,
571  const typet &target_type_raw,
572  const namespacet &ns)
573 {
574  if(offset_bytes == 0 && expr.type() == target_type_raw)
575  {
576  exprt result = expr;
577 
578  if(expr.type() != target_type_raw)
579  result.type() = target_type_raw;
580 
581  return result;
582  }
583 
584  if(
585  offset_bytes == 0 && expr.type().id() == ID_pointer &&
586  target_type_raw.id() == ID_pointer)
587  {
588  return typecast_exprt(expr, target_type_raw);
589  }
590 
591  const typet &source_type = ns.follow(expr.type());
592  const auto target_size_bits = pointer_offset_bits(target_type_raw, ns);
593  if(!target_size_bits.has_value())
594  return {};
595 
596  if(source_type.id()==ID_struct)
597  {
598  const struct_typet &struct_type = to_struct_type(source_type);
599 
600  mp_integer m_offset_bits = 0;
601  for(const auto &component : struct_type.components())
602  {
603  const auto m_size_bits = pointer_offset_bits(component.type(), ns);
604  if(!m_size_bits.has_value())
605  return {};
606 
607  // if this member completely contains the target, and this member is
608  // byte-aligned, recurse into it
609  if(
610  offset_bytes * 8 >= m_offset_bits && m_offset_bits % 8 == 0 &&
611  offset_bytes * 8 + *target_size_bits <= m_offset_bits + *m_size_bits)
612  {
613  const member_exprt member(expr, component.get_name(), component.type());
615  member, offset_bytes - m_offset_bits / 8, target_type_raw, ns);
616  }
617 
618  m_offset_bits += *m_size_bits;
619  }
620  }
621  else if(source_type.id()==ID_array)
622  {
623  const array_typet &array_type = to_array_type(source_type);
624 
625  const auto elem_size_bits =
626  pointer_offset_bits(array_type.element_type(), ns);
627 
628  // no arrays of non-byte-aligned, zero-, or unknown-sized objects
629  if(
630  elem_size_bits.has_value() && *elem_size_bits > 0 &&
631  *elem_size_bits % 8 == 0 && *target_size_bits <= *elem_size_bits)
632  {
633  const mp_integer elem_size_bytes = *elem_size_bits / 8;
634  const auto offset_inside_elem = offset_bytes % elem_size_bytes;
635  const auto target_size_bytes = *target_size_bits / 8;
636  // only recurse if the cell completely contains the target
637  if(offset_inside_elem + target_size_bytes <= elem_size_bytes)
638  {
640  index_exprt(
641  expr,
642  from_integer(
643  offset_bytes / elem_size_bytes, array_type.index_type())),
644  offset_inside_elem,
645  target_type_raw,
646  ns);
647  }
648  }
649  }
650  else if(
651  object_descriptor_exprt(expr).root_object().id() == ID_union &&
652  source_type.id() == ID_union)
653  {
654  const union_typet &union_type = to_union_type(source_type);
655 
656  for(const auto &component : union_type.components())
657  {
658  const auto m_size_bits = pointer_offset_bits(component.type(), ns);
659  if(!m_size_bits.has_value())
660  continue;
661 
662  // if this member completely contains the target, recurse into it
663  if(offset_bytes * 8 + *target_size_bits <= *m_size_bits)
664  {
665  const member_exprt member(expr, component.get_name(), component.type());
667  member, offset_bytes, target_type_raw, ns);
668  }
669  }
670  }
671 
672  return make_byte_extract(
673  expr, from_integer(offset_bytes, c_index_type()), target_type_raw);
674 }
675 
677  const exprt &expr,
678  const exprt &offset,
679  const typet &target_type,
680  const namespacet &ns)
681 {
682  const auto offset_bytes = numeric_cast<mp_integer>(offset);
683 
684  if(!offset_bytes.has_value())
685  return {};
686  else
687  return get_subexpression_at_offset(expr, *offset_bytes, target_type, ns);
688 }
to_union_tag_type
const union_tag_typet & to_union_tag_type(const typet &type)
Cast a typet to a union_tag_typet.
Definition: c_types.h:202
struct_union_typet::components
const componentst & components() const
Definition: std_types.h:147
dstringt
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:36
pointer_offset_size.h
to_union_type
const union_typet & to_union_type(const typet &type)
Cast a typet to a union_typet.
Definition: c_types.h:162
make_byte_extract
byte_extract_exprt make_byte_extract(const exprt &_op, const exprt &_offset, const typet &_type)
Construct a byte_extract_exprt with endianness and byte width matching the current configuration.
Definition: byte_operators.cpp:48
typecast_exprt::conditional_cast
static exprt conditional_cast(const exprt &expr, const typet &type)
Definition: std_expr.h:2025
mp_integer
BigInt mp_integer
Definition: smt_terms.h:17
arith_tools.h
to_struct_type
const struct_typet & to_struct_type(const typet &type)
Cast a typet to a struct_typet.
Definition: std_types.h:308
to_struct_union_type
const struct_union_typet & to_struct_union_type(const typet &type)
Cast a typet to a struct_union_typet.
Definition: std_types.h:214
member_offset_bits
optionalt< mp_integer > member_offset_bits(const struct_typet &type, const irep_idt &member, const namespacet &ns)
Definition: pointer_offset_size.cpp:65
typet
The type of an expression, extends irept.
Definition: type.h:28
union_typet::find_widest_union_component
optionalt< std::pair< struct_union_typet::componentt, mp_integer > > find_widest_union_component(const namespacet &ns) const
Determine the member of maximum bit width in a union type.
Definition: c_types.cpp:318
to_index_expr
const index_exprt & to_index_expr(const exprt &expr)
Cast an exprt to an index_exprt.
Definition: std_expr.h:1478
struct_union_typet
Base type for structs and unions.
Definition: std_types.h:61
vector_typet::size
const constant_exprt & size() const
Definition: std_types.cpp:269
if_exprt
The trinary if-then-else operator.
Definition: std_expr.h:2322
to_c_enum_type
const c_enum_typet & to_c_enum_type(const typet &type)
Cast a typet to a c_enum_typet.
Definition: c_types.h:302
object_descriptor_exprt
Split an expression into a base object and a (byte) offset.
Definition: pointer_expr.h:166
invariant.h
plus_exprt
The plus expression Associativity is not specified.
Definition: std_expr.h:946
exprt
Base class for all expressions.
Definition: expr.h:55
struct_union_typet::componentst
std::vector< componentt > componentst
Definition: std_types.h:140
namespace_baset::follow_tag
const union_typet & follow_tag(const union_tag_typet &) const
Follow type tag of union type.
Definition: namespace.cpp:63
component
auto component(T &struct_expr, const irep_idt &name, const namespacet &ns) -> decltype(struct_expr.op0())
Definition: std_expr.cpp:76
to_bitvector_type
const bitvector_typet & to_bitvector_type(const typet &type)
Cast a typet to a bitvector_typet.
Definition: bitvector_types.h:32
to_complex_type
const complex_typet & to_complex_type(const typet &type)
Cast a typet to a complex_typet.
Definition: std_types.h:1102
namespace.h
namespacet
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition: namespace.h:90
compute_pointer_offset
optionalt< mp_integer > compute_pointer_offset(const exprt &expr, const namespacet &ns)
Definition: pointer_offset_size.cpp:507
exprt::type
typet & type()
Return the type of the expression.
Definition: expr.h:84
byte_operators.h
Expression classes for byte-level operators.
is_ssa_expr
bool is_ssa_expr(const exprt &expr)
Definition: ssa_expr.h:125
DATA_INVARIANT
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
Definition: invariant.h:510
to_ssa_expr
const ssa_exprt & to_ssa_expr(const exprt &expr)
Cast a generic exprt to an ssa_exprt.
Definition: ssa_expr.h:145
to_c_enum_tag_type
const c_enum_tag_typet & to_c_enum_tag_type(const typet &type)
Cast a typet to a c_enum_tag_typet.
Definition: c_types.h:344
member_exprt::struct_op
const exprt & struct_op() const
Definition: std_expr.h:2832
PRECONDITION
#define PRECONDITION(CONDITION)
Definition: invariant.h:463
pointer_offset_bits
optionalt< mp_integer > pointer_offset_bits(const typet &type, const namespacet &ns)
Definition: pointer_offset_size.cpp:101
pointer_expr.h
irept::id_string
const std::string & id_string() const
Definition: irep.h:399
simplify
bool simplify(exprt &expr, const namespacet &ns)
Definition: simplify_expr.cpp:2926
mult_exprt
Binary multiplication Associativity is not specified.
Definition: std_expr.h:1051
simplify_expr
exprt simplify_expr(exprt src, const namespacet &ns)
Definition: simplify_expr.cpp:2931
index_exprt::index
exprt & index()
Definition: std_expr.h:1450
index_exprt::array
exprt & array()
Definition: std_expr.h:1440
irept::is_nil
bool is_nil() const
Definition: irep.h:376
irept::id
const irep_idt & id() const
Definition: irep.h:396
to_struct_tag_type
const struct_tag_typet & to_struct_tag_type(const typet &type)
Cast a typet to a struct_tag_typet.
Definition: std_types.h:474
union_typet
The union type.
Definition: c_types.h:124
optionalt
nonstd::optional< T > optionalt
Definition: optional.h:35
simplify_expr.h
bitvector_typet::get_width
std::size_t get_width() const
Definition: std_types.h:876
member_exprt
Extract member of struct or union.
Definition: std_expr.h:2793
to_c_bit_field_type
const c_bit_field_typet & to_c_bit_field_type(const typet &type)
Cast a typet to a c_bit_field_typet.
Definition: c_types.h:58
ssa_expr.h
struct_typet
Structure type, corresponds to C style structs.
Definition: std_types.h:230
pointer_offset_size
optionalt< mp_integer > pointer_offset_size(const typet &type, const namespacet &ns)
Compute the size of a type in bytes, rounding up to full bytes.
Definition: pointer_offset_size.cpp:90
array_typet
Arrays with given size.
Definition: std_types.h:762
namespace_baset::follow
const typet & follow(const typet &) const
Resolve type symbol to the type it points to.
Definition: namespace.cpp:49
from_integer
constant_exprt from_integer(const mp_integer &int_value, const typet &type)
Definition: arith_tools.cpp:100
get_subexpression_at_offset
optionalt< exprt > get_subexpression_at_offset(const exprt &expr, const mp_integer &offset_bytes, const typet &target_type_raw, const namespacet &ns)
Definition: pointer_offset_size.cpp:568
binary_relation_exprt
A base class for relations, i.e., binary predicates whose two operands have the same type.
Definition: std_expr.h:706
to_array_type
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
Definition: std_types.h:844
to_vector_type
const vector_typet & to_vector_type(const typet &type)
Cast a typet to a vector_typet.
Definition: std_types.h:1060
size_of_expr
optionalt< exprt > size_of_expr(const typet &type, const namespacet &ns)
Definition: pointer_offset_size.cpp:280
to_member_expr
const member_exprt & to_member_expr(const exprt &expr)
Cast an exprt to a member_exprt.
Definition: std_expr.h:2886
member_exprt::get_component_name
irep_idt get_component_name() const
Definition: std_expr.h:2816
index_exprt
Array index operator.
Definition: std_expr.h:1409
typecast_exprt
Semantic type conversion.
Definition: std_expr.h:2016
size_type
unsignedbv_typet size_type()
Definition: c_types.cpp:68
member_offset_expr
optionalt< exprt > member_offset_expr(const member_exprt &member_expr, const namespacet &ns)
Definition: pointer_offset_size.cpp:221
c_index_type
bitvector_typet c_index_type()
Definition: c_types.cpp:16
std_expr.h
array_typet::index_type
typet index_type() const
The type of the index expressions into any instance of this type.
Definition: std_types.cpp:33
member_offset
optionalt< mp_integer > member_offset(const struct_typet &type, const irep_idt &member, const namespacet &ns)
Definition: pointer_offset_size.cpp:24
c_types.h
irept::get_bool
bool get_bool(const irep_idt &name) const
Definition: irep.cpp:58
array_typet::element_type
const typet & element_type() const
The type of the elements of the array.
Definition: std_types.h:785