CBMC
format_expr.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Expression Pretty Printing
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
11 
12 #include "format_expr.h"
13 
14 #include "arith_tools.h"
15 #include "bitvector_expr.h"
16 #include "byte_operators.h"
17 #include "expr_util.h"
18 #include "floatbv_expr.h"
19 #include "format_type.h"
20 #include "ieee_float.h"
21 #include "mathematical_expr.h"
22 #include "mp_arith.h"
23 #include "pointer_expr.h"
24 #include "string_utils.h"
25 
26 #include <map>
27 #include <ostream>
28 
29 // expressions that are rendered with infix operators
30 struct infix_opt
31 {
32  const char *rep;
33 };
34 
35 const std::map<irep_idt, infix_opt> infix_map = {
36  {ID_plus, {"+"}},
37  {ID_minus, {"-"}},
38  {ID_mult, {"*"}},
39  {ID_div, {"/"}},
40  {ID_equal, {"="}},
41  {ID_notequal, {u8"\u2260"}}, // /=, U+2260
42  {ID_and, {u8"\u2227"}}, // wedge, U+2227
43  {ID_or, {u8"\u2228"}}, // vee, U+2228
44  {ID_xor, {u8"\u2295"}}, // + in circle, U+2295
45  {ID_implies, {u8"\u21d2"}}, // =>, U+21D2
46  {ID_le, {u8"\u2264"}}, // <=, U+2264
47  {ID_ge, {u8"\u2265"}}, // >=, U+2265
48  {ID_lt, {"<"}},
49  {ID_gt, {">"}},
50 };
51 
55 static bool bracket_subexpression(const exprt &sub_expr, const exprt &expr)
56 {
57  // no need for parentheses whenever the subexpression
58  // doesn't have operands
59  if(!sub_expr.has_operands())
60  return false;
61 
62  // no need if subexpression isn't an infix operator
63  if(infix_map.find(sub_expr.id()) == infix_map.end())
64  return false;
65 
66  // * and / bind stronger than + and -
67  if(
68  (sub_expr.id() == ID_mult || sub_expr.id() == ID_div) &&
69  (expr.id() == ID_plus || expr.id() == ID_minus))
70  return false;
71 
72  // ==, !=, <, <=, >, >= bind stronger than && and ||
73  if(
74  (sub_expr.id() == ID_equal || sub_expr.id() == ID_notequal ||
75  sub_expr.id() == ID_lt || sub_expr.id() == ID_gt ||
76  sub_expr.id() == ID_le || sub_expr.id() == ID_ge) &&
77  (expr.id() == ID_and || expr.id() == ID_or))
78  return false;
79 
80  // +, -, *, / bind stronger than ==, !=, <, <=, >, >=
81  if(
82  (sub_expr.id() == ID_plus || sub_expr.id() == ID_minus ||
83  sub_expr.id() == ID_mult || sub_expr.id() == ID_div) &&
84  (expr.id() == ID_equal || expr.id() == ID_notequal || expr.id() == ID_lt ||
85  expr.id() == ID_gt || expr.id() == ID_le || expr.id() == ID_ge))
86  {
87  return false;
88  }
89 
90  return true;
91 }
92 
95 static std::ostream &format_rec(std::ostream &os, const multi_ary_exprt &src)
96 {
97  bool first = true;
98 
99  std::string operator_str = id2string(src.id()); // default
100 
101  if(src.id() == ID_equal && to_equal_expr(src).op0().is_boolean())
102  {
103  operator_str = u8"\u21d4"; // <=>, U+21D4
104  }
105  else
106  {
107  auto infix_map_it = infix_map.find(src.id());
108  if(infix_map_it != infix_map.end())
109  operator_str = infix_map_it->second.rep;
110  }
111 
112  for(const auto &op : src.operands())
113  {
114  if(first)
115  first = false;
116  else
117  os << ' ' << operator_str << ' ';
118 
119  const bool need_parentheses = bracket_subexpression(op, src);
120 
121  if(need_parentheses)
122  os << '(';
123 
124  os << format(op);
125 
126  if(need_parentheses)
127  os << ')';
128  }
129 
130  return os;
131 }
132 
135 static std::ostream &format_rec(std::ostream &os, const binary_exprt &src)
136 {
137  return format_rec(os, to_multi_ary_expr(src));
138 }
139 
142 static std::ostream &format_rec(std::ostream &os, const unary_exprt &src)
143 {
144  if(src.id() == ID_not)
145  os << u8"\u00ac"; // neg, U+00AC
146  else if(src.id() == ID_unary_minus)
147  os << '-';
148  else if(src.id() == ID_count_leading_zeros)
149  os << "clz";
150  else if(src.id() == ID_count_trailing_zeros)
151  os << "ctz";
152  else if(src.id() == ID_find_first_set)
153  os << "ffs";
154  else
155  return os << src.pretty();
156 
157  if(src.op().has_operands())
158  return os << '(' << format(src.op()) << ')';
159  else
160  return os << format(src.op());
161 }
162 
164 static std::ostream &format_rec(std::ostream &os, const ternary_exprt &src)
165 {
166  os << src.id() << '(' << format(src.op0()) << ", " << format(src.op1())
167  << ", " << format(src.op2()) << ')';
168  return os;
169 }
170 
172 static std::ostream &format_rec(std::ostream &os, const constant_exprt &src)
173 {
174  auto type = src.type().id();
175 
176  if(type == ID_bool)
177  {
178  if(src.is_true())
179  return os << "true";
180  else if(src.is_false())
181  return os << "false";
182  else
183  return os << src.pretty();
184  }
185  else if(
186  type == ID_unsignedbv || type == ID_signedbv || type == ID_c_bool ||
187  type == ID_c_bit_field)
188  return os << *numeric_cast<mp_integer>(src);
189  else if(type == ID_bv)
190  {
191  // These do not have a numerical interpretation.
192  // We'll print the 0/1 bit pattern, starting with the bit
193  // that has the highest index.
194  auto width = to_bv_type(src.type()).get_width();
195  std::string result;
196  result.reserve(width);
197  auto &value = src.get_value();
198  for(std::size_t i = 0; i < width; i++)
199  result += get_bvrep_bit(value, width, width - i - 1) ? '1' : '0';
200  return os << result;
201  }
202  else if(type == ID_integer || type == ID_natural || type == ID_range)
203  return os << src.get_value();
204  else if(type == ID_string)
205  return os << '"' << escape(id2string(src.get_value())) << '"';
206  else if(type == ID_floatbv)
207  return os << ieee_floatt(src);
208  else if(type == ID_pointer)
209  {
210  if(src.is_null_pointer())
211  return os << ID_NULL;
212  else if(
213  src.get_value() == "INVALID" || src.get_value().starts_with("INVALID-"))
214  {
215  return os << "INVALID-POINTER";
216  }
217  else
218  {
219  const auto &pointer_type = to_pointer_type(src.type());
220  const auto width = pointer_type.get_width();
221  auto int_value = bvrep2integer(src.get_value(), width, false);
222  return os << "pointer(0x" << integer2string(int_value, 16) << ", "
223  << format(pointer_type.base_type()) << ')';
224  }
225  }
226  else if(type == ID_c_enum_tag)
227  {
228  return os << string2integer(id2string(src.get_value()), 16);
229  }
230  else
231  return os << src.pretty();
232 }
233 
234 std::ostream &fallback_format_rec(std::ostream &os, const exprt &expr)
235 {
236  os << expr.id();
237 
238  for(const auto &s : expr.get_named_sub())
239  if(s.first != ID_type && s.first != ID_C_source_location)
240  os << ' ' << s.first << "=\"" << s.second.id() << '"';
241 
242  if(expr.has_operands())
243  {
244  os << '(';
245  bool first = true;
246 
247  for(const auto &op : expr.operands())
248  {
249  if(first)
250  first = false;
251  else
252  os << ", ";
253 
254  os << format(op);
255  }
256 
257  os << ')';
258  }
259 
260  return os;
261 }
262 
264 {
265 public:
267  {
268  setup();
269  }
270 
271  using formattert =
272  std::function<std::ostream &(std::ostream &, const exprt &)>;
273  using expr_mapt = std::unordered_map<irep_idt, formattert>;
274 
276 
278  const formattert &find_formatter(const exprt &);
279 
280 private:
282  void setup();
283 
285 };
286 
287 // The below generates textual output in a generic syntax
288 // that is inspired by C/C++/Java, and is meant for debugging
289 // purposes.
291 {
292  auto multi_ary_expr =
293  [](std::ostream &os, const exprt &expr) -> std::ostream & {
294  return format_rec(os, to_multi_ary_expr(expr));
295  };
296 
297  expr_map[ID_plus] = multi_ary_expr;
298  expr_map[ID_mult] = multi_ary_expr;
299  expr_map[ID_and] = multi_ary_expr;
300  expr_map[ID_or] = multi_ary_expr;
301  expr_map[ID_xor] = multi_ary_expr;
302 
303  auto binary_infix_expr =
304  [](std::ostream &os, const exprt &expr) -> std::ostream & {
305  return format_rec(os, to_binary_expr(expr));
306  };
307 
308  expr_map[ID_lt] = binary_infix_expr;
309  expr_map[ID_gt] = binary_infix_expr;
310  expr_map[ID_ge] = binary_infix_expr;
311  expr_map[ID_le] = binary_infix_expr;
312  expr_map[ID_div] = binary_infix_expr;
313  expr_map[ID_minus] = binary_infix_expr;
314  expr_map[ID_implies] = binary_infix_expr;
315  expr_map[ID_equal] = binary_infix_expr;
316  expr_map[ID_notequal] = binary_infix_expr;
317 
318  auto binary_prefix_expr =
319  [](std::ostream &os, const exprt &expr) -> std::ostream & {
320  os << expr.id() << '(' << format(to_binary_expr(expr).op0()) << ", "
321  << format(to_binary_expr(expr).op1()) << ')';
322  return os;
323  };
324 
325  expr_map[ID_ieee_float_equal] = binary_prefix_expr;
326  expr_map[ID_ieee_float_notequal] = binary_prefix_expr;
327 
328  auto unary_expr = [](std::ostream &os, const exprt &expr) -> std::ostream & {
329  return format_rec(os, to_unary_expr(expr));
330  };
331 
332  expr_map[ID_not] = unary_expr;
333  expr_map[ID_unary_minus] = unary_expr;
334 
335  auto unary_with_parentheses_expr =
336  [](std::ostream &os, const exprt &expr) -> std::ostream & {
337  return os << expr.id() << '(' << format(to_unary_expr(expr).op()) << ')';
338  };
339 
340  expr_map[ID_isnan] = unary_with_parentheses_expr;
341  expr_map[ID_isinf] = unary_with_parentheses_expr;
342  expr_map[ID_isfinite] = unary_with_parentheses_expr;
343  expr_map[ID_isnormal] = unary_with_parentheses_expr;
344 
345  auto ternary_expr =
346  [](std::ostream &os, const exprt &expr) -> std::ostream & {
347  return format_rec(os, to_ternary_expr(expr));
348  };
349 
350  expr_map[ID_floatbv_plus] = ternary_expr;
351  expr_map[ID_floatbv_minus] = ternary_expr;
352  expr_map[ID_floatbv_mult] = ternary_expr;
353  expr_map[ID_floatbv_div] = ternary_expr;
354  expr_map[ID_floatbv_mod] = ternary_expr;
355 
356  expr_map[ID_constant] =
357  [](std::ostream &os, const exprt &expr) -> std::ostream & {
358  return format_rec(os, to_constant_expr(expr));
359  };
360 
361  expr_map[ID_address_of] =
362  [](std::ostream &os, const exprt &expr) -> std::ostream & {
363  const auto &address_of = to_address_of_expr(expr);
364  return os << "address_of(" << format(address_of.object()) << ')';
365  };
366 
367  expr_map[ID_annotated_pointer_constant] =
368  [](std::ostream &os, const exprt &expr) -> std::ostream & {
369  const auto &annotated_pointer = to_annotated_pointer_constant_expr(expr);
370  return os << format(annotated_pointer.symbolic_pointer());
371  };
372 
373  expr_map[ID_typecast] =
374  [](std::ostream &os, const exprt &expr) -> std::ostream & {
375  return os << "cast(" << format(to_typecast_expr(expr).op()) << ", "
376  << format(expr.type()) << ')';
377  };
378 
379  expr_map[ID_zero_extend] =
380  [](std::ostream &os, const exprt &expr) -> std::ostream & {
381  return os << "zero_extend(" << format(to_zero_extend_expr(expr).op())
382  << ", " << format(expr.type()) << ')';
383  };
384 
385  expr_map[ID_floatbv_typecast] =
386  [](std::ostream &os, const exprt &expr) -> std::ostream & {
387  const auto &floatbv_typecast_expr = to_floatbv_typecast_expr(expr);
388  return os << "floatbv_typecast(" << format(floatbv_typecast_expr.op())
389  << ", " << format(floatbv_typecast_expr.type()) << ", "
390  << format(floatbv_typecast_expr.rounding_mode()) << ')';
391  };
392 
393  auto byte_extract =
394  [](std::ostream &os, const exprt &expr) -> std::ostream & {
395  const auto &byte_extract_expr = to_byte_extract_expr(expr);
396  return os << expr.id() << '(' << format(byte_extract_expr.op()) << ", "
397  << format(byte_extract_expr.offset()) << ", "
398  << format(byte_extract_expr.type()) << ')';
399  };
400 
401  expr_map[ID_byte_extract_little_endian] = byte_extract;
402  expr_map[ID_byte_extract_big_endian] = byte_extract;
403 
404  auto byte_update = [](std::ostream &os, const exprt &expr) -> std::ostream & {
405  const auto &byte_update_expr = to_byte_update_expr(expr);
406  return os << expr.id() << '(' << format(byte_update_expr.op()) << ", "
407  << format(byte_update_expr.offset()) << ", "
408  << format(byte_update_expr.value()) << ", "
409  << format(byte_update_expr.type()) << ')';
410  };
411 
412  expr_map[ID_byte_update_little_endian] = byte_update;
413  expr_map[ID_byte_update_big_endian] = byte_update;
414 
415  expr_map[ID_member] =
416  [](std::ostream &os, const exprt &expr) -> std::ostream & {
417  return os << format(to_member_expr(expr).op()) << '.'
419  };
420 
421  expr_map[ID_symbol] =
422  [](std::ostream &os, const exprt &expr) -> std::ostream & {
423  return os << to_symbol_expr(expr).get_identifier();
424  };
425 
426  expr_map[ID_index] =
427  [](std::ostream &os, const exprt &expr) -> std::ostream & {
428  const auto &index_expr = to_index_expr(expr);
429  return os << format(index_expr.array()) << '[' << format(index_expr.index())
430  << ']';
431  };
432 
433  expr_map[ID_type] =
434  [](std::ostream &os, const exprt &expr) -> std::ostream & {
435  return format_rec(os, expr.type());
436  };
437 
438  expr_map[ID_forall] =
439  [](std::ostream &os, const exprt &expr) -> std::ostream & {
440  os << u8"\u2200 ";
441  bool first = true;
442  for(const auto &symbol : to_quantifier_expr(expr).variables())
443  {
444  if(first)
445  first = false;
446  else
447  os << ", ";
448  os << format(symbol) << " : " << format(symbol.type());
449  }
450  return os << " . " << format(to_quantifier_expr(expr).where());
451  };
452 
453  expr_map[ID_exists] =
454  [](std::ostream &os, const exprt &expr) -> std::ostream & {
455  os << u8"\u2203 ";
456  bool first = true;
457  for(const auto &symbol : to_quantifier_expr(expr).variables())
458  {
459  if(first)
460  first = false;
461  else
462  os << ", ";
463  os << format(symbol) << " : " << format(symbol.type());
464  }
465  return os << " . " << format(to_quantifier_expr(expr).where());
466  };
467 
468  expr_map[ID_let] = [](std::ostream &os, const exprt &expr) -> std::ostream & {
469  const auto &let_expr = to_let_expr(expr);
470 
471  os << "LET ";
472 
473  bool first = true;
474 
475  const auto &values = let_expr.values();
476  auto values_it = values.begin();
477  for(auto &v : let_expr.variables())
478  {
479  if(first)
480  first = false;
481  else
482  os << ", ";
483 
484  os << format(v) << " = " << format(*values_it);
485  ++values_it;
486  }
487 
488  return os << " IN " << format(let_expr.where());
489  };
490 
491  expr_map[ID_lambda] =
492  [](std::ostream &os, const exprt &expr) -> std::ostream & {
493  const auto &lambda_expr = to_lambda_expr(expr);
494 
495  os << u8"\u03bb ";
496 
497  bool first = true;
498 
499  for(auto &v : lambda_expr.variables())
500  {
501  if(first)
502  first = false;
503  else
504  os << ", ";
505 
506  os << format(v);
507  }
508 
509  return os << " . " << format(lambda_expr.where());
510  };
511 
512  auto compound = [](std::ostream &os, const exprt &expr) -> std::ostream & {
513  os << "{ ";
514 
515  bool first = true;
516 
517  for(const auto &op : expr.operands())
518  {
519  if(first)
520  first = false;
521  else
522  os << ", ";
523 
524  os << format(op);
525  }
526 
527  return os << " }";
528  };
529 
530  expr_map[ID_array] = compound;
531  expr_map[ID_struct] = compound;
532 
533  expr_map[ID_array_of] =
534  [](std::ostream &os, const exprt &expr) -> std::ostream & {
535  const auto &array_of_expr = to_array_of_expr(expr);
536  return os << "array_of(" << format(array_of_expr.what()) << ')';
537  };
538 
539  expr_map[ID_if] = [](std::ostream &os, const exprt &expr) -> std::ostream & {
540  const auto &if_expr = to_if_expr(expr);
541  return os << '(' << format(if_expr.cond()) << " ? "
542  << format(if_expr.true_case()) << " : "
543  << format(if_expr.false_case()) << ')';
544  };
545 
546  expr_map[ID_string_constant] =
547  [](std::ostream &os, const exprt &expr) -> std::ostream & {
548  return os << '"' << expr.get_string(ID_value) << '"';
549  };
550 
551  expr_map[ID_function_application] =
552  [](std::ostream &os, const exprt &expr) -> std::ostream & {
553  const auto &function_application_expr = to_function_application_expr(expr);
554  os << format(function_application_expr.function()) << '(';
555  bool first = true;
556  for(auto &argument : function_application_expr.arguments())
557  {
558  if(first)
559  first = false;
560  else
561  os << ", ";
562  os << format(argument);
563  }
564  os << ')';
565  return os;
566  };
567 
568  expr_map[ID_dereference] =
569  [](std::ostream &os, const exprt &expr) -> std::ostream & {
570  const auto &dereference_expr = to_dereference_expr(expr);
571  os << '*';
572  if(dereference_expr.pointer().id() != ID_symbol)
573  os << '(' << format(dereference_expr.pointer()) << ')';
574  else
575  os << format(dereference_expr.pointer());
576  return os;
577  };
578 
579  expr_map[ID_saturating_minus] =
580  [](std::ostream &os, const exprt &expr) -> std::ostream & {
581  const auto &saturating_minus = to_saturating_minus_expr(expr);
582  return os << "saturating-(" << format(saturating_minus.lhs()) << ", "
583  << format(saturating_minus.rhs()) << ')';
584  };
585 
586  expr_map[ID_saturating_plus] =
587  [](std::ostream &os, const exprt &expr) -> std::ostream & {
588  const auto &saturating_plus = to_saturating_plus_expr(expr);
589  return os << "saturating+(" << format(saturating_plus.lhs()) << ", "
590  << format(saturating_plus.rhs()) << ')';
591  };
592 
593  expr_map[ID_object_address] =
594  [](std::ostream &os, const exprt &expr) -> std::ostream & {
595  const auto &object_address_expr = to_object_address_expr(expr);
596  return os << u8"\u275d" << object_address_expr.object_identifier()
597  << u8"\u275e";
598  };
599 
600  expr_map[ID_object_size] =
601  [](std::ostream &os, const exprt &expr) -> std::ostream & {
602  const auto &object_size_expr = to_object_size_expr(expr);
603  return os << "object_size(" << format(object_size_expr.op()) << ')';
604  };
605 
606  expr_map[ID_pointer_offset] =
607  [](std::ostream &os, const exprt &expr) -> std::ostream & {
608  const auto &pointer_offset_expr = to_pointer_offset_expr(expr);
609  return os << "pointer_offset(" << format(pointer_offset_expr.op()) << ')';
610  };
611 
612  expr_map[ID_field_address] =
613  [](std::ostream &os, const exprt &expr) -> std::ostream & {
614  const auto &field_address_expr = to_field_address_expr(expr);
615  return os << format(field_address_expr.base()) << u8".\u275d"
616  << field_address_expr.component_name() << u8"\u275e";
617  };
618 
619  fallback = [](std::ostream &os, const exprt &expr) -> std::ostream & {
620  return fallback_format_rec(os, expr);
621  };
622 }
623 
626 {
627  auto m_it = expr_map.find(expr.id());
628  if(m_it == expr_map.end())
629  return fallback;
630  else
631  return m_it->second;
632 }
633 
635 
637 {
638  format_expr_config.expr_map[id] = std::move(formatter);
639 }
640 
641 std::ostream &format_rec(std::ostream &os, const exprt &expr)
642 {
643  auto &formatter = format_expr_config.find_formatter(expr);
644  return formatter(os, expr);
645 }
mp_integer bvrep2integer(const irep_idt &src, std::size_t width, bool is_signed)
convert a bit-vector representation (possibly signed) to integer
bool get_bvrep_bit(const irep_idt &src, std::size_t width, std::size_t bit_index)
Get a bit with given index from bit-vector representation.
API to expression classes for bitvectors.
const saturating_plus_exprt & to_saturating_plus_expr(const exprt &expr)
Cast an exprt to a saturating_plus_exprt.
const zero_extend_exprt & to_zero_extend_expr(const exprt &expr)
Cast an exprt to a zero_extend_exprt.
const saturating_minus_exprt & to_saturating_minus_expr(const exprt &expr)
Cast an exprt to a saturating_minus_exprt.
const bv_typet & to_bv_type(const typet &type)
Cast a typet to a bv_typet.
Expression classes for byte-level operators.
const byte_update_exprt & to_byte_update_expr(const exprt &expr)
const byte_extract_exprt & to_byte_extract_expr(const exprt &expr)
uint64_t u8
Definition: bytecode_info.h:58
pointer_typet pointer_type(const typet &subtype)
Definition: c_types.cpp:235
A base class for binary expressions.
Definition: std_expr.h:638
variablest & variables()
Definition: std_expr.h:3128
std::size_t get_width() const
Definition: std_types.h:925
A constant literal expression.
Definition: std_expr.h:2990
const irep_idt & get_value() const
Definition: std_expr.h:2998
bool is_null_pointer() const
Returns true if expr has a pointer type and a value NULL; it also returns true when expr has value ze...
Definition: std_expr.cpp:25
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:38
bool starts_with(const char *s) const
equivalent of as_string().starts_with(s)
Definition: dstring.h:95
Base class for all expressions.
Definition: expr.h:56
bool has_operands() const
Return true if there is at least one operand.
Definition: expr.h:91
bool is_true() const
Return whether the expression is a constant representing true.
Definition: expr.cpp:27
bool is_false() const
Return whether the expression is a constant representing false.
Definition: expr.cpp:34
typet & type()
Return the type of the expression.
Definition: expr.h:84
operandst & operands()
Definition: expr.h:94
std::function< std::ostream &(std::ostream &, const exprt &)> formattert
void setup()
setup the expressions we can format
std::unordered_map< irep_idt, formattert > expr_mapt
const formattert & find_formatter(const exprt &)
find the formatter for a given expression
std::string pretty(unsigned indent=0, unsigned max_indent=0) const
Definition: irep.cpp:482
named_subt & get_named_sub()
Definition: irep.h:450
const irep_idt & id() const
Definition: irep.h:388
irep_idt get_component_name() const
Definition: std_expr.h:2866
A base class for multi-ary expressions Associativity is not specified.
Definition: std_expr.h:912
const typet & base_type() const
The type of the data what we point to.
Definition: pointer_expr.h:35
const irep_idt & get_identifier() const
Definition: std_expr.h:160
An expression with three operands.
Definition: std_expr.h:67
exprt & op1()
Definition: expr.h:136
exprt & op2()
Definition: expr.h:139
exprt & op0()
Definition: expr.h:133
Generic base class for unary expressions.
Definition: std_expr.h:361
const exprt & op() const
Definition: std_expr.h:391
Deprecated expression utility functions.
API to expression classes for floating-point arithmetic.
const floatbv_typecast_exprt & to_floatbv_typecast_expr(const exprt &expr)
Cast an exprt to a floatbv_typecast_exprt.
Definition: floatbv_expr.h:68
static format_containert< T > format(const T &o)
Definition: format.h:37
static bool bracket_subexpression(const exprt &sub_expr, const exprt &expr)
We use the precendences that most readers expect (i.e., the ones you learn in primary school),...
Definition: format_expr.cpp:55
static std::ostream & format_rec(std::ostream &os, const multi_ary_exprt &src)
This formats a multi-ary expression, adding parentheses where indicated by bracket_subexpression.
Definition: format_expr.cpp:95
format_expr_configt format_expr_config
const std::map< irep_idt, infix_opt > infix_map
Definition: format_expr.cpp:35
void add_format_hook(irep_idt id, format_expr_configt::formattert formatter)
std::ostream & fallback_format_rec(std::ostream &os, const exprt &expr)
const std::string & id2string(const irep_idt &d)
Definition: irep.h:44
API to expression classes for 'mathematical' expressions.
const lambda_exprt & to_lambda_expr(const exprt &expr)
Cast an exprt to a lambda_exprt.
const function_application_exprt & to_function_application_expr(const exprt &expr)
Cast an exprt to a function_application_exprt.
const quantifier_exprt & to_quantifier_expr(const exprt &expr)
Cast an exprt to a quantifier_exprt.
const mp_integer string2integer(const std::string &n, unsigned base)
Definition: mp_arith.cpp:54
const std::string integer2string(const mp_integer &n, unsigned base)
Definition: mp_arith.cpp:103
API to expression classes for Pointers.
const object_size_exprt & to_object_size_expr(const exprt &expr)
Cast an exprt to a object_size_exprt.
const annotated_pointer_constant_exprt & to_annotated_pointer_constant_expr(const exprt &expr)
Cast an exprt to an annotated_pointer_constant_exprt.
const pointer_offset_exprt & to_pointer_offset_expr(const exprt &expr)
Cast an exprt to a pointer_offset_exprt.
const field_address_exprt & to_field_address_expr(const exprt &expr)
Cast an exprt to an field_address_exprt.
Definition: pointer_expr.h:727
const dereference_exprt & to_dereference_expr(const exprt &expr)
Cast an exprt to a dereference_exprt.
Definition: pointer_expr.h:890
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
Definition: pointer_expr.h:93
const object_address_exprt & to_object_address_expr(const exprt &expr)
Cast an exprt to an object_address_exprt.
Definition: pointer_expr.h:643
const address_of_exprt & to_address_of_expr(const exprt &expr)
Cast an exprt to an address_of_exprt.
Definition: pointer_expr.h:577
const if_exprt & to_if_expr(const exprt &expr)
Cast an exprt to an if_exprt.
Definition: std_expr.h:2450
const let_exprt & to_let_expr(const exprt &expr)
Cast an exprt to a let_exprt.
Definition: std_expr.h:3328
const constant_exprt & to_constant_expr(const exprt &expr)
Cast an exprt to a constant_exprt.
Definition: std_expr.h:3045
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
Definition: std_expr.h:272
const typecast_exprt & to_typecast_expr(const exprt &expr)
Cast an exprt to a typecast_exprt.
Definition: std_expr.h:2102
const multi_ary_exprt & to_multi_ary_expr(const exprt &expr)
Cast an exprt to a multi_ary_exprt.
Definition: std_expr.h:987
const binary_exprt & to_binary_expr(const exprt &expr)
Cast an exprt to a binary_exprt.
Definition: std_expr.h:715
const ternary_exprt & to_ternary_expr(const exprt &expr)
Cast an exprt to a ternary_exprt.
Definition: std_expr.h:116
const array_of_exprt & to_array_of_expr(const exprt &expr)
Cast an exprt to an array_of_exprt.
Definition: std_expr.h:1598
const equal_exprt & to_equal_expr(const exprt &expr)
Cast an exprt to an equal_exprt.
Definition: std_expr.h:1402
const member_exprt & to_member_expr(const exprt &expr)
Cast an exprt to a member_exprt.
Definition: std_expr.h:2936
const unary_exprt & to_unary_expr(const exprt &expr)
Cast an exprt to a unary_exprt.
Definition: std_expr.h:426
const index_exprt & to_index_expr(const exprt &expr)
Cast an exprt to an index_exprt.
Definition: std_expr.h:1533
std::string escape(const std::string &s)
Generic escaping of strings; this is not meant to be a particular programming language.
const char * rep
Definition: format_expr.cpp:32