CBMC
expr2c.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module:
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
9 #include "expr2c.h"
10 #include "expr2c_class.h"
11 
12 #include <util/arith_tools.h>
13 #include <util/c_types.h>
14 #include <util/config.h>
15 #include <util/cprover_prefix.h>
16 #include <util/expr_util.h>
17 #include <util/find_symbols.h>
18 #include <util/fixedbv.h>
19 #include <util/floatbv_expr.h>
20 #include <util/lispexpr.h>
21 #include <util/lispirep.h>
22 #include <util/namespace.h>
23 #include <util/pointer_expr.h>
25 #include <util/prefix.h>
26 #include <util/string_constant.h>
27 #include <util/string_utils.h>
28 #include <util/suffix.h>
29 #include <util/symbol.h>
30 
31 #include "c_misc.h"
32 #include "c_qualifiers.h"
33 
34 #include <algorithm>
35 #include <map>
36 #include <sstream>
37 
38 // clang-format off
39 
41 {
42  true,
43  true,
44  true,
45  "TRUE",
46  "FALSE",
47  true,
48  false,
49  false
50 };
51 
53 {
54  false,
55  false,
56  false,
57  "1",
58  "0",
59  false,
60  true,
61  true
62 };
63 
64 // clang-format on
65 /*
66 
67 Precedences are as follows. Higher values mean higher precedence.
68 
69 16 function call ()
70  ++ -- [] . ->
71 
72 1 comma
73 
74 */
75 
76 irep_idt expr2ct::id_shorthand(const irep_idt &identifier) const
77 {
78  const symbolt *symbol;
79 
80  if(!ns.lookup(identifier, symbol) &&
81  !symbol->base_name.empty() &&
82  has_suffix(id2string(identifier), id2string(symbol->base_name)))
83  return symbol->base_name;
84 
85  std::string sh=id2string(identifier);
86 
87  std::string::size_type pos=sh.rfind("::");
88  if(pos!=std::string::npos)
89  sh.erase(0, pos+2);
90 
91  return sh;
92 }
93 
94 static std::string clean_identifier(const irep_idt &id)
95 {
96  std::string dest=id2string(id);
97 
98  std::string::size_type c_pos=dest.find("::");
99  if(c_pos!=std::string::npos &&
100  dest.rfind("::")==c_pos)
101  dest.erase(0, c_pos+2);
102  else if(c_pos!=std::string::npos)
103  {
104  for(char &ch : dest)
105  if(ch == ':')
106  ch = '$';
107  else if(ch == '-')
108  ch = '_';
109  }
110 
111  // rewrite . as used in ELF section names
112  std::replace(dest.begin(), dest.end(), '.', '_');
113 
114  return dest;
115 }
116 
118 {
119  const std::unordered_set<irep_idt> symbols = find_symbol_identifiers(expr);
120 
121  // avoid renaming parameters, if possible
122  for(const auto &symbol_id : symbols)
123  {
124  const symbolt *symbol;
125  bool is_param = !ns.lookup(symbol_id, symbol) && symbol->is_parameter;
126 
127  if(!is_param)
128  continue;
129 
130  irep_idt sh = id_shorthand(symbol_id);
131 
132  std::string func = id2string(symbol_id);
133  func = func.substr(0, func.rfind("::"));
134 
135  // if there is a global symbol of the same name as the shorthand (even if
136  // not present in this particular expression) then there is a collision
137  const symbolt *global_symbol;
138  if(!ns.lookup(sh, global_symbol))
139  sh = func + "$$" + id2string(sh);
140 
141  ns_collision[func].insert(sh);
142 
143  if(!shorthands.insert(std::make_pair(symbol_id, sh)).second)
144  UNREACHABLE;
145  }
146 
147  for(const auto &symbol_id : symbols)
148  {
149  if(shorthands.find(symbol_id) != shorthands.end())
150  continue;
151 
152  irep_idt sh = id_shorthand(symbol_id);
153 
154  bool has_collision=
155  ns_collision[irep_idt()].find(sh)!=
156  ns_collision[irep_idt()].end();
157 
158  if(!has_collision)
159  {
160  // if there is a global symbol of the same name as the shorthand (even if
161  // not present in this particular expression) then there is a collision
162  const symbolt *symbol;
163  has_collision=!ns.lookup(sh, symbol);
164  }
165 
166  if(!has_collision)
167  {
168  irep_idt func;
169 
170  const symbolt *symbol;
171  // we use the source-level function name as a means to detect collisions,
172  // which is ok, because this is about generating user-visible output
173  if(!ns.lookup(symbol_id, symbol))
174  func=symbol->location.get_function();
175 
176  has_collision=!ns_collision[func].insert(sh).second;
177  }
178 
179  if(!has_collision)
180  {
181  // We could also conflict with a function argument, the code below
182  // finds the function we're in, and checks we don't conflict with
183  // any argument to the function
184  const std::string symbol_str = id2string(symbol_id);
185  const std::string func = symbol_str.substr(0, symbol_str.find("::"));
186  const symbolt *func_symbol;
187  if(!ns.lookup(func, func_symbol))
188  {
189  if(can_cast_type<code_typet>(func_symbol->type))
190  {
191  const auto func_type =
192  type_checked_cast<code_typet>(func_symbol->type);
193  const auto params = func_type.parameters();
194  for(const auto &param : params)
195  {
196  const auto param_id = param.get_identifier();
197  if(param_id != symbol_id && sh == id_shorthand(param_id))
198  {
199  has_collision = true;
200  break;
201  }
202  }
203  }
204  }
205  }
206 
207  if(has_collision)
208  sh = clean_identifier(symbol_id);
209 
210  shorthands.insert(std::make_pair(symbol_id, sh));
211  }
212 }
213 
214 std::string expr2ct::convert(const typet &src)
215 {
216  return convert_rec(src, c_qualifierst(), "");
217 }
218 
220  const typet &src,
221  const qualifierst &qualifiers,
222  const std::string &declarator)
223 {
224  std::unique_ptr<qualifierst> clone = qualifiers.clone();
225  c_qualifierst &new_qualifiers = dynamic_cast<c_qualifierst &>(*clone);
226  new_qualifiers.read(src);
227 
228  std::string q=new_qualifiers.as_string();
229 
230  std::string d = declarator.empty() ? declarator : " " + declarator;
231 
232  if(!configuration.expand_typedef && src.find(ID_C_typedef).is_not_nil())
233  {
234  return q+id2string(src.get(ID_C_typedef))+d;
235  }
236 
237  if(src.id()==ID_bool)
238  {
239  return q + CPROVER_PREFIX + "bool" + d;
240  }
241  else if(src.id()==ID_c_bool)
242  {
243  return q+"_Bool"+d;
244  }
245  else if(src.id()==ID_string)
246  {
247  return q + CPROVER_PREFIX + "string" + d;
248  }
249  else if(src.id()==ID_natural ||
250  src.id()==ID_integer ||
251  src.id()==ID_rational)
252  {
253  return q+src.id_string()+d;
254  }
255  else if(src.id()==ID_empty)
256  {
257  return q+"void"+d;
258  }
259  else if(src.id()==ID_complex)
260  {
261  // these take more or less arbitrary subtypes
262  return q + "_Complex " + convert(to_complex_type(src).subtype()) + d;
263  }
264  else if(src.id()==ID_floatbv)
265  {
266  std::size_t width=to_floatbv_type(src).get_width();
267 
268  if(width==config.ansi_c.single_width)
269  return q+"float"+d;
270  else if(width==config.ansi_c.double_width)
271  return q+"double"+d;
272  else if(width==config.ansi_c.long_double_width)
273  return q+"long double"+d;
274  else
275  {
276  std::string swidth = std::to_string(width);
277  std::string fwidth=src.get_string(ID_f);
278  return q + CPROVER_PREFIX + "floatbv[" + swidth + "][" + fwidth + "]";
279  }
280  }
281  else if(src.id()==ID_fixedbv)
282  {
283  const std::size_t width=to_fixedbv_type(src).get_width();
284 
285  const std::size_t fraction_bits=to_fixedbv_type(src).get_fraction_bits();
286  return q + CPROVER_PREFIX + "fixedbv[" + std::to_string(width) + "][" +
287  std::to_string(fraction_bits) + "]" + d;
288  }
289  else if(src.id()==ID_c_bit_field)
290  {
291  std::string width=std::to_string(to_c_bit_field_type(src).get_width());
292  return q + convert(to_c_bit_field_type(src).underlying_type()) + d + " : " +
293  width;
294  }
295  else if(src.id()==ID_signedbv ||
296  src.id()==ID_unsignedbv)
297  {
298  // annotated?
299  irep_idt c_type=src.get(ID_C_c_type);
300  const std::string c_type_str=c_type_as_string(c_type);
301 
302  if(c_type==ID_char &&
303  config.ansi_c.char_is_unsigned!=(src.id()==ID_unsignedbv))
304  {
305  if(src.id()==ID_signedbv)
306  return q+"signed char"+d;
307  else
308  return q+"unsigned char"+d;
309  }
310  else if(c_type!=ID_wchar_t && !c_type_str.empty())
311  return q+c_type_str+d;
312 
313  // There is also wchar_t among the above, but this isn't a C type.
314 
315  const std::size_t width = to_bitvector_type(src).get_width();
316 
317  bool is_signed=src.id()==ID_signedbv;
318  std::string sign_str=is_signed?"signed ":"unsigned ";
319 
320  if(width==config.ansi_c.int_width)
321  {
322  if(is_signed)
323  sign_str.clear();
324  return q+sign_str+"int"+d;
325  }
326  else if(width==config.ansi_c.long_int_width)
327  {
328  if(is_signed)
329  sign_str.clear();
330  return q+sign_str+"long int"+d;
331  }
332  else if(width==config.ansi_c.char_width)
333  {
334  // always include sign
335  return q+sign_str+"char"+d;
336  }
337  else if(width==config.ansi_c.short_int_width)
338  {
339  if(is_signed)
340  sign_str.clear();
341  return q+sign_str+"short int"+d;
342  }
343  else if(width==config.ansi_c.long_long_int_width)
344  {
345  if(is_signed)
346  sign_str.clear();
347  return q+sign_str+"long long int"+d;
348  }
349  else if(width==128)
350  {
351  if(is_signed)
352  sign_str.clear();
353  return q + sign_str + "__int128" + d;
354  }
355  else
356  {
357  return q + sign_str + CPROVER_PREFIX + "bitvector[" +
358  integer2string(width) + "]" + d;
359  }
360  }
361  else if(src.id()==ID_struct)
362  {
363  return convert_struct_type(src, q, d);
364  }
365  else if(src.id()==ID_union)
366  {
367  const union_typet &union_type=to_union_type(src);
368 
369  std::string dest=q+"union";
370 
371  const irep_idt &tag=union_type.get_tag();
372  if(!tag.empty())
373  dest+=" "+id2string(tag);
374 
375  if(!union_type.is_incomplete())
376  {
377  dest += " {";
378 
379  for(const auto &c : union_type.components())
380  {
381  dest += ' ';
382  dest += convert_rec(c.type(), c_qualifierst(), id2string(c.get_name()));
383  dest += ';';
384  }
385 
386  dest += " }";
387  }
388 
389  dest+=d;
390 
391  return dest;
392  }
393  else if(src.id()==ID_c_enum)
394  {
395  std::string result;
396  result+=q;
397  result+="enum";
398 
399  // do we have a tag?
400  const irept &tag=src.find(ID_tag);
401 
402  if(tag.is_nil())
403  {
404  }
405  else
406  {
407  result+=' ';
408  result+=tag.get_string(ID_C_base_name);
409  }
410 
411  result+=' ';
412 
413  if(!to_c_enum_type(src).is_incomplete())
414  {
415  const c_enum_typet &c_enum_type = to_c_enum_type(src);
416  const bool is_signed = c_enum_type.underlying_type().id() == ID_signedbv;
417  const auto width =
419 
420  result += '{';
421 
422  // add members
423  const c_enum_typet::memberst &members = c_enum_type.members();
424 
425  for(c_enum_typet::memberst::const_iterator it = members.begin();
426  it != members.end();
427  it++)
428  {
429  mp_integer int_value = bvrep2integer(it->get_value(), width, is_signed);
430 
431  if(it != members.begin())
432  result += ',';
433  result += ' ';
434  result += id2string(it->get_base_name());
435  result += '=';
436  result += integer2string(int_value);
437  }
438 
439  result += " }";
440  }
441 
442  result += d;
443  return result;
444  }
445  else if(src.id()==ID_c_enum_tag)
446  {
447  const c_enum_tag_typet &c_enum_tag_type=to_c_enum_tag_type(src);
448  const symbolt &symbol=ns.lookup(c_enum_tag_type);
449  std::string result=q+"enum";
450  result+=" "+id2string(symbol.base_name);
451  result+=d;
452  return result;
453  }
454  else if(src.id()==ID_pointer)
455  {
456  c_qualifierst sub_qualifiers;
457  const typet &base_type = to_pointer_type(src).base_type();
458  sub_qualifiers.read(base_type);
459 
460  // The star gets attached to the declarator.
461  std::string new_declarator="*";
462 
463  if(!q.empty() && (!declarator.empty() || base_type.id() == ID_pointer))
464  {
465  new_declarator+=" "+q;
466  }
467 
468  new_declarator+=declarator;
469 
470  // Depending on precedences, we may add parentheses.
471  if(
472  base_type.id() == ID_code ||
473  (sizeof_nesting == 0 && base_type.id() == ID_array))
474  {
475  new_declarator="("+new_declarator+")";
476  }
477 
478  return convert_rec(base_type, sub_qualifiers, new_declarator);
479  }
480  else if(src.id()==ID_array)
481  {
482  return convert_array_type(src, qualifiers, declarator);
483  }
484  else if(src.id()==ID_struct_tag)
485  {
486  const struct_tag_typet &struct_tag_type=
487  to_struct_tag_type(src);
488 
489  std::string dest=q+"struct";
490  const std::string &tag=ns.follow_tag(struct_tag_type).get_string(ID_tag);
491  if(!tag.empty())
492  dest+=" "+tag;
493  dest+=d;
494 
495  return dest;
496  }
497  else if(src.id()==ID_union_tag)
498  {
499  const union_tag_typet &union_tag_type=
500  to_union_tag_type(src);
501 
502  std::string dest=q+"union";
503  const std::string &tag=ns.follow_tag(union_tag_type).get_string(ID_tag);
504  if(!tag.empty())
505  dest+=" "+tag;
506  dest+=d;
507 
508  return dest;
509  }
510  else if(src.id()==ID_code)
511  {
512  const code_typet &code_type=to_code_type(src);
513 
514  // C doesn't really have syntax for function types,
515  // i.e., the following won't parse without declarator
516  std::string dest=declarator+"(";
517 
518  const code_typet::parameterst &parameters=code_type.parameters();
519 
520  if(parameters.empty())
521  {
522  if(!code_type.has_ellipsis())
523  dest+="void"; // means 'no parameters'
524  }
525  else
526  {
527  for(code_typet::parameterst::const_iterator
528  it=parameters.begin();
529  it!=parameters.end();
530  it++)
531  {
532  if(it!=parameters.begin())
533  dest+=", ";
534 
535  if(it->get_identifier().empty())
536  dest+=convert(it->type());
537  else
538  {
539  std::string arg_declarator=
540  convert(symbol_exprt(it->get_identifier(), it->type()));
541  dest+=convert_rec(it->type(), c_qualifierst(), arg_declarator);
542  }
543  }
544 
545  if(code_type.has_ellipsis())
546  dest+=", ...";
547  }
548 
549  dest+=')';
550 
551  c_qualifierst ret_qualifiers;
552  ret_qualifiers.read(code_type.return_type());
553  // _Noreturn should go with the return type
554  if(new_qualifiers.is_noreturn)
555  {
556  ret_qualifiers.is_noreturn=true;
557  new_qualifiers.is_noreturn=false;
558  q=new_qualifiers.as_string();
559  }
560 
561  const typet &return_type=code_type.return_type();
562 
563  // return type may be a function pointer or array
564  const typet *non_ptr_type = &return_type;
565  while(non_ptr_type->id()==ID_pointer)
566  non_ptr_type = &(to_pointer_type(*non_ptr_type).base_type());
567 
568  if(non_ptr_type->id()==ID_code ||
569  non_ptr_type->id()==ID_array)
570  dest=convert_rec(return_type, ret_qualifiers, dest);
571  else
572  dest=convert_rec(return_type, ret_qualifiers, "")+" "+dest;
573 
574  if(!q.empty())
575  {
576  dest+=" "+q;
577  // strip trailing space off q
578  if(dest[dest.size()-1]==' ')
579  dest.resize(dest.size()-1);
580  }
581 
582  return dest;
583  }
584  else if(src.id()==ID_vector)
585  {
586  const vector_typet &vector_type=to_vector_type(src);
587 
588  const mp_integer size_int = numeric_cast_v<mp_integer>(vector_type.size());
589  std::string dest="__gcc_v"+integer2string(size_int);
590 
591  std::string tmp = convert(vector_type.element_type());
592 
593  if(tmp=="signed char" || tmp=="char")
594  dest+="qi";
595  else if(tmp=="signed short int")
596  dest+="hi";
597  else if(tmp=="signed int")
598  dest+="si";
599  else if(tmp=="signed long long int")
600  dest+="di";
601  else if(tmp=="float")
602  dest+="sf";
603  else if(tmp=="double")
604  dest+="df";
605  else
606  {
607  const std::string subtype = convert(vector_type.element_type());
608  dest=subtype;
609  dest+=" __attribute__((vector_size (";
610  dest+=convert(vector_type.size());
611  dest+="*sizeof("+subtype+"))))";
612  }
613 
614  return q+dest+d;
615  }
616  else if(src.id()==ID_constructor ||
617  src.id()==ID_destructor)
618  {
619  return q+"__attribute__(("+id2string(src.id())+")) void"+d;
620  }
621 
622  {
623  lispexprt lisp;
624  irep2lisp(src, lisp);
625  std::string dest="irep(\""+MetaString(lisp.expr2string())+"\")";
626  dest+=d;
627 
628  return dest;
629  }
630 }
631 
639  const typet &src,
640  const std::string &qualifiers_str,
641  const std::string &declarator_str)
642 {
643  return convert_struct_type(
644  src,
645  qualifiers_str,
646  declarator_str,
649 }
650 
662  const typet &src,
663  const std::string &qualifiers,
664  const std::string &declarator,
665  bool inc_struct_body,
666  bool inc_padding_components)
667 {
668  // Either we are including the body (in which case it makes sense to include
669  // or exclude the parameters) or there is no body so therefore we definitely
670  // shouldn't be including the parameters
671  INVARIANT(
672  inc_struct_body || !inc_padding_components, "inconsistent configuration");
673 
674  const struct_typet &struct_type=to_struct_type(src);
675 
676  std::string dest=qualifiers+"struct";
677 
678  const irep_idt &tag=struct_type.get_tag();
679  if(!tag.empty())
680  dest+=" "+id2string(tag);
681 
682  if(inc_struct_body && !struct_type.is_incomplete())
683  {
684  dest+=" {";
685 
686  for(const auto &component : struct_type.components())
687  {
688  // Skip padding parameters unless we including them
689  if(component.get_is_padding() && !inc_padding_components)
690  {
691  continue;
692  }
693 
694  dest+=' ';
695  dest+=convert_rec(
696  component.type(),
697  c_qualifierst(),
698  id2string(component.get_name()));
699  dest+=';';
700  }
701 
702  dest+=" }";
703  }
704 
705  dest+=declarator;
706 
707  return dest;
708 }
709 
717  const typet &src,
718  const qualifierst &qualifiers,
719  const std::string &declarator_str)
720 {
721  return convert_array_type(
722  src, qualifiers, declarator_str, configuration.include_array_size);
723 }
724 
734  const typet &src,
735  const qualifierst &qualifiers,
736  const std::string &declarator_str,
737  bool inc_size_if_possible)
738 {
739  // The [...] gets attached to the declarator.
740  std::string array_suffix;
741 
742  if(to_array_type(src).size().is_nil() || !inc_size_if_possible)
743  array_suffix="[]";
744  else
745  array_suffix="["+convert(to_array_type(src).size())+"]";
746 
747  // This won't really parse without declarator.
748  // Note that qualifiers are passed down.
749  return convert_rec(
750  to_array_type(src).element_type(),
751  qualifiers,
752  declarator_str + array_suffix);
753 }
754 
756  const typecast_exprt &src,
757  unsigned &precedence)
758 {
759  if(src.operands().size()!=1)
760  return convert_norep(src, precedence);
761 
762  // some special cases
763 
764  const typet &to_type = src.type();
765  const typet &from_type = src.op().type();
766 
767  if(to_type.id()==ID_c_bool &&
768  from_type.id()==ID_bool)
769  return convert_with_precedence(src.op(), precedence);
770 
771  if(to_type.id()==ID_bool &&
772  from_type.id()==ID_c_bool)
773  return convert_with_precedence(src.op(), precedence);
774 
775  std::string dest = "(" + convert(to_type) + ")";
776 
777  unsigned p;
778  std::string tmp=convert_with_precedence(src.op(), p);
779 
780  if(precedence>p)
781  dest+='(';
782  dest+=tmp;
783  if(precedence>p)
784  dest+=')';
785 
786  return dest;
787 }
788 
790  const ternary_exprt &src,
791  const std::string &symbol1,
792  const std::string &symbol2,
793  unsigned precedence)
794 {
795  const exprt &op0=src.op0();
796  const exprt &op1=src.op1();
797  const exprt &op2=src.op2();
798 
799  unsigned p0, p1, p2;
800 
801  std::string s_op0=convert_with_precedence(op0, p0);
802  std::string s_op1=convert_with_precedence(op1, p1);
803  std::string s_op2=convert_with_precedence(op2, p2);
804 
805  std::string dest;
806 
807  if(precedence>=p0)
808  dest+='(';
809  dest+=s_op0;
810  if(precedence>=p0)
811  dest+=')';
812 
813  dest+=' ';
814  dest+=symbol1;
815  dest+=' ';
816 
817  if(precedence>=p1)
818  dest+='(';
819  dest+=s_op1;
820  if(precedence>=p1)
821  dest+=')';
822 
823  dest+=' ';
824  dest+=symbol2;
825  dest+=' ';
826 
827  if(precedence>=p2)
828  dest+='(';
829  dest+=s_op2;
830  if(precedence>=p2)
831  dest+=')';
832 
833  return dest;
834 }
835 
837  const binding_exprt &src,
838  const std::string &symbol,
839  unsigned precedence)
840 {
841  // our made-up syntax can only do one symbol
842  if(src.variables().size() != 1)
843  return convert_norep(src, precedence);
844 
845  unsigned p0, p1;
846 
847  std::string op0 = convert_with_precedence(src.variables().front(), p0);
848  std::string op1 = convert_with_precedence(src.where(), p1);
849 
850  std::string dest=symbol+" { ";
851  dest += convert(src.variables().front().type());
852  dest+=" "+op0+"; ";
853  dest+=op1;
854  dest+=" }";
855 
856  return dest;
857 }
858 
860  const exprt &src,
861  unsigned precedence)
862 {
863  if(src.operands().size()<3)
864  return convert_norep(src, precedence);
865 
866  unsigned p0;
867  const auto &old = to_with_expr(src).old();
868  std::string op0 = convert_with_precedence(old, p0);
869 
870  std::string dest;
871 
872  if(precedence>p0)
873  dest+='(';
874  dest+=op0;
875  if(precedence>p0)
876  dest+=')';
877 
878  dest+=" WITH [";
879 
880  for(size_t i=1; i<src.operands().size(); i+=2)
881  {
882  std::string op1, op2;
883  unsigned p1, p2;
884 
885  if(i!=1)
886  dest+=", ";
887 
888  if(src.operands()[i].id()==ID_member_name)
889  {
890  const irep_idt &component_name=
891  src.operands()[i].get(ID_component_name);
892 
893  const struct_union_typet::componentt &comp_expr =
894  (old.type().id() == ID_struct_tag || old.type().id() == ID_union_tag)
896  .get_component(component_name)
897  : to_struct_union_type(old.type()).get_component(component_name);
898  CHECK_RETURN(comp_expr.is_not_nil());
899 
900  irep_idt display_component_name;
901 
902  if(comp_expr.get_pretty_name().empty())
903  display_component_name=component_name;
904  else
905  display_component_name=comp_expr.get_pretty_name();
906 
907  op1="."+id2string(display_component_name);
908  p1=10;
909  }
910  else
911  op1=convert_with_precedence(src.operands()[i], p1);
912 
913  op2=convert_with_precedence(src.operands()[i+1], p2);
914 
915  dest+=op1;
916  dest+=":=";
917  dest+=op2;
918  }
919 
920  dest+=']';
921 
922  return dest;
923 }
924 
926  const let_exprt &src,
927  unsigned precedence)
928 {
929  std::string dest = "LET ";
930 
931  bool first = true;
932 
933  const auto &values = src.values();
934  auto values_it = values.begin();
935  for(auto &v : src.variables())
936  {
937  if(first)
938  first = false;
939  else
940  dest += ", ";
941 
942  dest += convert(v) + "=" + convert(*values_it);
943  ++values_it;
944  }
945 
946  dest += " IN " + convert(src.where());
947 
948  return dest;
949 }
950 
951 std::string
952 expr2ct::convert_update(const update_exprt &src, unsigned precedence)
953 {
954  std::string dest;
955 
956  dest+="UPDATE(";
957 
958  std::string op0, op1, op2;
959  unsigned p0, p2;
960 
961  op0 = convert_with_precedence(src.op0(), p0);
962  op2 = convert_with_precedence(src.op2(), p2);
963 
964  if(precedence>p0)
965  dest+='(';
966  dest+=op0;
967  if(precedence>p0)
968  dest+=')';
969 
970  dest+=", ";
971 
972  const exprt &designator = src.op1();
973 
974  for(const auto &op : designator.operands())
975  dest += convert(op);
976 
977  dest+=", ";
978 
979  if(precedence>p2)
980  dest+='(';
981  dest+=op2;
982  if(precedence>p2)
983  dest+=')';
984 
985  dest+=')';
986 
987  return dest;
988 }
989 
991  const exprt &src,
992  unsigned precedence)
993 {
994  if(src.operands().size()<2)
995  return convert_norep(src, precedence);
996 
997  bool condition=true;
998 
999  std::string dest="cond {\n";
1000 
1001  for(const auto &operand : src.operands())
1002  {
1003  unsigned p;
1004  std::string op = convert_with_precedence(operand, p);
1005 
1006  if(condition)
1007  dest+=" ";
1008 
1009  dest+=op;
1010 
1011  if(condition)
1012  dest+=": ";
1013  else
1014  dest+=";\n";
1015 
1016  condition=!condition;
1017  }
1018 
1019  dest+="} ";
1020 
1021  return dest;
1022 }
1023 
1025  const binary_exprt &src,
1026  const std::string &symbol,
1027  unsigned precedence,
1028  bool full_parentheses)
1029 {
1030  const exprt &op0 = src.op0();
1031  const exprt &op1 = src.op1();
1032 
1033  unsigned p0, p1;
1034 
1035  std::string s_op0=convert_with_precedence(op0, p0);
1036  std::string s_op1=convert_with_precedence(op1, p1);
1037 
1038  std::string dest;
1039 
1040  // In pointer arithmetic, x+(y-z) is unfortunately
1041  // not the same as (x+y)-z, even though + and -
1042  // have the same precedence. We thus add parentheses
1043  // for the case x+(y-z). Similarly, (x*y)/z is not
1044  // the same as x*(y/z), but * and / have the same
1045  // precedence.
1046 
1047  bool use_parentheses0=
1048  precedence>p0 ||
1049  (precedence==p0 && full_parentheses) ||
1050  (precedence==p0 && src.id()!=op0.id());
1051 
1052  if(use_parentheses0)
1053  dest+='(';
1054  dest+=s_op0;
1055  if(use_parentheses0)
1056  dest+=')';
1057 
1058  dest+=' ';
1059  dest+=symbol;
1060  dest+=' ';
1061 
1062  bool use_parentheses1=
1063  precedence>p1 ||
1064  (precedence==p1 && full_parentheses) ||
1065  (precedence==p1 && src.id()!=op1.id());
1066 
1067  if(use_parentheses1)
1068  dest+='(';
1069  dest+=s_op1;
1070  if(use_parentheses1)
1071  dest+=')';
1072 
1073  return dest;
1074 }
1075 
1077  const exprt &src,
1078  const std::string &symbol,
1079  unsigned precedence,
1080  bool full_parentheses)
1081 {
1082  if(src.operands().size()<2)
1083  return convert_norep(src, precedence);
1084 
1085  std::string dest;
1086  bool first=true;
1087 
1088  for(const auto &operand : src.operands())
1089  {
1090  if(first)
1091  first=false;
1092  else
1093  {
1094  if(symbol!=", ")
1095  dest+=' ';
1096  dest+=symbol;
1097  dest+=' ';
1098  }
1099 
1100  unsigned p;
1101  std::string op = convert_with_precedence(operand, p);
1102 
1103  // In pointer arithmetic, x+(y-z) is unfortunately
1104  // not the same as (x+y)-z, even though + and -
1105  // have the same precedence. We thus add parentheses
1106  // for the case x+(y-z). Similarly, (x*y)/z is not
1107  // the same as x*(y/z), but * and / have the same
1108  // precedence.
1109 
1110  bool use_parentheses = precedence > p ||
1111  (precedence == p && full_parentheses) ||
1112  (precedence == p && src.id() != operand.id());
1113 
1114  if(use_parentheses)
1115  dest+='(';
1116  dest+=op;
1117  if(use_parentheses)
1118  dest+=')';
1119  }
1120 
1121  return dest;
1122 }
1123 
1125  const unary_exprt &src,
1126  const std::string &symbol,
1127  unsigned precedence)
1128 {
1129  unsigned p;
1130  std::string op = convert_with_precedence(src.op(), p);
1131 
1132  std::string dest=symbol;
1133  if(precedence>=p ||
1134  (!symbol.empty() && has_prefix(op, symbol)))
1135  dest+='(';
1136  dest+=op;
1137  if(precedence>=p ||
1138  (!symbol.empty() && has_prefix(op, symbol)))
1139  dest+=')';
1140 
1141  return dest;
1142 }
1143 
1144 std::string expr2ct::convert_allocate(const exprt &src, unsigned &precedence)
1145 {
1146  if(src.operands().size() != 2)
1147  return convert_norep(src, precedence);
1148 
1149  unsigned p0;
1150  std::string op0 = convert_with_precedence(to_binary_expr(src).op0(), p0);
1151 
1152  unsigned p1;
1153  std::string op1 = convert_with_precedence(to_binary_expr(src).op1(), p1);
1154 
1155  std::string dest = "ALLOCATE";
1156  dest += '(';
1157 
1158  if(
1159  src.type().id() == ID_pointer &&
1160  to_pointer_type(src.type()).base_type().id() != ID_empty)
1161  {
1162  dest += convert(to_pointer_type(src.type()).base_type());
1163  dest+=", ";
1164  }
1165 
1166  dest += op0 + ", " + op1;
1167  dest += ')';
1168 
1169  return dest;
1170 }
1171 
1173  const exprt &src,
1174  unsigned &precedence)
1175 {
1176  if(!src.operands().empty())
1177  return convert_norep(src, precedence);
1178 
1179  return "NONDET("+convert(src.type())+")";
1180 }
1181 
1183  const exprt &src,
1184  unsigned &precedence)
1185 {
1186  if(
1187  src.operands().size() != 1 ||
1188  to_code(to_unary_expr(src).op()).get_statement() != ID_block)
1189  {
1190  return convert_norep(src, precedence);
1191  }
1192 
1193  return "(" +
1194  convert_code(to_code_block(to_code(to_unary_expr(src).op())), 0) + ")";
1195 }
1196 
1198  const exprt &src,
1199  unsigned &precedence)
1200 {
1201  if(src.operands().size()==1)
1202  return "COIN(" + convert(to_unary_expr(src).op()) + ")";
1203  else
1204  return convert_norep(src, precedence);
1205 }
1206 
1207 std::string expr2ct::convert_literal(const exprt &src)
1208 {
1209  return "L("+src.get_string(ID_literal)+")";
1210 }
1211 
1213  const exprt &src,
1214  unsigned &precedence)
1215 {
1216  if(src.operands().size()==1)
1217  return "PROB_UNIFORM(" + convert(src.type()) + "," +
1218  convert(to_unary_expr(src).op()) + ")";
1219  else
1220  return convert_norep(src, precedence);
1221 }
1222 
1223 std::string expr2ct::convert_function(const exprt &src, const std::string &name)
1224 {
1225  std::string dest=name;
1226  dest+='(';
1227 
1228  forall_operands(it, src)
1229  {
1230  unsigned p;
1231  std::string op=convert_with_precedence(*it, p);
1232 
1233  if(it!=src.operands().begin())
1234  dest+=", ";
1235 
1236  dest+=op;
1237  }
1238 
1239  dest+=')';
1240 
1241  return dest;
1242 }
1243 
1245  const exprt &src,
1246  unsigned precedence)
1247 {
1248  if(src.operands().size()!=2)
1249  return convert_norep(src, precedence);
1250 
1251  unsigned p0;
1252  std::string op0 = convert_with_precedence(to_binary_expr(src).op0(), p0);
1253  if(*op0.rbegin()==';')
1254  op0.resize(op0.size()-1);
1255 
1256  unsigned p1;
1257  std::string op1 = convert_with_precedence(to_binary_expr(src).op1(), p1);
1258  if(*op1.rbegin()==';')
1259  op1.resize(op1.size()-1);
1260 
1261  std::string dest=op0;
1262  dest+=", ";
1263  dest+=op1;
1264 
1265  return dest;
1266 }
1267 
1269  const exprt &src,
1270  unsigned precedence)
1271 {
1272  if(
1273  src.operands().size() == 2 && to_binary_expr(src).op0().is_zero() &&
1274  to_binary_expr(src).op1().is_constant())
1275  {
1276  // This is believed to be gcc only; check if this is sensible
1277  // in MSC mode.
1278  return convert_with_precedence(to_binary_expr(src).op1(), precedence) + "i";
1279  }
1280 
1281  // ISO C11 offers:
1282  // double complex CMPLX(double x, double y);
1283  // float complex CMPLXF(float x, float y);
1284  // long double complex CMPLXL(long double x, long double y);
1285 
1286  const typet &subtype = to_complex_type(src.type()).subtype();
1287 
1288  std::string name;
1289 
1290  if(subtype==double_type())
1291  name="CMPLX";
1292  else if(subtype==float_type())
1293  name="CMPLXF";
1294  else if(subtype==long_double_type())
1295  name="CMPLXL";
1296  else
1297  name="CMPLX"; // default, possibly wrong
1298 
1299  std::string dest=name;
1300  dest+='(';
1301 
1302  forall_operands(it, src)
1303  {
1304  unsigned p;
1305  std::string op=convert_with_precedence(*it, p);
1306 
1307  if(it!=src.operands().begin())
1308  dest+=", ";
1309 
1310  dest+=op;
1311  }
1312 
1313  dest+=')';
1314 
1315  return dest;
1316 }
1317 
1319  const exprt &src,
1320  unsigned precedence)
1321 {
1322  if(src.operands().size()!=1)
1323  return convert_norep(src, precedence);
1324 
1325  return "ARRAY_OF(" + convert(to_unary_expr(src).op()) + ')';
1326 }
1327 
1329  const byte_extract_exprt &src,
1330  unsigned precedence)
1331 {
1332  if(src.operands().size()!=2)
1333  return convert_norep(src, precedence);
1334 
1335  unsigned p0;
1336  std::string op0 = convert_with_precedence(src.op0(), p0);
1337 
1338  unsigned p1;
1339  std::string op1 = convert_with_precedence(src.op1(), p1);
1340 
1341  std::string dest=src.id_string();
1342  dest+='(';
1343  dest+=op0;
1344  dest+=", ";
1345  dest+=op1;
1346  dest+=", ";
1347  dest+=convert(src.type());
1348  dest+=')';
1349 
1350  return dest;
1351 }
1352 
1353 std::string
1354 expr2ct::convert_byte_update(const byte_update_exprt &src, unsigned precedence)
1355 {
1356  unsigned p0;
1357  std::string op0 = convert_with_precedence(src.op0(), p0);
1358 
1359  unsigned p1;
1360  std::string op1 = convert_with_precedence(src.op1(), p1);
1361 
1362  unsigned p2;
1363  std::string op2 = convert_with_precedence(src.op2(), p2);
1364 
1365  std::string dest=src.id_string();
1366  dest+='(';
1367  dest+=op0;
1368  dest+=", ";
1369  dest+=op1;
1370  dest+=", ";
1371  dest+=op2;
1372  dest+=", ";
1373  dest += convert(src.op2().type());
1374  dest+=')';
1375 
1376  return dest;
1377 }
1378 
1380  const exprt &src,
1381  const std::string &symbol,
1382  unsigned precedence)
1383 {
1384  if(src.operands().size()!=1)
1385  return convert_norep(src, precedence);
1386 
1387  unsigned p;
1388  std::string op = convert_with_precedence(to_unary_expr(src).op(), p);
1389 
1390  std::string dest;
1391  if(precedence>p)
1392  dest+='(';
1393  dest+=op;
1394  if(precedence>p)
1395  dest+=')';
1396  dest+=symbol;
1397 
1398  return dest;
1399 }
1400 
1401 std::string expr2ct::convert_index(const binary_exprt &src, unsigned precedence)
1402 {
1403  unsigned p;
1404  std::string op = convert_with_precedence(src.op0(), p);
1405 
1406  std::string dest;
1407  if(precedence>p)
1408  dest+='(';
1409  dest+=op;
1410  if(precedence>p)
1411  dest+=')';
1412 
1413  dest+='[';
1414  dest += convert(src.op1());
1415  dest+=']';
1416 
1417  return dest;
1418 }
1419 
1421  const exprt &src, unsigned &precedence)
1422 {
1423  if(src.operands().size()!=2)
1424  return convert_norep(src, precedence);
1425 
1426  std::string dest="POINTER_ARITHMETIC(";
1427 
1428  unsigned p;
1429  std::string op;
1430 
1431  op = convert(to_binary_expr(src).op0().type());
1432  dest+=op;
1433 
1434  dest+=", ";
1435 
1436  op = convert_with_precedence(to_binary_expr(src).op0(), p);
1437  if(precedence>p)
1438  dest+='(';
1439  dest+=op;
1440  if(precedence>p)
1441  dest+=')';
1442 
1443  dest+=", ";
1444 
1445  op = convert_with_precedence(to_binary_expr(src).op1(), p);
1446  if(precedence>p)
1447  dest+='(';
1448  dest+=op;
1449  if(precedence>p)
1450  dest+=')';
1451 
1452  dest+=')';
1453 
1454  return dest;
1455 }
1456 
1458  const exprt &src, unsigned &precedence)
1459 {
1460  if(src.operands().size()!=2)
1461  return convert_norep(src, precedence);
1462 
1463  const auto &binary_expr = to_binary_expr(src);
1464 
1465  std::string dest="POINTER_DIFFERENCE(";
1466 
1467  unsigned p;
1468  std::string op;
1469 
1470  op = convert(binary_expr.op0().type());
1471  dest+=op;
1472 
1473  dest+=", ";
1474 
1475  op = convert_with_precedence(binary_expr.op0(), p);
1476  if(precedence>p)
1477  dest+='(';
1478  dest+=op;
1479  if(precedence>p)
1480  dest+=')';
1481 
1482  dest+=", ";
1483 
1484  op = convert_with_precedence(binary_expr.op1(), p);
1485  if(precedence>p)
1486  dest+='(';
1487  dest+=op;
1488  if(precedence>p)
1489  dest+=')';
1490 
1491  dest+=')';
1492 
1493  return dest;
1494 }
1495 
1497 {
1498  unsigned precedence;
1499 
1500  if(!src.operands().empty())
1501  return convert_norep(src, precedence);
1502 
1503  return "."+src.get_string(ID_component_name);
1504 }
1505 
1507 {
1508  unsigned precedence;
1509 
1510  if(src.operands().size()!=1)
1511  return convert_norep(src, precedence);
1512 
1513  return "[" + convert(to_unary_expr(src).op()) + "]";
1514 }
1515 
1517  const member_exprt &src,
1518  unsigned precedence)
1519 {
1520  const auto &compound = src.compound();
1521 
1522  unsigned p;
1523  std::string dest;
1524 
1525  if(compound.id() == ID_dereference)
1526  {
1527  const auto &pointer = to_dereference_expr(compound).pointer();
1528 
1529  std::string op = convert_with_precedence(pointer, p);
1530 
1531  if(precedence > p || pointer.id() == ID_typecast)
1532  dest+='(';
1533  dest+=op;
1534  if(precedence > p || pointer.id() == ID_typecast)
1535  dest+=')';
1536 
1537  dest+="->";
1538  }
1539  else
1540  {
1541  std::string op = convert_with_precedence(compound, p);
1542 
1543  if(precedence > p || compound.id() == ID_typecast)
1544  dest+='(';
1545  dest+=op;
1546  if(precedence > p || compound.id() == ID_typecast)
1547  dest+=')';
1548 
1549  dest+='.';
1550  }
1551 
1552  if(
1553  compound.type().id() != ID_struct && compound.type().id() != ID_union &&
1554  compound.type().id() != ID_struct_tag &&
1555  compound.type().id() != ID_union_tag)
1556  {
1557  return convert_norep(src, precedence);
1558  }
1559 
1560  const struct_union_typet &struct_union_type =
1561  (compound.type().id() == ID_struct_tag ||
1562  compound.type().id() == ID_union_tag)
1563  ? ns.follow_tag(to_struct_or_union_tag_type(compound.type()))
1564  : to_struct_union_type(compound.type());
1565 
1566  irep_idt component_name=src.get_component_name();
1567 
1568  if(!component_name.empty())
1569  {
1570  const auto &comp_expr = struct_union_type.get_component(component_name);
1571 
1572  if(comp_expr.is_nil())
1573  return convert_norep(src, precedence);
1574 
1575  if(!comp_expr.get_pretty_name().empty())
1576  dest += id2string(comp_expr.get_pretty_name());
1577  else
1578  dest+=id2string(component_name);
1579 
1580  return dest;
1581  }
1582 
1583  std::size_t n=src.get_component_number();
1584 
1585  if(n>=struct_union_type.components().size())
1586  return convert_norep(src, precedence);
1587 
1588  const auto &comp_expr = struct_union_type.components()[n];
1589 
1590  if(!comp_expr.get_pretty_name().empty())
1591  dest += id2string(comp_expr.get_pretty_name());
1592  else
1593  dest += id2string(comp_expr.get_name());
1594 
1595  return dest;
1596 }
1597 
1599  const exprt &src,
1600  unsigned precedence)
1601 {
1602  if(src.operands().size()!=1)
1603  return convert_norep(src, precedence);
1604 
1605  return "[]=" + convert(to_unary_expr(src).op());
1606 }
1607 
1609  const exprt &src,
1610  unsigned precedence)
1611 {
1612  if(src.operands().size()!=1)
1613  return convert_norep(src, precedence);
1614 
1615  return "." + src.get_string(ID_name) + "=" + convert(to_unary_expr(src).op());
1616 }
1617 
1619  const exprt &src,
1620  unsigned &precedence)
1621 {
1622  lispexprt lisp;
1623  irep2lisp(src, lisp);
1624  std::string dest="irep(\""+MetaString(lisp.expr2string())+"\")";
1625  precedence=16;
1626  return dest;
1627 }
1628 
1629 std::string expr2ct::convert_symbol(const exprt &src)
1630 {
1631  const irep_idt &id=src.get(ID_identifier);
1632  std::string dest;
1633 
1634  if(
1635  src.operands().size() == 1 &&
1636  to_unary_expr(src).op().id() == ID_predicate_passive_symbol)
1637  {
1638  dest = to_unary_expr(src).op().get_string(ID_identifier);
1639  }
1640  else
1641  {
1642  std::unordered_map<irep_idt, irep_idt>::const_iterator entry =
1643  shorthands.find(id);
1644  // we might be called from conversion of a type
1645  if(entry==shorthands.end())
1646  {
1647  get_shorthands(src);
1648 
1649  entry=shorthands.find(id);
1650  CHECK_RETURN(entry != shorthands.end());
1651  }
1652 
1653  dest=id2string(entry->second);
1654 
1655  #if 0
1656  if(id.starts_with(SYMEX_DYNAMIC_PREFIX "::dynamic_object"))
1657  {
1658  if(sizeof_nesting++ == 0)
1659  dest+=" /*"+convert(src.type());
1660  if(--sizeof_nesting == 0)
1661  dest+="*/";
1662  }
1663  #endif
1664  }
1665 
1666  return dest;
1667 }
1668 
1670 {
1671  const irep_idt id=src.get_identifier();
1672  return "nondet_symbol<" + convert(src.type()) + ">(" + id2string(id) + ")";
1673 }
1674 
1676 {
1677  const std::string &id=src.get_string(ID_identifier);
1678  return "ps("+id+")";
1679 }
1680 
1682 {
1683  const std::string &id=src.get_string(ID_identifier);
1684  return "pns("+id+")";
1685 }
1686 
1688 {
1689  const std::string &id=src.get_string(ID_identifier);
1690  return "pps("+id+")";
1691 }
1692 
1694 {
1695  const std::string &id=src.get_string(ID_identifier);
1696  return id;
1697 }
1698 
1700 {
1701  return "nondet_bool()";
1702 }
1703 
1705  const exprt &src,
1706  unsigned &precedence)
1707 {
1708  if(src.operands().size()!=2)
1709  return convert_norep(src, precedence);
1710 
1711  std::string result="<";
1712 
1713  result += convert(to_binary_expr(src).op0());
1714  result+=", ";
1715  result += convert(to_binary_expr(src).op1());
1716  result+=", ";
1717 
1718  if(src.type().is_nil())
1719  result+='?';
1720  else
1721  result+=convert(src.type());
1722 
1723  result+='>';
1724 
1725  return result;
1726 }
1727 
1728 static std::optional<exprt>
1730 {
1731  const typet &type = static_cast<const typet &>(expr.find(ID_C_c_sizeof_type));
1732 
1733  if(type.is_nil())
1734  return {};
1735 
1736  const auto type_size_expr = size_of_expr(type, ns);
1737  std::optional<mp_integer> type_size;
1738  if(type_size_expr.has_value())
1739  type_size = numeric_cast<mp_integer>(*type_size_expr);
1740  auto val = numeric_cast<mp_integer>(expr);
1741 
1742  if(
1743  !type_size.has_value() || *type_size < 0 || !val.has_value() ||
1744  *val < *type_size || (*type_size == 0 && *val > 0))
1745  {
1746  return {};
1747  }
1748 
1749  const unsignedbv_typet t(size_type());
1751  address_bits(*val + 1) <= t.get_width(),
1752  "sizeof value does not fit size_type");
1753 
1754  mp_integer remainder = 0;
1755 
1756  if(*type_size != 0)
1757  {
1758  remainder = *val % *type_size;
1759  *val -= remainder;
1760  *val /= *type_size;
1761  }
1762 
1763  exprt result(ID_sizeof, t);
1764  result.set(ID_type_arg, type);
1765 
1766  if(*val > 1)
1767  result = mult_exprt(result, from_integer(*val, t));
1768  if(remainder > 0)
1769  result = plus_exprt(result, from_integer(remainder, t));
1770 
1771  return typecast_exprt::conditional_cast(result, expr.type());
1772 }
1773 
1775  const constant_exprt &src,
1776  unsigned &precedence)
1777 {
1778  const irep_idt &base=src.get(ID_C_base);
1779  const typet &type = src.type();
1780  const irep_idt value=src.get_value();
1781  std::string dest;
1782 
1783  if(type.id()==ID_integer ||
1784  type.id()==ID_natural ||
1785  type.id()==ID_rational)
1786  {
1787  dest=id2string(value);
1788  }
1789  else if(type.id()==ID_c_enum ||
1790  type.id()==ID_c_enum_tag)
1791  {
1792  c_enum_typet c_enum_type = type.id() == ID_c_enum
1793  ? to_c_enum_type(type)
1794  : ns.follow_tag(to_c_enum_tag_type(type));
1795 
1796  if(c_enum_type.id()!=ID_c_enum)
1797  return convert_norep(src, precedence);
1798 
1800  {
1801  const c_enum_typet::memberst &members =
1802  to_c_enum_type(c_enum_type).members();
1803 
1804  for(const auto &member : members)
1805  {
1806  if(member.get_value() == value)
1807  return "/*enum*/" + id2string(member.get_base_name());
1808  }
1809  }
1810 
1811  // lookup failed or enum is to be output as integer
1812  const bool is_signed = c_enum_type.underlying_type().id() == ID_signedbv;
1813  const auto width =
1814  to_bitvector_type(c_enum_type.underlying_type()).get_width();
1815 
1816  std::string value_as_string =
1817  integer2string(bvrep2integer(value, width, is_signed));
1818 
1820  return value_as_string;
1821  else
1822  return "/*enum*/" + value_as_string;
1823  }
1824  else if(type.id()==ID_rational)
1825  return convert_norep(src, precedence);
1826  else if(type.id()==ID_bv)
1827  {
1828  // not C
1829  dest=id2string(value);
1830  }
1831  else if(type.id()==ID_bool)
1832  {
1833  dest=convert_constant_bool(src.is_true());
1834  }
1835  else if(type.id()==ID_unsignedbv ||
1836  type.id()==ID_signedbv ||
1837  type.id()==ID_c_bit_field ||
1838  type.id()==ID_c_bool)
1839  {
1840  const auto width = to_bitvector_type(type).get_width();
1841 
1842  mp_integer int_value = bvrep2integer(
1843  value,
1844  width,
1845  type.id() == ID_signedbv ||
1846  (type.id() == ID_c_bit_field &&
1847  to_c_bit_field_type(type).underlying_type().id() == ID_signedbv));
1848 
1849  const irep_idt &c_type =
1850  type.id() == ID_c_bit_field
1851  ? to_c_bit_field_type(type).underlying_type().get(ID_C_c_type)
1852  : type.get(ID_C_c_type);
1853 
1854  if(type.id()==ID_c_bool)
1855  {
1856  dest=convert_constant_bool(int_value!=0);
1857  }
1858  else if(type==char_type() &&
1859  type!=signed_int_type() &&
1860  type!=unsigned_int_type())
1861  {
1862  if(int_value=='\n')
1863  dest+="'\\n'";
1864  else if(int_value=='\r')
1865  dest+="'\\r'";
1866  else if(int_value=='\t')
1867  dest+="'\\t'";
1868  else if(int_value=='\'')
1869  dest+="'\\''";
1870  else if(int_value=='\\')
1871  dest+="'\\\\'";
1872  else if(int_value>=' ' && int_value<126)
1873  {
1874  dest+='\'';
1875  dest += numeric_cast_v<char>(int_value);
1876  dest+='\'';
1877  }
1878  else
1879  dest=integer2string(int_value);
1880  }
1881  else
1882  {
1883  if(base=="16")
1884  dest="0x"+integer2string(int_value, 16);
1885  else if(base=="8")
1886  dest="0"+integer2string(int_value, 8);
1887  else if(base=="2")
1888  dest="0b"+integer2string(int_value, 2);
1889  else
1890  dest=integer2string(int_value);
1891 
1892  if(c_type==ID_unsigned_int)
1893  dest+='u';
1894  else if(c_type==ID_unsigned_long_int)
1895  dest+="ul";
1896  else if(c_type==ID_signed_long_int)
1897  dest+='l';
1898  else if(c_type==ID_unsigned_long_long_int)
1899  dest+="ull";
1900  else if(c_type==ID_signed_long_long_int)
1901  dest+="ll";
1902 
1903  if(sizeof_nesting == 0)
1904  {
1905  const auto sizeof_expr_opt = build_sizeof_expr(src, ns);
1906 
1907  if(sizeof_expr_opt.has_value())
1908  {
1909  ++sizeof_nesting;
1910  dest = convert(sizeof_expr_opt.value()) + " /*" + dest + "*/ ";
1911  --sizeof_nesting;
1912  }
1913  }
1914  }
1915  }
1916  else if(type.id()==ID_floatbv)
1917  {
1919 
1920  if(!dest.empty() && isdigit(dest[dest.size() - 1]))
1921  {
1922  if(dest.find('.')==std::string::npos)
1923  dest+=".0";
1924 
1925  // ANSI-C: double is default; float/long-double require annotation
1926  if(src.type()==float_type())
1927  dest+='f';
1928  else if(src.type()==long_double_type() &&
1930  dest+='l';
1931  }
1932  else if(dest.size()==4 &&
1933  (dest[0]=='+' || dest[0]=='-'))
1934  {
1936  {
1937  if(dest == "+inf")
1938  dest = "+INFINITY";
1939  else if(dest == "-inf")
1940  dest = "-INFINITY";
1941  else if(dest == "+NaN")
1942  dest = "+NAN";
1943  else if(dest == "-NaN")
1944  dest = "-NAN";
1945  }
1946  else
1947  {
1948  // ANSI-C: double is default; float/long-double require annotation
1949  std::string suffix = "";
1950  if(src.type() == float_type())
1951  suffix = "f";
1952  else if(
1953  src.type() == long_double_type() &&
1955  {
1956  suffix = "l";
1957  }
1958 
1959  if(dest == "+inf")
1960  dest = "(1.0" + suffix + "/0.0" + suffix + ")";
1961  else if(dest == "-inf")
1962  dest = "(-1.0" + suffix + "/0.0" + suffix + ")";
1963  else if(dest == "+NaN")
1964  dest = "(0.0" + suffix + "/0.0" + suffix + ")";
1965  else if(dest == "-NaN")
1966  dest = "(-0.0" + suffix + "/0.0" + suffix + ")";
1967  }
1968  }
1969  }
1970  else if(type.id()==ID_fixedbv)
1971  {
1973 
1974  if(!dest.empty() && isdigit(dest[dest.size() - 1]))
1975  {
1976  if(src.type()==float_type())
1977  dest+='f';
1978  else if(src.type()==long_double_type())
1979  dest+='l';
1980  }
1981  }
1982  else if(type.id() == ID_array)
1983  {
1984  dest = convert_array(src);
1985  }
1986  else if(type.id()==ID_pointer)
1987  {
1988  if(is_null_pointer(src))
1989  {
1991  dest = "NULL";
1992  else
1993  dest = "0";
1994  if(to_pointer_type(type).base_type().id() != ID_empty)
1995  dest="(("+convert(type)+")"+dest+")";
1996  }
1997  else if(
1998  value == "INVALID" || value.starts_with("INVALID-") ||
1999  value == "NULL+offset")
2000  {
2001  dest = id2string(value);
2002  }
2003  else
2004  {
2005  const auto width = to_pointer_type(type).get_width();
2006  mp_integer int_value = bvrep2integer(value, width, false);
2007  return "(" + convert(type) + ")" + integer2string(int_value);
2008  }
2009  }
2010  else if(type.id()==ID_string)
2011  {
2012  return '"'+id2string(src.get_value())+'"';
2013  }
2014  else
2015  return convert_norep(src, precedence);
2016 
2017  return dest;
2018 }
2019 
2022  unsigned &precedence)
2023 {
2024  const auto &annotation = src.symbolic_pointer();
2025 
2026  return convert_with_precedence(annotation, precedence);
2027 }
2028 
2033 std::string expr2ct::convert_constant_bool(bool boolean_value)
2034 {
2035  if(boolean_value)
2036  return configuration.true_string;
2037  else
2038  return configuration.false_string;
2039 }
2040 
2042  const exprt &src,
2043  unsigned &precedence)
2044 {
2045  return convert_struct(
2047 }
2048 
2058  const exprt &src,
2059  unsigned &precedence,
2060  bool include_padding_components)
2061 {
2062  if(src.type().id() != ID_struct && src.type().id() != ID_struct_tag)
2063  return convert_norep(src, precedence);
2064 
2065  const struct_typet &struct_type =
2066  src.type().id() == ID_struct_tag
2068  : to_struct_type(src.type());
2069 
2070  const struct_typet::componentst &components=
2071  struct_type.components();
2072 
2073  if(components.size()!=src.operands().size())
2074  return convert_norep(src, precedence);
2075 
2076  std::string dest="{ ";
2077 
2078  exprt::operandst::const_iterator o_it=src.operands().begin();
2079 
2080  bool first=true;
2081  bool newline=false;
2082  size_t last_size=0;
2083 
2084  for(const auto &component : struct_type.components())
2085  {
2087  o_it->type().id() != ID_code, "struct member must not be of code type");
2088 
2089  if(component.get_is_padding() && !include_padding_components)
2090  {
2091  ++o_it;
2092  continue;
2093  }
2094 
2095  if(first)
2096  first=false;
2097  else
2098  {
2099  dest+=',';
2100 
2101  if(newline)
2102  dest+="\n ";
2103  else
2104  dest+=' ';
2105  }
2106 
2107  std::string tmp=convert(*o_it);
2108 
2109  if(last_size+40<dest.size())
2110  {
2111  newline=true;
2112  last_size=dest.size();
2113  }
2114  else
2115  newline=false;
2116 
2117  dest+='.';
2118  dest+=component.get_string(ID_name);
2119  dest+='=';
2120  dest+=tmp;
2121 
2122  o_it++;
2123  }
2124 
2125  dest+=" }";
2126 
2127  return dest;
2128 }
2129 
2131  const exprt &src,
2132  unsigned &precedence)
2133 {
2134  const typet &type = src.type();
2135 
2136  if(type.id() != ID_vector)
2137  return convert_norep(src, precedence);
2138 
2139  std::string dest="{ ";
2140 
2141  bool first=true;
2142  bool newline=false;
2143  size_t last_size=0;
2144 
2145  for(const auto &op : src.operands())
2146  {
2147  if(first)
2148  first=false;
2149  else
2150  {
2151  dest+=',';
2152 
2153  if(newline)
2154  dest+="\n ";
2155  else
2156  dest+=' ';
2157  }
2158 
2159  std::string tmp = convert(op);
2160 
2161  if(last_size+40<dest.size())
2162  {
2163  newline=true;
2164  last_size=dest.size();
2165  }
2166  else
2167  newline=false;
2168 
2169  dest+=tmp;
2170  }
2171 
2172  dest+=" }";
2173 
2174  return dest;
2175 }
2176 
2178  const exprt &src,
2179  unsigned &precedence)
2180 {
2181  std::string dest="{ ";
2182 
2183  if(src.operands().size()!=1)
2184  return convert_norep(src, precedence);
2185 
2186  dest+='.';
2187  dest+=src.get_string(ID_component_name);
2188  dest+='=';
2189  dest += convert(to_union_expr(src).op());
2190 
2191  dest+=" }";
2192 
2193  return dest;
2194 }
2195 
2196 std::string expr2ct::convert_array(const exprt &src)
2197 {
2198  std::string dest;
2199 
2200  // we treat arrays of characters as string constants,
2201  // and arrays of wchar_t as wide strings
2202 
2203  const typet &element_type = to_array_type(src.type()).element_type();
2204 
2205  bool all_constant=true;
2206 
2207  for(const auto &op : src.operands())
2208  {
2209  if(!op.is_constant())
2210  all_constant=false;
2211  }
2212 
2213  if(
2214  src.get_bool(ID_C_string_constant) && all_constant &&
2215  (element_type == char_type() || element_type == wchar_t_type()))
2216  {
2217  bool wide = element_type == wchar_t_type();
2218 
2219  if(wide)
2220  dest+='L';
2221 
2222  dest+="\"";
2223 
2224  dest.reserve(dest.size()+1+src.operands().size());
2225 
2226  bool last_was_hex=false;
2227 
2228  forall_operands(it, src)
2229  {
2230  // these have a trailing zero
2231  if(it==--src.operands().end())
2232  break;
2233 
2234  const unsigned int ch = numeric_cast_v<unsigned>(to_constant_expr(*it));
2235 
2236  if(last_was_hex)
2237  {
2238  // we use "string splicing" to avoid ambiguity
2239  if(isxdigit(ch))
2240  dest+="\" \"";
2241 
2242  last_was_hex=false;
2243  }
2244 
2245  switch(ch)
2246  {
2247  case '\n': dest+="\\n"; break; /* NL (0x0a) */
2248  case '\t': dest+="\\t"; break; /* HT (0x09) */
2249  case '\v': dest+="\\v"; break; /* VT (0x0b) */
2250  case '\b': dest+="\\b"; break; /* BS (0x08) */
2251  case '\r': dest+="\\r"; break; /* CR (0x0d) */
2252  case '\f': dest+="\\f"; break; /* FF (0x0c) */
2253  case '\a': dest+="\\a"; break; /* BEL (0x07) */
2254  case '\\': dest+="\\\\"; break;
2255  case '"': dest+="\\\""; break;
2256 
2257  default:
2258  if(ch>=' ' && ch!=127 && ch<0xff)
2259  dest+=static_cast<char>(ch);
2260  else
2261  {
2262  std::ostringstream oss;
2263  oss << "\\x" << std::hex << ch;
2264  dest += oss.str();
2265  last_was_hex=true;
2266  }
2267  }
2268  }
2269 
2270  dest+="\"";
2271 
2272  return dest;
2273  }
2274 
2275  dest="{ ";
2276 
2277  forall_operands(it, src)
2278  {
2279  std::string tmp;
2280 
2281  if(it->is_not_nil())
2282  tmp=convert(*it);
2283 
2284  if((it+1)!=src.operands().end())
2285  {
2286  tmp+=", ";
2287  if(tmp.size()>40)
2288  tmp+="\n ";
2289  }
2290 
2291  dest+=tmp;
2292  }
2293 
2294  dest+=" }";
2295 
2296  return dest;
2297 }
2298 
2300  const exprt &src,
2301  unsigned &precedence)
2302 {
2303  std::string dest="{ ";
2304 
2305  if((src.operands().size()%2)!=0)
2306  return convert_norep(src, precedence);
2307 
2308  forall_operands(it, src)
2309  {
2310  std::string tmp1=convert(*it);
2311 
2312  it++;
2313 
2314  std::string tmp2=convert(*it);
2315 
2316  std::string tmp="["+tmp1+"]="+tmp2;
2317 
2318  if((it+1)!=src.operands().end())
2319  {
2320  tmp+=", ";
2321  if(tmp.size()>40)
2322  tmp+="\n ";
2323  }
2324 
2325  dest+=tmp;
2326  }
2327 
2328  dest+=" }";
2329 
2330  return dest;
2331 }
2332 
2334 {
2335  std::string dest;
2336  if(src.id()!=ID_compound_literal)
2337  dest+="{ ";
2338 
2339  forall_operands(it, src)
2340  {
2341  std::string tmp=convert(*it);
2342 
2343  if((it+1)!=src.operands().end())
2344  {
2345  tmp+=", ";
2346  if(tmp.size()>40)
2347  tmp+="\n ";
2348  }
2349 
2350  dest+=tmp;
2351  }
2352 
2353  if(src.id()!=ID_compound_literal)
2354  dest+=" }";
2355 
2356  return dest;
2357 }
2358 
2359 std::string expr2ct::convert_rox(const shift_exprt &src, unsigned precedence)
2360 {
2361  // AAAA rox n == (AAAA lhs_op n % width(AAAA))
2362  // | (AAAA rhs_op (width(AAAA) - n % width(AAAA)))
2363  // Where lhs_op and rhs_op depend on whether it is rol or ror
2364  // Get AAAA and if it's signed wrap it in a cast to remove
2365  // the sign since this messes with C shifts
2366  exprt op0 = src.op();
2367  size_t type_width;
2369  {
2370  // Set the type width
2371  type_width = to_signedbv_type(op0.type()).get_width();
2372  // Shifts in C are arithmetic and care about sign, by forcing
2373  // a cast to unsigned we force the shifts to perform rol/r
2374  op0 = typecast_exprt(op0, unsignedbv_typet(type_width));
2375  }
2376  else if(can_cast_type<unsignedbv_typet>(op0.type()))
2377  {
2378  // Set the type width
2379  type_width = to_unsignedbv_type(op0.type()).get_width();
2380  }
2381  else
2382  {
2383  UNREACHABLE;
2384  }
2385  // Construct the "width(AAAA)" constant
2386  const exprt width_expr = from_integer(type_width, src.distance().type());
2387  // Apply modulo to n since shifting will overflow
2388  // That is: 0001 << 4 == 0, but 0001 rol 4 == 0001
2389  const exprt distance_modulo_width = mod_exprt(src.distance(), width_expr);
2390  // Now put the pieces together
2391  // width(AAAA) - (n % width(AAAA))
2392  const auto complement_width_expr =
2393  minus_exprt(width_expr, distance_modulo_width);
2394  // lhs and rhs components defined according to rol/ror
2395  exprt lhs_expr;
2396  exprt rhs_expr;
2397  if(src.id() == ID_rol)
2398  {
2399  // AAAA << (n % width(AAAA))
2400  lhs_expr = shl_exprt(op0, distance_modulo_width);
2401  // AAAA >> complement_width_expr
2402  rhs_expr = ashr_exprt(op0, complement_width_expr);
2403  }
2404  else if(src.id() == ID_ror)
2405  {
2406  // AAAA >> (n % width(AAAA))
2407  lhs_expr = ashr_exprt(op0, distance_modulo_width);
2408  // AAAA << complement_width_expr
2409  rhs_expr = shl_exprt(op0, complement_width_expr);
2410  }
2411  else
2412  {
2413  // Someone called this function when they shouldn't have.
2414  UNREACHABLE;
2415  }
2416  return convert_with_precedence(bitor_exprt(lhs_expr, rhs_expr), precedence);
2417 }
2418 
2420 {
2421  if(src.operands().size()!=1)
2422  {
2423  unsigned precedence;
2424  return convert_norep(src, precedence);
2425  }
2426 
2427  const exprt &value = to_unary_expr(src).op();
2428 
2429  const exprt &designator = static_cast<const exprt &>(src.find(ID_designator));
2430  if(designator.operands().size() != 1)
2431  {
2432  unsigned precedence;
2433  return convert_norep(src, precedence);
2434  }
2435 
2436  const exprt &designator_id = to_unary_expr(designator).op();
2437 
2438  std::string dest;
2439 
2440  if(designator_id.id() == ID_member)
2441  {
2442  dest = "." + id2string(designator_id.get(ID_component_name));
2443  }
2444  else if(
2445  designator_id.id() == ID_index && designator_id.operands().size() == 1)
2446  {
2447  dest = "[" + convert(to_unary_expr(designator_id).op()) + "]";
2448  }
2449  else
2450  {
2451  unsigned precedence;
2452  return convert_norep(src, precedence);
2453  }
2454 
2455  dest+='=';
2456  dest += convert(value);
2457 
2458  return dest;
2459 }
2460 
2461 std::string
2463 {
2464  std::string dest;
2465 
2466  {
2467  unsigned p;
2468  std::string function_str=convert_with_precedence(src.function(), p);
2469  dest+=function_str;
2470  }
2471 
2472  dest+='(';
2473 
2474  forall_expr(it, src.arguments())
2475  {
2476  unsigned p;
2477  std::string arg_str=convert_with_precedence(*it, p);
2478 
2479  if(it!=src.arguments().begin())
2480  dest+=", ";
2481  // TODO: ggf. Klammern je nach p
2482  dest+=arg_str;
2483  }
2484 
2485  dest+=')';
2486 
2487  return dest;
2488 }
2489 
2492 {
2493  std::string dest;
2494 
2495  {
2496  unsigned p;
2497  std::string function_str=convert_with_precedence(src.function(), p);
2498  dest+=function_str;
2499  }
2500 
2501  dest+='(';
2502 
2503  forall_expr(it, src.arguments())
2504  {
2505  unsigned p;
2506  std::string arg_str=convert_with_precedence(*it, p);
2507 
2508  if(it!=src.arguments().begin())
2509  dest+=", ";
2510  // TODO: ggf. Klammern je nach p
2511  dest+=arg_str;
2512  }
2513 
2514  dest+=')';
2515 
2516  return dest;
2517 }
2518 
2520  const exprt &src,
2521  unsigned &precedence)
2522 {
2523  precedence=16;
2524 
2525  std::string dest="overflow(\"";
2526  dest+=src.id().c_str()+9;
2527  dest+="\"";
2528 
2529  if(!src.operands().empty())
2530  {
2531  dest+=", ";
2532  dest += convert(to_multi_ary_expr(src).op0().type());
2533  }
2534 
2535  for(const auto &op : src.operands())
2536  {
2537  unsigned p;
2538  std::string arg_str = convert_with_precedence(op, p);
2539 
2540  dest+=", ";
2541  // TODO: ggf. Klammern je nach p
2542  dest+=arg_str;
2543  }
2544 
2545  dest+=')';
2546 
2547  return dest;
2548 }
2549 
2550 std::string expr2ct::indent_str(unsigned indent)
2551 {
2552  return std::string(indent, ' ');
2553 }
2554 
2556  const code_asmt &src,
2557  unsigned indent)
2558 {
2559  std::string dest=indent_str(indent);
2560 
2561  if(src.get_flavor()==ID_gcc)
2562  {
2563  if(src.operands().size()==5)
2564  {
2565  dest+="asm(";
2566  dest+=convert(src.op0());
2567  if(!src.operands()[1].operands().empty() ||
2568  !src.operands()[2].operands().empty() ||
2569  !src.operands()[3].operands().empty() ||
2570  !src.operands()[4].operands().empty())
2571  {
2572  // need extended syntax
2573 
2574  // outputs
2575  dest+=" : ";
2576  forall_operands(it, src.op1())
2577  {
2578  if(it->operands().size()==2)
2579  {
2580  if(it!=src.op1().operands().begin())
2581  dest+=", ";
2582  dest += convert(to_binary_expr(*it).op0());
2583  dest+="(";
2584  dest += convert(to_binary_expr(*it).op1());
2585  dest+=")";
2586  }
2587  }
2588 
2589  // inputs
2590  dest+=" : ";
2591  forall_operands(it, src.op2())
2592  {
2593  if(it->operands().size()==2)
2594  {
2595  if(it!=src.op2().operands().begin())
2596  dest+=", ";
2597  dest += convert(to_binary_expr(*it).op0());
2598  dest+="(";
2599  dest += convert(to_binary_expr(*it).op1());
2600  dest+=")";
2601  }
2602  }
2603 
2604  // clobbered registers
2605  dest+=" : ";
2606  forall_operands(it, src.op3())
2607  {
2608  if(it!=src.op3().operands().begin())
2609  dest+=", ";
2610  if(it->id()==ID_gcc_asm_clobbered_register)
2611  dest += convert(to_unary_expr(*it).op());
2612  else
2613  dest+=convert(*it);
2614  }
2615  }
2616  dest+=");";
2617  }
2618  }
2619  else if(src.get_flavor()==ID_msc)
2620  {
2621  if(src.operands().size()==1)
2622  {
2623  dest+="__asm {\n";
2624  dest+=indent_str(indent);
2625  dest+=convert(src.op0());
2626  dest+="\n}";
2627  }
2628  }
2629 
2630  return dest;
2631 }
2632 
2634  const code_whilet &src,
2635  unsigned indent)
2636 {
2637  if(src.operands().size()!=2)
2638  {
2639  unsigned precedence;
2640  return convert_norep(src, precedence);
2641  }
2642 
2643  std::string dest=indent_str(indent);
2644  dest+="while("+convert(src.cond());
2645 
2646  if(src.body().is_nil())
2647  dest+=");";
2648  else
2649  {
2650  dest+=")\n";
2651  dest+=convert_code(
2652  src.body(),
2653  src.body().get_statement()==ID_block ? indent : indent+2);
2654  }
2655 
2656  return dest;
2657 }
2658 
2660  const code_dowhilet &src,
2661  unsigned indent)
2662 {
2663  if(src.operands().size()!=2)
2664  {
2665  unsigned precedence;
2666  return convert_norep(src, precedence);
2667  }
2668 
2669  std::string dest=indent_str(indent);
2670 
2671  if(src.body().is_nil())
2672  dest+="do;";
2673  else
2674  {
2675  dest+="do\n";
2676  dest+=convert_code(
2677  src.body(),
2678  src.body().get_statement()==ID_block ? indent : indent+2);
2679  dest+="\n";
2680  dest+=indent_str(indent);
2681  }
2682 
2683  dest+="while("+convert(src.cond())+");";
2684 
2685  return dest;
2686 }
2687 
2689  const code_ifthenelset &src,
2690  unsigned indent)
2691 {
2692  if(src.operands().size()!=3)
2693  {
2694  unsigned precedence;
2695  return convert_norep(src, precedence);
2696  }
2697 
2698  std::string dest=indent_str(indent);
2699  dest+="if("+convert(src.cond())+")\n";
2700 
2701  if(src.then_case().is_nil())
2702  {
2703  dest+=indent_str(indent+2);
2704  dest+=';';
2705  }
2706  else
2707  dest += convert_code(
2708  src.then_case(),
2709  src.then_case().get_statement() == ID_block ? indent : indent + 2);
2710  dest+="\n";
2711 
2712  if(!src.else_case().is_nil())
2713  {
2714  dest+="\n";
2715  dest+=indent_str(indent);
2716  dest+="else\n";
2717  dest += convert_code(
2718  src.else_case(),
2719  src.else_case().get_statement() == ID_block ? indent : indent + 2);
2720  }
2721 
2722  return dest;
2723 }
2724 
2726  const codet &src,
2727  unsigned indent)
2728 {
2729  if(src.operands().size() != 1)
2730  {
2731  unsigned precedence;
2732  return convert_norep(src, precedence);
2733  }
2734 
2735  std::string dest=indent_str(indent);
2736  dest+="return";
2737 
2738  if(to_code_frontend_return(src).has_return_value())
2739  dest+=" "+convert(src.op0());
2740 
2741  dest+=';';
2742 
2743  return dest;
2744 }
2745 
2747  const codet &src,
2748  unsigned indent)
2749 {
2750  std:: string dest=indent_str(indent);
2751  dest+="goto ";
2752  dest+=clean_identifier(src.get(ID_destination));
2753  dest+=';';
2754 
2755  return dest;
2756 }
2757 
2758 std::string expr2ct::convert_code_break(unsigned indent)
2759 {
2760  std::string dest=indent_str(indent);
2761  dest+="break";
2762  dest+=';';
2763 
2764  return dest;
2765 }
2766 
2768  const codet &src,
2769  unsigned indent)
2770 {
2771  if(src.operands().empty())
2772  {
2773  unsigned precedence;
2774  return convert_norep(src, precedence);
2775  }
2776 
2777  std::string dest=indent_str(indent);
2778  dest+="switch(";
2779  dest+=convert(src.op0());
2780  dest+=")\n";
2781 
2782  dest+=indent_str(indent);
2783  dest+='{';
2784 
2785  forall_operands(it, src)
2786  {
2787  if(it==src.operands().begin())
2788  continue;
2789  const exprt &op=*it;
2790 
2791  if(op.get(ID_statement)!=ID_block)
2792  {
2793  unsigned precedence;
2794  dest+=convert_norep(op, precedence);
2795  }
2796  else
2797  {
2798  for(const auto &operand : op.operands())
2799  dest += convert_code(to_code(operand), indent + 2);
2800  }
2801  }
2802 
2803  dest+="\n";
2804  dest+=indent_str(indent);
2805  dest+='}';
2806 
2807  return dest;
2808 }
2809 
2810 std::string expr2ct::convert_code_continue(unsigned indent)
2811 {
2812  std::string dest=indent_str(indent);
2813  dest+="continue";
2814  dest+=';';
2815 
2816  return dest;
2817 }
2818 
2819 std::string
2820 expr2ct::convert_code_frontend_decl(const codet &src, unsigned indent)
2821 {
2822  // initializer to go away
2823  if(src.operands().size()!=1 &&
2824  src.operands().size()!=2)
2825  {
2826  unsigned precedence;
2827  return convert_norep(src, precedence);
2828  }
2829 
2830  std::string declarator=convert(src.op0());
2831 
2832  std::string dest=indent_str(indent);
2833 
2834  const symbolt *symbol=nullptr;
2835  if(!ns.lookup(to_symbol_expr(src.op0()).get_identifier(), symbol))
2836  {
2837  if(symbol->is_file_local &&
2838  (src.op0().type().id()==ID_code || symbol->is_static_lifetime))
2839  dest+="static ";
2840  else if(symbol->is_extern)
2841  dest+="extern ";
2842  else if(
2844  {
2845  dest += "__declspec(dllexport) ";
2846  }
2847 
2848  if(symbol->type.id()==ID_code &&
2849  to_code_type(symbol->type).get_inlined())
2850  dest+="inline ";
2851  }
2852 
2853  dest+=convert_rec(src.op0().type(), c_qualifierst(), declarator);
2854 
2855  if(src.operands().size()==2)
2856  dest+="="+convert(src.op1());
2857 
2858  dest+=';';
2859 
2860  return dest;
2861 }
2862 
2864  const codet &src,
2865  unsigned indent)
2866 {
2867  // initializer to go away
2868  if(src.operands().size()!=1)
2869  {
2870  unsigned precedence;
2871  return convert_norep(src, precedence);
2872  }
2873 
2874  return indent_str(indent) + "dead " + convert(src.op0()) + ";";
2875 }
2876 
2878  const code_fort &src,
2879  unsigned indent)
2880 {
2881  if(src.operands().size()!=4)
2882  {
2883  unsigned precedence;
2884  return convert_norep(src, precedence);
2885  }
2886 
2887  std::string dest=indent_str(indent);
2888  dest+="for(";
2889 
2890  if(!src.init().is_nil())
2891  dest += convert(src.init());
2892  else
2893  dest+=' ';
2894  dest+="; ";
2895  if(!src.cond().is_nil())
2896  dest += convert(src.cond());
2897  dest+="; ";
2898  if(!src.iter().is_nil())
2899  dest += convert(src.iter());
2900 
2901  if(src.body().is_nil())
2902  dest+=");\n";
2903  else
2904  {
2905  dest+=")\n";
2906  dest+=convert_code(
2907  src.body(),
2908  src.body().get_statement()==ID_block ? indent : indent+2);
2909  }
2910 
2911  return dest;
2912 }
2913 
2915  const code_blockt &src,
2916  unsigned indent)
2917 {
2918  std::string dest=indent_str(indent);
2919  dest+="{\n";
2920 
2921  for(const auto &statement : src.statements())
2922  {
2923  if(statement.get_statement() == ID_label)
2924  dest += convert_code(statement, indent);
2925  else
2926  dest += convert_code(statement, indent + 2);
2927 
2928  dest+="\n";
2929  }
2930 
2931  dest+=indent_str(indent);
2932  dest+='}';
2933 
2934  return dest;
2935 }
2936 
2938  const codet &src,
2939  unsigned indent)
2940 {
2941  std::string dest;
2942 
2943  for(const auto &op : src.operands())
2944  {
2945  dest += convert_code(to_code(op), indent);
2946  dest+="\n";
2947  }
2948 
2949  return dest;
2950 }
2951 
2953  const codet &src,
2954  unsigned indent)
2955 {
2956  std::string dest=indent_str(indent);
2957 
2958  std::string expr_str;
2959  if(src.operands().size()==1)
2960  expr_str=convert(src.op0());
2961  else
2962  {
2963  unsigned precedence;
2964  expr_str=convert_norep(src, precedence);
2965  }
2966 
2967  dest+=expr_str;
2968  if(dest.empty() || *dest.rbegin()!=';')
2969  dest+=';';
2970 
2971  return dest;
2972 }
2973 
2975  const codet &src,
2976  unsigned indent)
2977 {
2978  static bool comment_done=false;
2979 
2980  if(
2981  !comment_done && (!src.source_location().get_comment().empty() ||
2982  !src.source_location().get_pragmas().empty()))
2983  {
2984  comment_done=true;
2985  std::string dest;
2986  if(!src.source_location().get_comment().empty())
2987  {
2988  dest += indent_str(indent);
2989  dest += "/* " + id2string(src.source_location().get_comment()) + " */\n";
2990  }
2991  if(!src.source_location().get_pragmas().empty())
2992  {
2993  std::ostringstream oss;
2994  oss << indent_str(indent) << "/* ";
2995  const auto &pragmas = src.source_location().get_pragmas();
2996  join_strings(
2997  oss,
2998  pragmas.begin(),
2999  pragmas.end(),
3000  ',',
3001  [](const std::pair<irep_idt, irept> &p) { return p.first; });
3002  oss << " */\n";
3003  dest += oss.str();
3004  }
3005  dest+=convert_code(src, indent);
3006  comment_done=false;
3007  return dest;
3008  }
3009 
3010  const irep_idt &statement=src.get_statement();
3011 
3012  if(statement==ID_expression)
3013  return convert_code_expression(src, indent);
3014 
3015  if(statement==ID_block)
3016  return convert_code_block(to_code_block(src), indent);
3017 
3018  if(statement==ID_switch)
3019  return convert_code_switch(src, indent);
3020 
3021  if(statement==ID_for)
3022  return convert_code_for(to_code_for(src), indent);
3023 
3024  if(statement==ID_while)
3025  return convert_code_while(to_code_while(src), indent);
3026 
3027  if(statement==ID_asm)
3028  return convert_code_asm(to_code_asm(src), indent);
3029 
3030  if(statement==ID_skip)
3031  return indent_str(indent)+";";
3032 
3033  if(statement==ID_dowhile)
3034  return convert_code_dowhile(to_code_dowhile(src), indent);
3035 
3036  if(statement==ID_ifthenelse)
3037  return convert_code_ifthenelse(to_code_ifthenelse(src), indent);
3038 
3039  if(statement==ID_return)
3040  return convert_code_return(src, indent);
3041 
3042  if(statement==ID_goto)
3043  return convert_code_goto(src, indent);
3044 
3045  if(statement==ID_printf)
3046  return convert_code_printf(src, indent);
3047 
3048  if(statement==ID_fence)
3049  return convert_code_fence(src, indent);
3050 
3052  return convert_code_input(src, indent);
3053 
3055  return convert_code_output(src, indent);
3056 
3057  if(statement==ID_assume)
3058  return convert_code_assume(src, indent);
3059 
3060  if(statement==ID_assert)
3061  return convert_code_assert(src, indent);
3062 
3063  if(statement==ID_break)
3064  return convert_code_break(indent);
3065 
3066  if(statement==ID_continue)
3067  return convert_code_continue(indent);
3068 
3069  if(statement==ID_decl)
3070  return convert_code_frontend_decl(src, indent);
3071 
3072  if(statement==ID_decl_block)
3073  return convert_code_decl_block(src, indent);
3074 
3075  if(statement==ID_dead)
3076  return convert_code_dead(src, indent);
3077 
3078  if(statement==ID_assign)
3080 
3081  if(statement=="lock")
3082  return convert_code_lock(src, indent);
3083 
3084  if(statement=="unlock")
3085  return convert_code_unlock(src, indent);
3086 
3087  if(statement==ID_atomic_begin)
3088  return indent_str(indent) + CPROVER_PREFIX + "atomic_begin();";
3089 
3090  if(statement==ID_atomic_end)
3091  return indent_str(indent) + CPROVER_PREFIX + "atomic_end();";
3092 
3093  if(statement==ID_function_call)
3095 
3096  if(statement==ID_label)
3097  return convert_code_label(to_code_label(src), indent);
3098 
3099  if(statement==ID_switch_case)
3100  return convert_code_switch_case(to_code_switch_case(src), indent);
3101 
3102  if(statement==ID_array_set)
3103  return convert_code_array_set(src, indent);
3104 
3105  if(statement==ID_array_copy)
3106  return convert_code_array_copy(src, indent);
3107 
3108  if(statement==ID_array_replace)
3109  return convert_code_array_replace(src, indent);
3110 
3111  if(statement == ID_set_may || statement == ID_set_must)
3112  return indent_str(indent) + convert_function(src, id2string(statement)) +
3113  ";";
3114 
3115  unsigned precedence;
3116  return convert_norep(src, precedence);
3117 }
3118 
3120  const code_frontend_assignt &src,
3121  unsigned indent)
3122 {
3123  return indent_str(indent) +
3124  convert_binary(to_binary_expr(src), "=", 2, true) + ";";
3125 }
3126 
3128  const codet &src,
3129  unsigned indent)
3130 {
3131  if(src.operands().size()!=1)
3132  {
3133  unsigned precedence;
3134  return convert_norep(src, precedence);
3135  }
3136 
3137  return indent_str(indent)+"LOCK("+convert(src.op0())+");";
3138 }
3139 
3141  const codet &src,
3142  unsigned indent)
3143 {
3144  if(src.operands().size()!=1)
3145  {
3146  unsigned precedence;
3147  return convert_norep(src, precedence);
3148  }
3149 
3150  return indent_str(indent)+"UNLOCK("+convert(src.op0())+");";
3151 }
3152 
3154  const code_function_callt &src,
3155  unsigned indent)
3156 {
3157  if(src.operands().size()!=3)
3158  {
3159  unsigned precedence;
3160  return convert_norep(src, precedence);
3161  }
3162 
3163  std::string dest=indent_str(indent);
3164 
3165  if(src.lhs().is_not_nil())
3166  {
3167  unsigned p;
3168  std::string lhs_str=convert_with_precedence(src.lhs(), p);
3169 
3170  // TODO: ggf. Klammern je nach p
3171  dest+=lhs_str;
3172  dest+='=';
3173  }
3174 
3175  {
3176  unsigned p;
3177  std::string function_str=convert_with_precedence(src.function(), p);
3178  dest+=function_str;
3179  }
3180 
3181  dest+='(';
3182 
3183  const exprt::operandst &arguments=src.arguments();
3184 
3185  forall_expr(it, arguments)
3186  {
3187  unsigned p;
3188  std::string arg_str=convert_with_precedence(*it, p);
3189 
3190  if(it!=arguments.begin())
3191  dest+=", ";
3192  // TODO: ggf. Klammern je nach p
3193  dest+=arg_str;
3194  }
3195 
3196  dest+=");";
3197 
3198  return dest;
3199 }
3200 
3202  const codet &src,
3203  unsigned indent)
3204 {
3205  std::string dest=indent_str(indent)+"printf(";
3206 
3207  forall_operands(it, src)
3208  {
3209  unsigned p;
3210  std::string arg_str=convert_with_precedence(*it, p);
3211 
3212  if(it!=src.operands().begin())
3213  dest+=", ";
3214  // TODO: ggf. Klammern je nach p
3215  dest+=arg_str;
3216  }
3217 
3218  dest+=");";
3219 
3220  return dest;
3221 }
3222 
3224  const codet &src,
3225  unsigned indent)
3226 {
3227  std::string dest=indent_str(indent)+"FENCE(";
3228 
3229  irep_idt att[]=
3230  { ID_WRfence, ID_RRfence, ID_RWfence, ID_WWfence,
3231  ID_RRcumul, ID_RWcumul, ID_WWcumul, ID_WRcumul,
3232  irep_idt() };
3233 
3234  bool first=true;
3235 
3236  for(unsigned i=0; !att[i].empty(); i++)
3237  {
3238  if(src.get_bool(att[i]))
3239  {
3240  if(first)
3241  first=false;
3242  else
3243  dest+='+';
3244 
3245  dest+=id2string(att[i]);
3246  }
3247  }
3248 
3249  dest+=");";
3250  return dest;
3251 }
3252 
3254  const codet &src,
3255  unsigned indent)
3256 {
3257  std::string dest=indent_str(indent)+"INPUT(";
3258 
3259  forall_operands(it, src)
3260  {
3261  unsigned p;
3262  std::string arg_str=convert_with_precedence(*it, p);
3263 
3264  if(it!=src.operands().begin())
3265  dest+=", ";
3266  // TODO: ggf. Klammern je nach p
3267  dest+=arg_str;
3268  }
3269 
3270  dest+=");";
3271 
3272  return dest;
3273 }
3274 
3276  const codet &src,
3277  unsigned indent)
3278 {
3279  std::string dest=indent_str(indent)+"OUTPUT(";
3280 
3281  forall_operands(it, src)
3282  {
3283  unsigned p;
3284  std::string arg_str=convert_with_precedence(*it, p);
3285 
3286  if(it!=src.operands().begin())
3287  dest+=", ";
3288  dest+=arg_str;
3289  }
3290 
3291  dest+=");";
3292 
3293  return dest;
3294 }
3295 
3297  const codet &src,
3298  unsigned indent)
3299 {
3300  std::string dest=indent_str(indent)+"ARRAY_SET(";
3301 
3302  forall_operands(it, src)
3303  {
3304  unsigned p;
3305  std::string arg_str=convert_with_precedence(*it, p);
3306 
3307  if(it!=src.operands().begin())
3308  dest+=", ";
3309  // TODO: ggf. Klammern je nach p
3310  dest+=arg_str;
3311  }
3312 
3313  dest+=");";
3314 
3315  return dest;
3316 }
3317 
3319  const codet &src,
3320  unsigned indent)
3321 {
3322  std::string dest=indent_str(indent)+"ARRAY_COPY(";
3323 
3324  forall_operands(it, src)
3325  {
3326  unsigned p;
3327  std::string arg_str=convert_with_precedence(*it, p);
3328 
3329  if(it!=src.operands().begin())
3330  dest+=", ";
3331  // TODO: ggf. Klammern je nach p
3332  dest+=arg_str;
3333  }
3334 
3335  dest+=");";
3336 
3337  return dest;
3338 }
3339 
3341  const codet &src,
3342  unsigned indent)
3343 {
3344  std::string dest=indent_str(indent)+"ARRAY_REPLACE(";
3345 
3346  forall_operands(it, src)
3347  {
3348  unsigned p;
3349  std::string arg_str=convert_with_precedence(*it, p);
3350 
3351  if(it!=src.operands().begin())
3352  dest+=", ";
3353  dest+=arg_str;
3354  }
3355 
3356  dest+=");";
3357 
3358  return dest;
3359 }
3360 
3362  const codet &src,
3363  unsigned indent)
3364 {
3365  if(src.operands().size()!=1)
3366  {
3367  unsigned precedence;
3368  return convert_norep(src, precedence);
3369  }
3370 
3371  return indent_str(indent)+"assert("+convert(src.op0())+");";
3372 }
3373 
3375  const codet &src,
3376  unsigned indent)
3377 {
3378  if(src.operands().size()!=1)
3379  {
3380  unsigned precedence;
3381  return convert_norep(src, precedence);
3382  }
3383 
3384  return indent_str(indent) + CPROVER_PREFIX + "assume(" + convert(src.op0()) +
3385  ");";
3386 }
3387 
3389  const code_labelt &src,
3390  unsigned indent)
3391 {
3392  std::string labels_string;
3393 
3394  irep_idt label=src.get_label();
3395 
3396  labels_string+="\n";
3397  labels_string+=indent_str(indent);
3398  labels_string+=clean_identifier(label);
3399  labels_string+=":\n";
3400 
3401  std::string tmp=convert_code(src.code(), indent+2);
3402 
3403  return labels_string+tmp;
3404 }
3405 
3407  const code_switch_caset &src,
3408  unsigned indent)
3409 {
3410  std::string labels_string;
3411 
3412  if(src.is_default())
3413  {
3414  labels_string+="\n";
3415  labels_string+=indent_str(indent);
3416  labels_string+="default:\n";
3417  }
3418  else
3419  {
3420  labels_string+="\n";
3421  labels_string+=indent_str(indent);
3422  labels_string+="case ";
3423  labels_string+=convert(src.case_op());
3424  labels_string+=":\n";
3425  }
3426 
3427  unsigned next_indent=indent;
3428  if(src.code().get_statement()!=ID_block &&
3429  src.code().get_statement()!=ID_switch_case)
3430  next_indent+=2;
3431  std::string tmp=convert_code(src.code(), next_indent);
3432 
3433  return labels_string+tmp;
3434 }
3435 
3436 std::string expr2ct::convert_code(const codet &src)
3437 {
3438  return convert_code(src, 0);
3439 }
3440 
3441 std::string expr2ct::convert_Hoare(const exprt &src)
3442 {
3443  unsigned precedence;
3444 
3445  if(src.operands().size()!=2)
3446  return convert_norep(src, precedence);
3447 
3448  const exprt &assumption = to_binary_expr(src).op0();
3449  const exprt &assertion = to_binary_expr(src).op1();
3450  const codet &code=
3451  static_cast<const codet &>(src.find(ID_code));
3452 
3453  std::string dest="\n";
3454  dest+='{';
3455 
3456  if(!assumption.is_nil())
3457  {
3458  std::string assumption_str=convert(assumption);
3459  dest+=" assume(";
3460  dest+=assumption_str;
3461  dest+=");\n";
3462  }
3463  else
3464  dest+="\n";
3465 
3466  {
3467  std::string code_str=convert_code(code);
3468  dest+=code_str;
3469  }
3470 
3471  if(!assertion.is_nil())
3472  {
3473  std::string assertion_str=convert(assertion);
3474  dest+=" assert(";
3475  dest+=assertion_str;
3476  dest+=");\n";
3477  }
3478 
3479  dest+='}';
3480 
3481  return dest;
3482 }
3483 
3484 std::string
3485 expr2ct::convert_extractbit(const extractbit_exprt &src, unsigned precedence)
3486 {
3487  std::string dest = convert_with_precedence(src.src(), precedence);
3488  dest+='[';
3489  dest += convert_with_precedence(src.index(), precedence);
3490  dest+=']';
3491 
3492  return dest;
3493 }
3494 
3495 std::string
3496 expr2ct::convert_extractbits(const extractbits_exprt &src, unsigned precedence)
3497 {
3498  std::string dest = convert_with_precedence(src.src(), precedence);
3499  dest+='[';
3500  dest += convert_with_precedence(src.upper(), precedence);
3501  dest+=", ";
3502  dest += convert_with_precedence(src.lower(), precedence);
3503  dest+=']';
3504 
3505  return dest;
3506 }
3507 
3509  const exprt &src,
3510  unsigned &precedence)
3511 {
3512  if(src.has_operands())
3513  return convert_norep(src, precedence);
3514 
3515  std::string dest="sizeof(";
3516  dest+=convert(static_cast<const typet&>(src.find(ID_type_arg)));
3517  dest+=')';
3518 
3519  return dest;
3520 }
3521 
3523 {
3524  std::string dest;
3525  unsigned p;
3526  const auto &cond = src.operands().front();
3527  if(!cond.is_true())
3528  {
3529  dest += convert_with_precedence(cond, p);
3530  dest += ": ";
3531  }
3532 
3533  const auto &targets = src.operands()[1];
3534  forall_operands(it, targets)
3535  {
3536  std::string op = convert_with_precedence(*it, p);
3537 
3538  if(it != targets.operands().begin())
3539  dest += ", ";
3540 
3541  dest += op;
3542  }
3543 
3544  return dest;
3545 }
3546 
3548 {
3549  if(auto type_ptr = type_try_dynamic_cast<unsignedbv_typet>(src.type()))
3550  {
3551  const std::size_t width = type_ptr->get_width();
3552  if(width == 8 || width == 16 || width == 32 || width == 64)
3553  {
3554  return convert_function(
3555  src, "__builtin_bitreverse" + std::to_string(width));
3556  }
3557  }
3558 
3559  unsigned precedence;
3560  return convert_norep(src, precedence);
3561 }
3562 
3564 {
3565  std::string dest = src.id() == ID_r_ok ? "R_OK"
3566  : src.id() == ID_w_ok ? "W_OK"
3567  : "RW_OK";
3568 
3569  dest += '(';
3570 
3571  unsigned p;
3572  dest += convert_with_precedence(src.pointer(), p);
3573  dest += ", ";
3574  dest += convert_with_precedence(src.size(), p);
3575 
3576  dest += ')';
3577 
3578  return dest;
3579 }
3580 
3581 std::string
3583 {
3584  // we hide prophecy expressions in C-style output
3585  std::string dest = src.id() == ID_prophecy_r_ok ? "R_OK"
3586  : src.id() == ID_prophecy_w_ok ? "W_OK"
3587  : "RW_OK";
3588 
3589  dest += '(';
3590 
3591  unsigned p;
3592  dest += convert_with_precedence(src.pointer(), p);
3593  dest += ", ";
3594  dest += convert_with_precedence(src.size(), p);
3595 
3596  dest += ')';
3597 
3598  return dest;
3599 }
3600 
3602 {
3603  std::string dest = CPROVER_PREFIX "pointer_in_range";
3604 
3605  dest += '(';
3606 
3607  unsigned p;
3608  dest += convert_with_precedence(src.lower_bound(), p);
3609  dest += ", ";
3610  dest += convert_with_precedence(src.pointer(), p);
3611  dest += ", ";
3612  dest += convert_with_precedence(src.upper_bound(), p);
3613 
3614  dest += ')';
3615 
3616  return dest;
3617 }
3618 
3621 {
3622  // we hide prophecy expressions in C-style output
3623  std::string dest = CPROVER_PREFIX "pointer_in_range";
3624 
3625  dest += '(';
3626 
3627  unsigned p;
3628  dest += convert_with_precedence(src.lower_bound(), p);
3629  dest += ", ";
3630  dest += convert_with_precedence(src.pointer(), p);
3631  dest += ", ";
3632  dest += convert_with_precedence(src.upper_bound(), p);
3633 
3634  dest += ')';
3635 
3636  return dest;
3637 }
3638 
3640  const exprt &src,
3641  unsigned &precedence)
3642 {
3643  precedence=16;
3644 
3645  if(src.id()==ID_plus)
3646  return convert_multi_ary(src, "+", precedence=12, false);
3647 
3648  else if(src.id()==ID_minus)
3649  return convert_binary(to_binary_expr(src), "-", precedence = 12, true);
3650 
3651  else if(src.id()==ID_unary_minus)
3652  return convert_unary(to_unary_expr(src), "-", precedence = 15);
3653 
3654  else if(src.id()==ID_unary_plus)
3655  return convert_unary(to_unary_expr(src), "+", precedence = 15);
3656 
3657  else if(src.id()==ID_floatbv_typecast)
3658  {
3659  const auto &floatbv_typecast = to_floatbv_typecast_expr(src);
3660 
3661  std::string dest="FLOAT_TYPECAST(";
3662 
3663  unsigned p0;
3664  std::string tmp0 = convert_with_precedence(floatbv_typecast.op(), p0);
3665 
3666  if(p0<=1)
3667  dest+='(';
3668  dest+=tmp0;
3669  if(p0<=1)
3670  dest+=')';
3671 
3672  dest+=", ";
3673  dest += convert(src.type());
3674  dest+=", ";
3675 
3676  unsigned p1;
3677  std::string tmp1 =
3678  convert_with_precedence(floatbv_typecast.rounding_mode(), p1);
3679 
3680  if(p1<=1)
3681  dest+='(';
3682  dest+=tmp1;
3683  if(p1<=1)
3684  dest+=')';
3685 
3686  dest+=')';
3687  return dest;
3688  }
3689 
3690  else if(src.id()==ID_sign)
3691  {
3692  if(to_unary_expr(src).op().type().id() == ID_floatbv)
3693  return convert_function(src, "signbit");
3694  else
3695  return convert_function(src, "SIGN");
3696  }
3697 
3698  else if(src.id()==ID_popcount)
3699  {
3701  return convert_function(src, "__popcnt");
3702  else
3703  return convert_function(src, "__builtin_popcount");
3704  }
3705 
3706  else if(src.id()=="pointer_arithmetic")
3707  return convert_pointer_arithmetic(src, precedence=16);
3708 
3709  else if(src.id()=="pointer_difference")
3710  return convert_pointer_difference(src, precedence=16);
3711 
3712  else if(src.id() == ID_null_object)
3713  return "NULL-object";
3714 
3715  else if(src.id()==ID_integer_address ||
3716  src.id()==ID_integer_address_object ||
3717  src.id()==ID_stack_object ||
3718  src.id()==ID_static_object)
3719  {
3720  return id2string(src.id());
3721  }
3722 
3723  else if(src.id()=="builtin-function")
3724  return src.get_string(ID_identifier);
3725 
3726  else if(src.id()==ID_array_of)
3727  return convert_array_of(src, precedence=16);
3728 
3729  else if(src.id()==ID_bswap)
3730  return convert_function(
3731  src,
3732  "__builtin_bswap" + integer2string(*pointer_offset_bits(
3733  to_unary_expr(src).op().type(), ns)));
3734 
3735  else if(src.id().starts_with("byte_extract"))
3736  return convert_byte_extract(to_byte_extract_expr(src), precedence = 16);
3737 
3738  else if(src.id().starts_with("byte_update"))
3739  return convert_byte_update(to_byte_update_expr(src), precedence = 16);
3740 
3741  else if(src.id()==ID_address_of)
3742  {
3743  const auto &object = to_address_of_expr(src).object();
3744 
3745  if(object.id() == ID_label)
3746  return "&&" + object.get_string(ID_identifier);
3747  else if(object.id() == ID_index && to_index_expr(object).index().is_zero())
3748  return convert(to_index_expr(object).array());
3749  else if(to_pointer_type(src.type()).base_type().id() == ID_code)
3750  return convert_unary(to_unary_expr(src), "", precedence = 15);
3751  else
3752  return convert_unary(to_unary_expr(src), "&", precedence = 15);
3753  }
3754 
3755  else if(src.id()==ID_dereference)
3756  {
3757  const auto &pointer = to_dereference_expr(src).pointer();
3758 
3759  if(src.type().id() == ID_code)
3760  return convert_unary(to_unary_expr(src), "", precedence = 15);
3761  else if(
3762  pointer.id() == ID_plus && pointer.operands().size() == 2 &&
3763  to_plus_expr(pointer).op0().type().id() == ID_pointer)
3764  {
3765  // Note that index[pointer] is legal C, but we avoid it nevertheless.
3766  return convert_index(to_binary_expr(pointer), precedence = 16);
3767  }
3768  else
3769  return convert_unary(to_unary_expr(src), "*", precedence = 15);
3770  }
3771 
3772  else if(src.id()==ID_index)
3773  return convert_index(to_binary_expr(src), precedence = 16);
3774 
3775  else if(src.id()==ID_member)
3776  return convert_member(to_member_expr(src), precedence=16);
3777 
3778  else if(src.id()=="array-member-value")
3779  return convert_array_member_value(src, precedence=16);
3780 
3781  else if(src.id()=="struct-member-value")
3782  return convert_struct_member_value(src, precedence=16);
3783 
3784  else if(src.id()==ID_function_application)
3786 
3787  else if(src.id()==ID_side_effect)
3788  {
3789  const irep_idt &statement=src.get(ID_statement);
3790  if(statement==ID_preincrement)
3791  return convert_unary(to_unary_expr(src), "++", precedence = 15);
3792  else if(statement==ID_predecrement)
3793  return convert_unary(to_unary_expr(src), "--", precedence = 15);
3794  else if(statement==ID_postincrement)
3795  return convert_unary_post(to_unary_expr(src), "++", precedence = 16);
3796  else if(statement==ID_postdecrement)
3797  return convert_unary_post(to_unary_expr(src), "--", precedence = 16);
3798  else if(statement==ID_assign_plus)
3799  return convert_binary(to_binary_expr(src), "+=", precedence = 2, true);
3800  else if(statement==ID_assign_minus)
3801  return convert_binary(to_binary_expr(src), "-=", precedence = 2, true);
3802  else if(statement==ID_assign_mult)
3803  return convert_binary(to_binary_expr(src), "*=", precedence = 2, true);
3804  else if(statement==ID_assign_div)
3805  return convert_binary(to_binary_expr(src), "/=", precedence = 2, true);
3806  else if(statement==ID_assign_mod)
3807  return convert_binary(to_binary_expr(src), "%=", precedence = 2, true);
3808  else if(statement==ID_assign_shl)
3809  return convert_binary(to_binary_expr(src), "<<=", precedence = 2, true);
3810  else if(statement==ID_assign_shr)
3811  return convert_binary(to_binary_expr(src), ">>=", precedence = 2, true);
3812  else if(statement==ID_assign_bitand)
3813  return convert_binary(to_binary_expr(src), "&=", precedence = 2, true);
3814  else if(statement==ID_assign_bitxor)
3815  return convert_binary(to_binary_expr(src), "^=", precedence = 2, true);
3816  else if(statement==ID_assign_bitor)
3817  return convert_binary(to_binary_expr(src), "|=", precedence = 2, true);
3818  else if(statement==ID_assign)
3819  return convert_binary(to_binary_expr(src), "=", precedence = 2, true);
3820  else if(statement==ID_function_call)
3823  else if(statement == ID_allocate)
3824  return convert_allocate(src, precedence = 15);
3825  else if(statement==ID_printf)
3826  return convert_function(src, "printf");
3827  else if(statement==ID_nondet)
3828  return convert_nondet(src, precedence=16);
3829  else if(statement=="prob_coin")
3830  return convert_prob_coin(src, precedence=16);
3831  else if(statement=="prob_unif")
3832  return convert_prob_uniform(src, precedence=16);
3833  else if(statement==ID_statement_expression)
3834  return convert_statement_expression(src, precedence=15);
3835  else if(statement == ID_va_start)
3836  return convert_function(src, CPROVER_PREFIX "va_start");
3837  else
3838  return convert_norep(src, precedence);
3839  }
3840 
3841  else if(src.id()==ID_literal)
3842  return convert_literal(src);
3843 
3844  else if(src.id()==ID_not)
3845  return convert_unary(to_not_expr(src), "!", precedence = 15);
3846 
3847  else if(src.id()==ID_bitnot)
3848  return convert_unary(to_bitnot_expr(src), "~", precedence = 15);
3849 
3850  else if(src.id()==ID_mult)
3851  return convert_multi_ary(src, "*", precedence=13, false);
3852 
3853  else if(src.id()==ID_div)
3854  return convert_binary(to_div_expr(src), "/", precedence = 13, true);
3855 
3856  else if(src.id()==ID_mod)
3857  return convert_binary(to_mod_expr(src), "%", precedence = 13, true);
3858 
3859  else if(src.id()==ID_shl)
3860  return convert_binary(to_shl_expr(src), "<<", precedence = 11, true);
3861 
3862  else if(src.id()==ID_ashr || src.id()==ID_lshr)
3863  return convert_binary(to_shift_expr(src), ">>", precedence = 11, true);
3864 
3865  else if(src.id()==ID_lt || src.id()==ID_gt ||
3866  src.id()==ID_le || src.id()==ID_ge)
3867  {
3868  return convert_binary(
3869  to_binary_relation_expr(src), src.id_string(), precedence = 10, true);
3870  }
3871 
3872  else if(src.id()==ID_notequal)
3873  return convert_binary(to_notequal_expr(src), "!=", precedence = 9, true);
3874 
3875  else if(src.id()==ID_equal)
3876  return convert_binary(to_equal_expr(src), "==", precedence = 9, true);
3877 
3878  else if(src.id()==ID_complex)
3879  return convert_complex(src, precedence=16);
3880 
3881  else if(src.id()==ID_bitand)
3882  return convert_multi_ary(src, "&", precedence=8, false);
3883 
3884  else if(src.id()==ID_bitxor)
3885  return convert_multi_ary(src, "^", precedence=7, false);
3886 
3887  else if(src.id()==ID_bitor)
3888  return convert_multi_ary(src, "|", precedence=6, false);
3889 
3890  else if(src.id()==ID_and)
3891  return convert_multi_ary(src, "&&", precedence=5, false);
3892 
3893  else if(src.id()==ID_or)
3894  return convert_multi_ary(src, "||", precedence=4, false);
3895 
3896  else if(src.id()==ID_xor)
3897  return convert_multi_ary(src, "!=", precedence = 9, false);
3898 
3899  else if(src.id()==ID_implies)
3900  return convert_binary(to_implies_expr(src), "==>", precedence = 3, true);
3901 
3902  else if(src.id()==ID_if)
3903  return convert_trinary(to_if_expr(src), "?", ":", precedence = 3);
3904 
3905  else if(src.id()==ID_forall)
3906  return convert_binding(to_quantifier_expr(src), "forall", precedence = 2);
3907 
3908  else if(src.id()==ID_exists)
3909  return convert_binding(to_quantifier_expr(src), "exists", precedence = 2);
3910 
3911  else if(src.id()==ID_lambda)
3912  return convert_binding(to_lambda_expr(src), "LAMBDA", precedence = 2);
3913 
3914  else if(src.id()==ID_with)
3915  return convert_with(src, precedence=16);
3916 
3917  else if(src.id()==ID_update)
3918  return convert_update(to_update_expr(src), precedence = 16);
3919 
3920  else if(src.id()==ID_member_designator)
3921  return precedence=16, convert_member_designator(src);
3922 
3923  else if(src.id()==ID_index_designator)
3924  return precedence=16, convert_index_designator(src);
3925 
3926  else if(src.id()==ID_symbol)
3927  return convert_symbol(src);
3928 
3929  else if(src.id()==ID_nondet_symbol)
3931 
3932  else if(src.id()==ID_predicate_symbol)
3933  return convert_predicate_symbol(src);
3934 
3935  else if(src.id()==ID_predicate_next_symbol)
3936  return convert_predicate_next_symbol(src);
3937 
3938  else if(src.id()==ID_predicate_passive_symbol)
3940 
3941  else if(src.id()=="quant_symbol")
3942  return convert_quantified_symbol(src);
3943 
3944  else if(src.id()==ID_nondet_bool)
3945  return convert_nondet_bool();
3946 
3947  else if(src.id()==ID_object_descriptor)
3948  return convert_object_descriptor(src, precedence);
3949 
3950  else if(src.id()=="Hoare")
3951  return convert_Hoare(src);
3952 
3953  else if(src.id()==ID_code)
3954  return convert_code(to_code(src));
3955 
3956  else if(src.is_constant())
3957  return convert_constant(to_constant_expr(src), precedence);
3958 
3959  else if(src.id() == ID_annotated_pointer_constant)
3960  {
3962  to_annotated_pointer_constant_expr(src), precedence);
3963  }
3964 
3965  else if(src.id()==ID_string_constant)
3966  return '"' + MetaString(id2string(to_string_constant(src).value())) + '"';
3967 
3968  else if(src.id()==ID_struct)
3969  return convert_struct(src, precedence);
3970 
3971  else if(src.id()==ID_vector)
3972  return convert_vector(src, precedence);
3973 
3974  else if(src.id()==ID_union)
3975  return convert_union(to_unary_expr(src), precedence);
3976 
3977  else if(src.id()==ID_array)
3978  return convert_array(src);
3979 
3980  else if(src.id() == ID_array_list)
3981  return convert_array_list(src, precedence);
3982 
3983  else if(src.id()==ID_typecast)
3984  return convert_typecast(to_typecast_expr(src), precedence=14);
3985 
3986  else if(src.id()==ID_comma)
3987  return convert_comma(src, precedence=1);
3988 
3989  else if(src.id()==ID_ptr_object)
3990  return "PTR_OBJECT("+id2string(src.get(ID_identifier))+")";
3991 
3992  else if(src.id()==ID_cond)
3993  return convert_cond(src, precedence);
3994 
3995  else if(
3998  {
3999  return convert_overflow(src, precedence);
4000  }
4001 
4002  else if(src.id()==ID_unknown)
4003  return "*";
4004 
4005  else if(src.id()==ID_invalid)
4006  return "#";
4007 
4008  else if(src.id()==ID_extractbit)
4009  return convert_extractbit(to_extractbit_expr(src), precedence);
4010 
4011  else if(src.id()==ID_extractbits)
4012  return convert_extractbits(to_extractbits_expr(src), precedence);
4013 
4014  else if(src.id()==ID_initializer_list ||
4015  src.id()==ID_compound_literal)
4016  {
4017  precedence = 15;
4018  return convert_initializer_list(src);
4019  }
4020 
4021  else if(src.id()==ID_designated_initializer)
4022  {
4023  precedence = 15;
4024  return convert_designated_initializer(src);
4025  }
4026 
4027  else if(src.id()==ID_sizeof)
4028  return convert_sizeof(src, precedence);
4029 
4030  else if(src.id()==ID_let)
4031  return convert_let(to_let_expr(src), precedence=16);
4032 
4033  else if(src.id()==ID_type)
4034  return convert(src.type());
4035 
4036  else if(src.id() == ID_rol || src.id() == ID_ror)
4037  return convert_rox(to_shift_expr(src), precedence);
4038 
4039  else if(src.id() == ID_conditional_target_group)
4040  {
4042  }
4043 
4044  else if(src.id() == ID_bitreverse)
4046 
4047  else if(src.id() == ID_r_ok || src.id() == ID_w_ok || src.id() == ID_rw_ok)
4048  return convert_r_or_w_ok(to_r_or_w_ok_expr(src));
4049 
4050  else if(
4051  auto prophecy_r_or_w_ok =
4052  expr_try_dynamic_cast<prophecy_r_or_w_ok_exprt>(src))
4053  {
4054  return convert_prophecy_r_or_w_ok(*prophecy_r_or_w_ok);
4055  }
4056 
4057  else if(src.id() == ID_pointer_in_range)
4059 
4060  else if(src.id() == ID_prophecy_pointer_in_range)
4061  {
4064  }
4065 
4066  auto function_string_opt = convert_function(src);
4067  if(function_string_opt.has_value())
4068  return *function_string_opt;
4069 
4070  // no C language expression for internal representation
4071  return convert_norep(src, precedence);
4072 }
4073 
4074 std::optional<std::string> expr2ct::convert_function(const exprt &src)
4075 {
4076  static const std::map<irep_idt, std::string> function_names = {
4077  {"buffer_size", "BUFFER_SIZE"},
4078  {"is_zero_string", "IS_ZERO_STRING"},
4079  {"object_value", "OBJECT_VALUE"},
4080  {"pointer_base", "POINTER_BASE"},
4081  {"pointer_cons", "POINTER_CONS"},
4082  {"zero_string", "ZERO_STRING"},
4083  {"zero_string_length", "ZERO_STRING_LENGTH"},
4084  {ID_abs, "abs"},
4085  {ID_alignof, "alignof"}, // C uses "_Alignof", C++ uses "alignof"
4086  {ID_builtin_offsetof, "builtin_offsetof"},
4087  {ID_complex_imag, "__imag__"},
4088  {ID_complex_real, "__real__"},
4089  {ID_concatenation, "CONCATENATION"},
4090  {ID_count_leading_zeros, "__builtin_clz"},
4091  {ID_count_trailing_zeros, "__builtin_ctz"},
4092  {ID_dynamic_object, "DYNAMIC_OBJECT"},
4093  {ID_live_object, "LIVE_OBJECT"},
4094  {ID_writeable_object, "WRITEABLE_OBJECT"},
4095  {ID_find_first_set, "__builtin_ffs"},
4096  {ID_separate, "SEPARATE"},
4097  {ID_floatbv_div, "FLOAT/"},
4098  {ID_floatbv_minus, "FLOAT-"},
4099  {ID_floatbv_mult, "FLOAT*"},
4100  {ID_floatbv_plus, "FLOAT+"},
4101  {ID_floatbv_rem, "FLOAT%"},
4102  {ID_gcc_builtin_va_arg, "gcc_builtin_va_arg"},
4103  {ID_get_may, CPROVER_PREFIX "get_may"},
4104  {ID_get_must, CPROVER_PREFIX "get_must"},
4105  {ID_ieee_float_equal, "IEEE_FLOAT_EQUAL"},
4106  {ID_ieee_float_notequal, "IEEE_FLOAT_NOTEQUAL"},
4107  {ID_infinity, "INFINITY"},
4108  {ID_is_dynamic_object, "IS_DYNAMIC_OBJECT"},
4109  {ID_is_invalid_pointer, "IS_INVALID_POINTER"},
4110  {ID_is_invalid_pointer, CPROVER_PREFIX "is_invalid_pointer"},
4111  {ID_isfinite, "isfinite"},
4112  {ID_isinf, "isinf"},
4113  {ID_isnan, "isnan"},
4114  {ID_isnormal, "isnormal"},
4115  {ID_object_size, CPROVER_PREFIX "OBJECT_SIZE"},
4116  {ID_pointer_object, CPROVER_PREFIX "POINTER_OBJECT"},
4117  {ID_pointer_offset, CPROVER_PREFIX "POINTER_OFFSET"},
4118  {ID_loop_entry, CPROVER_PREFIX "loop_entry"},
4119  {ID_saturating_minus, CPROVER_PREFIX "saturating_minus"},
4120  {ID_saturating_plus, CPROVER_PREFIX "saturating_plus"},
4121  {ID_width, "WIDTH"},
4122  };
4123 
4124  const auto function_entry = function_names.find(src.id());
4125  if(function_entry == function_names.end())
4126  return {};
4127 
4128  return convert_function(src, function_entry->second);
4129 }
4130 
4131 std::string expr2ct::convert(const exprt &src)
4132 {
4133  unsigned precedence;
4134  return convert_with_precedence(src, precedence);
4135 }
4136 
4143  const typet &src,
4144  const std::string &identifier)
4145 {
4146  return convert_rec(src, c_qualifierst(), identifier);
4147 }
4148 
4149 std::string expr2c(
4150  const exprt &expr,
4151  const namespacet &ns,
4152  const expr2c_configurationt &configuration)
4153 {
4154  std::string code;
4155  expr2ct expr2c(ns, configuration);
4156  expr2c.get_shorthands(expr);
4157  return expr2c.convert(expr);
4158 }
4159 
4160 std::string expr2c(const exprt &expr, const namespacet &ns)
4161 {
4163 }
4164 
4165 std::string type2c(
4166  const typet &type,
4167  const namespacet &ns,
4168  const expr2c_configurationt &configuration)
4169 {
4170  expr2ct expr2c(ns, configuration);
4171  // expr2c.get_shorthands(expr);
4172  return expr2c.convert(type);
4173 }
4174 
4175 std::string type2c(const typet &type, const namespacet &ns)
4176 {
4178 }
4179 
4180 std::string type2c(
4181  const typet &type,
4182  const std::string &identifier,
4183  const namespacet &ns,
4184  const expr2c_configurationt &configuration)
4185 {
4186  expr2ct expr2c(ns, configuration);
4187  return expr2c.convert_with_identifier(type, identifier);
4188 }
configt config
Definition: config.cpp:25
mp_integer bvrep2integer(const irep_idt &src, std::size_t width, bool is_signed)
convert a bit-vector representation (possibly signed) to integer
constant_exprt from_integer(const mp_integer &int_value, const typet &type)
std::size_t address_bits(const mp_integer &size)
ceil(log2(size))
const shift_exprt & to_shift_expr(const exprt &expr)
Cast an exprt to a shift_exprt.
const extractbit_exprt & to_extractbit_expr(const exprt &expr)
Cast an exprt to an extractbit_exprt.
const extractbits_exprt & to_extractbits_expr(const exprt &expr)
Cast an exprt to an extractbits_exprt.
const bitreverse_exprt & to_bitreverse_expr(const exprt &expr)
Cast an exprt to a bitreverse_exprt.
const bitnot_exprt & to_bitnot_expr(const exprt &expr)
Cast an exprt to a bitnot_exprt.
bool can_cast_expr< binary_overflow_exprt >(const exprt &base)
bool can_cast_expr< unary_minus_overflow_exprt >(const exprt &base)
const shl_exprt & to_shl_expr(const exprt &expr)
Cast an exprt to a shl_exprt.
const floatbv_typet & to_floatbv_type(const typet &type)
Cast a typet to a floatbv_typet.
const signedbv_typet & to_signedbv_type(const typet &type)
Cast a typet to a signedbv_typet.
bool can_cast_type< signedbv_typet >(const typet &type)
Check whether a reference to a typet is a signedbv_typet.
const bitvector_typet & to_bitvector_type(const typet &type)
Cast a typet to a bitvector_typet.
const fixedbv_typet & to_fixedbv_type(const typet &type)
Cast a typet to a fixedbv_typet.
bool can_cast_type< unsignedbv_typet >(const typet &type)
Check whether a reference to a typet is a unsignedbv_typet.
const unsignedbv_typet & to_unsignedbv_type(const typet &type)
Cast a typet to an unsignedbv_typet.
const byte_update_exprt & to_byte_update_expr(const exprt &expr)
const byte_extract_exprt & to_byte_extract_expr(const exprt &expr)
std::string MetaString(const std::string &in)
Definition: c_misc.cpp:95
ANSI-C Misc Utilities.
floatbv_typet float_type()
Definition: c_types.cpp:177
unsignedbv_typet unsigned_int_type()
Definition: c_types.cpp:36
std::string c_type_as_string(const irep_idt &c_type)
Definition: c_types.cpp:251
signedbv_typet signed_int_type()
Definition: c_types.cpp:22
bitvector_typet char_type()
Definition: c_types.cpp:106
bitvector_typet wchar_t_type()
Definition: c_types.cpp:141
floatbv_typet long_double_type()
Definition: c_types.cpp:193
floatbv_typet double_type()
Definition: c_types.cpp:185
const c_enum_typet & to_c_enum_type(const typet &type)
Cast a typet to a c_enum_typet.
Definition: c_types.h:335
const union_tag_typet & to_union_tag_type(const typet &type)
Cast a typet to a union_tag_typet.
Definition: c_types.h:224
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:80
const union_typet & to_union_type(const typet &type)
Cast a typet to a union_typet.
Definition: c_types.h:184
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:377
exprt & object()
Definition: pointer_expr.h:549
Pointer-typed bitvector constant annotated with the pointer expression that the bitvector is the nume...
const typet & element_type() const
The type of the elements of the array.
Definition: std_types.h:827
Arithmetic right shift.
A base class for binary expressions.
Definition: std_expr.h:638
exprt & op1()
Definition: expr.h:136
exprt & op0()
Definition: expr.h:133
A base class for variable bindings (quantifiers, let, lambda)
Definition: std_expr.h:3099
exprt & where()
Definition: std_expr.h:3130
variablest & variables()
Definition: std_expr.h:3120
Bit-wise OR.
Reverse the order of bits in a bit-vector.
std::size_t get_width() const
Definition: std_types.h:920
Expression of type type extracted from some object op starting at position offset (given in number of...
Expression corresponding to op() where the bytes starting at position offset (given in number of byte...
const typet & underlying_type() const
Definition: c_types.h:30
C enum tag type, i.e., c_enum_typet with an identifier.
Definition: c_types.h:352
The type of C enums.
Definition: c_types.h:239
memberst & members()
Definition: c_types.h:283
const typet & underlying_type() const
Definition: c_types.h:307
std::vector< c_enum_membert > memberst
Definition: c_types.h:275
virtual std::string as_string() const override
virtual void read(const typet &src) override
codet representation of an inline assembler statement.
Definition: std_code.h:1253
const irep_idt & get_flavor() const
Definition: std_code.h:1263
A codet representing sequential composition of program statements.
Definition: std_code.h:130
code_operandst & statements()
Definition: std_code.h:138
codet representation of a do while statement.
Definition: std_code.h:672
const exprt & cond() const
Definition: std_code.h:679
const codet & body() const
Definition: std_code.h:689
codet representation of a for statement.
Definition: std_code.h:734
const exprt & init() const
Definition: std_code.h:749
const exprt & iter() const
Definition: std_code.h:769
const exprt & cond() const
Definition: std_code.h:759
const codet & body() const
Definition: std_code.h:779
A codet representing an assignment in the program.
Definition: std_code.h:24
goto_instruction_codet representation of a function call statement.
codet representation of an if-then-else statement.
Definition: std_code.h:460
const codet & then_case() const
Definition: std_code.h:488
const exprt & cond() const
Definition: std_code.h:478
const codet & else_case() const
Definition: std_code.h:498
codet representation of a label for branch targets.
Definition: std_code.h:959
const irep_idt & get_label() const
Definition: std_code.h:967
codet & code()
Definition: std_code.h:977
codet representation of a switch-case, i.e. a case statement within a switch.
Definition: std_code.h:1023
codet & code()
Definition: std_code.h:1050
const exprt & case_op() const
Definition: std_code.h:1040
bool is_default() const
Definition: std_code.h:1030
Base type of functions.
Definition: std_types.h:583
std::vector< parametert > parameterst
Definition: std_types.h:585
const typet & return_type() const
Definition: std_types.h:689
bool get_inlined() const
Definition: std_types.h:709
bool has_ellipsis() const
Definition: std_types.h:655
const parameterst & parameters() const
Definition: std_types.h:699
codet representing a while statement.
Definition: std_code.h:610
const exprt & cond() const
Definition: std_code.h:617
const codet & body() const
Definition: std_code.h:627
Data structure for representing an arbitrary statement in a program.
Definition: std_code_base.h:29
exprt & op3()
Definition: expr.h:142
exprt & op1()
Definition: expr.h:136
exprt & op2()
Definition: expr.h:139
exprt & op0()
Definition: expr.h:133
const irep_idt & get_statement() const
Definition: std_code_base.h:65
struct configt::ansi_ct ansi_c
A constant literal expression.
Definition: std_expr.h:2987
const irep_idt & get_value() const
Definition: std_expr.h:2995
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
bool empty() const
Definition: dstring.h:89
const char * c_str() const
Definition: dstring.h:116
std::optional< std::string > convert_function(const exprt &src)
Returns a string if src is a function with a known conversion, else returns nullopt.
Definition: expr2c.cpp:4074
std::string convert_nondet(const exprt &src, unsigned &precedence)
Definition: expr2c.cpp:1172
std::string convert_literal(const exprt &src)
Definition: expr2c.cpp:1207
std::string convert_code_continue(unsigned indent)
Definition: expr2c.cpp:2810
virtual std::string convert_array_type(const typet &src, const qualifierst &qualifiers, const std::string &declarator_str)
To generate a C-like type declaration of an array.
Definition: expr2c.cpp:716
std::string convert_code_switch_case(const code_switch_caset &src, unsigned indent)
Definition: expr2c.cpp:3406
std::string convert_typecast(const typecast_exprt &src, unsigned &precedence)
Definition: expr2c.cpp:755
std::string convert_comma(const exprt &src, unsigned precedence)
Definition: expr2c.cpp:1244
std::string convert_code_assert(const codet &src, unsigned indent)
Definition: expr2c.cpp:3361
std::string convert_union(const exprt &src, unsigned &precedence)
Definition: expr2c.cpp:2177
std::string convert_code_expression(const codet &src, unsigned indent)
Definition: expr2c.cpp:2952
std::string convert_code_goto(const codet &src, unsigned indent)
Definition: expr2c.cpp:2746
std::string convert_code_switch(const codet &src, unsigned indent)
Definition: expr2c.cpp:2767
std::string convert_pointer_in_range(const pointer_in_range_exprt &src)
Definition: expr2c.cpp:3601
std::string convert_initializer_list(const exprt &src)
Definition: expr2c.cpp:2333
std::string convert_quantified_symbol(const exprt &src)
Definition: expr2c.cpp:1693
std::string convert_binding(const binding_exprt &, const std::string &symbol, unsigned precedence)
Definition: expr2c.cpp:836
std::string convert_function_application(const function_application_exprt &src)
Definition: expr2c.cpp:2462
std::string convert_code_unlock(const codet &src, unsigned indent)
Definition: expr2c.cpp:3140
std::string convert_code_decl_block(const codet &src, unsigned indent)
Definition: expr2c.cpp:2937
static std::string indent_str(unsigned indent)
Definition: expr2c.cpp:2550
std::string convert_byte_update(const byte_update_exprt &, unsigned precedence)
Definition: expr2c.cpp:1354
std::string convert_code(const codet &src)
Definition: expr2c.cpp:3436
std::string convert_pointer_arithmetic(const exprt &src, unsigned &precedence)
Definition: expr2c.cpp:1420
std::string convert_let(const let_exprt &, unsigned precedence)
Definition: expr2c.cpp:925
std::string convert_nondet_bool()
Definition: expr2c.cpp:1699
std::string convert_norep(const exprt &src, unsigned &precedence)
Definition: expr2c.cpp:1618
const expr2c_configurationt & configuration
Definition: expr2c_class.h:56
std::unordered_map< irep_idt, std::unordered_set< irep_idt > > ns_collision
Definition: expr2c_class.h:88
std::string convert_code_output(const codet &src, unsigned indent)
Definition: expr2c.cpp:3275
std::string convert_code_while(const code_whilet &src, unsigned indent)
Definition: expr2c.cpp:2633
std::string convert_index_designator(const exprt &src)
Definition: expr2c.cpp:1506
std::string convert_code_frontend_decl(const codet &, unsigned indent)
Definition: expr2c.cpp:2820
std::string convert_pointer_difference(const exprt &src, unsigned &precedence)
Definition: expr2c.cpp:1457
std::string convert_code_block(const code_blockt &src, unsigned indent)
Definition: expr2c.cpp:2914
std::string convert_code_asm(const code_asmt &src, unsigned indent)
Definition: expr2c.cpp:2555
std::string convert_prophecy_pointer_in_range(const prophecy_pointer_in_range_exprt &src)
Definition: expr2c.cpp:3619
std::string convert_allocate(const exprt &src, unsigned &precedence)
Definition: expr2c.cpp:1144
std::string convert_Hoare(const exprt &src)
Definition: expr2c.cpp:3441
std::string convert_sizeof(const exprt &src, unsigned &precedence)
Definition: expr2c.cpp:3508
std::string convert_code_lock(const codet &src, unsigned indent)
Definition: expr2c.cpp:3127
std::string convert_r_or_w_ok(const r_or_w_ok_exprt &src)
Definition: expr2c.cpp:3563
std::string convert_code_dowhile(const code_dowhilet &src, unsigned indent)
Definition: expr2c.cpp:2659
irep_idt id_shorthand(const irep_idt &identifier) const
Definition: expr2c.cpp:76
std::string convert_cond(const exprt &src, unsigned precedence)
Definition: expr2c.cpp:990
std::string convert_side_effect_expr_function_call(const side_effect_expr_function_callt &src)
Definition: expr2c.cpp:2490
std::string convert_overflow(const exprt &src, unsigned &precedence)
Definition: expr2c.cpp:2519
std::string convert_member(const member_exprt &src, unsigned precedence)
Definition: expr2c.cpp:1516
void get_shorthands(const exprt &expr)
Definition: expr2c.cpp:117
std::string convert_code_for(const code_fort &src, unsigned indent)
Definition: expr2c.cpp:2877
std::string convert_with_identifier(const typet &src, const std::string &identifier)
Build a declaration string, which requires converting both a type and putting an identifier in the sy...
Definition: expr2c.cpp:4142
std::string convert_extractbits(const extractbits_exprt &src, unsigned precedence)
Definition: expr2c.cpp:3496
virtual std::string convert_struct(const exprt &src, unsigned &precedence)
Definition: expr2c.cpp:2041
std::string convert_trinary(const ternary_exprt &src, const std::string &symbol1, const std::string &symbol2, unsigned precedence)
Definition: expr2c.cpp:789
std::string convert_prob_coin(const exprt &src, unsigned &precedence)
Definition: expr2c.cpp:1197
std::string convert_update(const update_exprt &, unsigned precedence)
Definition: expr2c.cpp:952
std::string convert_nondet_symbol(const nondet_symbol_exprt &)
Definition: expr2c.cpp:1669
std::string convert_code_printf(const codet &src, unsigned indent)
Definition: expr2c.cpp:3201
std::string convert_unary(const unary_exprt &, const std::string &symbol, unsigned precedence)
Definition: expr2c.cpp:1124
std::string convert_code_ifthenelse(const code_ifthenelset &src, unsigned indent)
Definition: expr2c.cpp:2688
std::string convert_index(const binary_exprt &, unsigned precedence)
Definition: expr2c.cpp:1401
std::string convert_member_designator(const exprt &src)
Definition: expr2c.cpp:1496
virtual std::string convert_rec(const typet &src, const qualifierst &qualifiers, const std::string &declarator)
Definition: expr2c.cpp:219
std::string convert_byte_extract(const byte_extract_exprt &, unsigned precedence)
Definition: expr2c.cpp:1328
std::string convert_code_label(const code_labelt &src, unsigned indent)
Definition: expr2c.cpp:3388
virtual std::string convert_symbol(const exprt &src)
Definition: expr2c.cpp:1629
virtual std::string convert_constant(const constant_exprt &src, unsigned &precedence)
Definition: expr2c.cpp:1774
std::string convert_code_array_copy(const codet &src, unsigned indent)
Definition: expr2c.cpp:3318
std::string convert_statement_expression(const exprt &src, unsigned &precendence)
Definition: expr2c.cpp:1182
std::string convert_struct_member_value(const exprt &src, unsigned precedence)
Definition: expr2c.cpp:1608
std::string convert_code_dead(const codet &src, unsigned indent)
Definition: expr2c.cpp:2863
const namespacet & ns
Definition: expr2c_class.h:55
virtual std::string convert_annotated_pointer_constant(const annotated_pointer_constant_exprt &src, unsigned &precedence)
Definition: expr2c.cpp:2020
std::string convert_rox(const shift_exprt &src, unsigned precedence)
Conversion function from rol/ror expressions to C code strings Note that this constructs a complex ex...
Definition: expr2c.cpp:2359
virtual std::string convert_with_precedence(const exprt &src, unsigned &precedence)
Definition: expr2c.cpp:3639
std::string convert_designated_initializer(const exprt &src)
Definition: expr2c.cpp:2419
std::string convert_vector(const exprt &src, unsigned &precedence)
Definition: expr2c.cpp:2130
std::string convert_multi_ary(const exprt &src, const std::string &symbol, unsigned precedence, bool full_parentheses)
Definition: expr2c.cpp:1076
std::string convert_array_member_value(const exprt &src, unsigned precedence)
Definition: expr2c.cpp:1598
std::string convert_unary_post(const exprt &src, const std::string &symbol, unsigned precedence)
Definition: expr2c.cpp:1379
std::unordered_map< irep_idt, irep_idt > shorthands
Definition: expr2c_class.h:89
std::string convert_complex(const exprt &src, unsigned precedence)
Definition: expr2c.cpp:1268
std::string convert_code_function_call(const code_function_callt &src, unsigned indent)
Definition: expr2c.cpp:3153
std::string convert_code_fence(const codet &src, unsigned indent)
Definition: expr2c.cpp:3223
std::string convert_bitreverse(const bitreverse_exprt &src)
Definition: expr2c.cpp:3547
virtual std::string convert(const typet &src)
Definition: expr2c.cpp:214
std::string convert_code_return(const codet &src, unsigned indent)
Definition: expr2c.cpp:2725
std::string convert_code_break(unsigned indent)
Definition: expr2c.cpp:2758
virtual std::string convert_struct_type(const typet &src, const std::string &qualifiers_str, const std::string &declarator_str)
To generate C-like string for defining the given struct.
Definition: expr2c.cpp:638
std::string convert_with(const exprt &src, unsigned precedence)
Definition: expr2c.cpp:859
std::string convert_code_frontend_assign(const code_frontend_assignt &, unsigned indent)
Definition: expr2c.cpp:3119
std::string convert_object_descriptor(const exprt &src, unsigned &precedence)
Definition: expr2c.cpp:1704
std::string convert_predicate_passive_symbol(const exprt &src)
Definition: expr2c.cpp:1687
std::string convert_array_list(const exprt &src, unsigned &precedence)
Definition: expr2c.cpp:2299
unsigned sizeof_nesting
Definition: expr2c_class.h:91
std::string convert_array_of(const exprt &src, unsigned precedence)
Definition: expr2c.cpp:1318
std::string convert_code_array_replace(const codet &src, unsigned indent)
Definition: expr2c.cpp:3340
std::string convert_conditional_target_group(const exprt &src)
Definition: expr2c.cpp:3522
std::string convert_code_assume(const codet &src, unsigned indent)
Definition: expr2c.cpp:3374
std::string convert_code_input(const codet &src, unsigned indent)
Definition: expr2c.cpp:3253
std::string convert_extractbit(const extractbit_exprt &, unsigned precedence)
Definition: expr2c.cpp:3485
std::string convert_predicate_next_symbol(const exprt &src)
Definition: expr2c.cpp:1681
std::string convert_code_array_set(const codet &src, unsigned indent)
Definition: expr2c.cpp:3296
std::string convert_binary(const binary_exprt &, const std::string &symbol, unsigned precedence, bool full_parentheses)
Definition: expr2c.cpp:1024
virtual std::string convert_constant_bool(bool boolean_value)
To get the C-like representation of a given boolean value.
Definition: expr2c.cpp:2033
std::string convert_predicate_symbol(const exprt &src)
Definition: expr2c.cpp:1675
std::string convert_prophecy_r_or_w_ok(const prophecy_r_or_w_ok_exprt &src)
Definition: expr2c.cpp:3582
std::string convert_array(const exprt &src)
Definition: expr2c.cpp:2196
std::string convert_prob_uniform(const exprt &src, unsigned &precedence)
Definition: expr2c.cpp:1212
Base class for all expressions.
Definition: expr.h:56
std::vector< exprt > operandst
Definition: expr.h:58
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
const source_locationt & source_location() const
Definition: expr.h:231
typet & type()
Return the type of the expression.
Definition: expr.h:84
bool is_constant() const
Return whether the expression is a constant.
Definition: expr.h:212
operandst & operands()
Definition: expr.h:94
Extracts a single bit of a bit-vector operand.
Extracts a sub-range of a bit-vector operand.
std::size_t get_fraction_bits() const
std::string to_ansi_c_string() const
Definition: fixedbv.h:62
Application of (mathematical) function.
std::string to_ansi_c_string() const
Definition: ieee_float.h:280
There are a large number of kinds of tree structured or tree-like data in CPROVER.
Definition: irep.h:360
bool get_bool(const irep_idt &name) const
Definition: irep.cpp:57
const irept & find(const irep_idt &name) const
Definition: irep.cpp:93
const irep_idt & get(const irep_idt &name) const
Definition: irep.cpp:44
const std::string & id_string() const
Definition: irep.h:387
void set(const irep_idt &name, const irep_idt &value)
Definition: irep.h:408
bool is_not_nil() const
Definition: irep.h:368
const irep_idt & id() const
Definition: irep.h:384
const std::string & get_string(const irep_idt &name) const
Definition: irep.h:397
bool is_nil() const
Definition: irep.h:364
A let expression.
Definition: std_expr.h:3196
exprt & where()
convenience accessor for binding().where()
Definition: std_expr.h:3289
binding_exprt::variablest & variables()
convenience accessor for binding().variables()
Definition: std_expr.h:3277
operandst & values()
Definition: std_expr.h:3266
std::string expr2string() const
Definition: lispexpr.cpp:15
Extract member of struct or union.
Definition: std_expr.h:2841
const exprt & compound() const
Definition: std_expr.h:2890
irep_idt get_component_name() const
Definition: std_expr.h:2863
std::size_t get_component_number() const
Definition: std_expr.h:2873
Binary minus.
Definition: std_expr.h:1061
Modulo defined as lhs-(rhs * truncate(lhs/rhs)).
Definition: std_expr.h:1223
Binary multiplication Associativity is not specified.
Definition: std_expr.h:1107
const union_typet & follow_tag(const union_tag_typet &) const
Follow type tag of union type.
Definition: namespace.cpp:63
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition: namespace.h:94
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
Definition: namespace.cpp:148
Expression to hold a nondeterministic choice.
Definition: std_expr.h:292
const irep_idt & get_identifier() const
Definition: std_expr.h:320
The plus expression Associativity is not specified.
Definition: std_expr.h:1002
pointer_in_range(a, b, c) evaluates to true iff same_object(a, b, c) ∧ r_ok(a, offset(c)-offset(a)) ∧...
Definition: pointer_expr.h:387
const exprt & lower_bound() const
Definition: pointer_expr.h:402
const exprt & pointer() const
Definition: pointer_expr.h:407
const exprt & upper_bound() const
Definition: pointer_expr.h:412
const typet & base_type() const
The type of the data what we point to.
Definition: pointer_expr.h:35
pointer_in_range (see pointer_in_range_exprt) with prophecy expressions to encode whether a pointer r...
Definition: pointer_expr.h:453
const exprt & upper_bound() const
Definition: pointer_expr.h:485
const exprt & lower_bound() const
Definition: pointer_expr.h:475
const exprt & pointer() const
Definition: pointer_expr.h:480
A base class for a predicate that indicates that an address range is ok to read or write or both.
const exprt & size() const
const exprt & pointer() const
virtual std::unique_ptr< qualifierst > clone() const =0
A base class for a predicate that indicates that an address range is ok to read or write or both.
Definition: pointer_expr.h:920
const exprt & size() const
Definition: pointer_expr.h:932
const exprt & pointer() const
Definition: pointer_expr.h:927
A base class for shift and rotate operators.
exprt & distance()
exprt & op()
Left shift.
A side_effect_exprt representation of a function call side effect.
Definition: std_code.h:1692
exprt::operandst & arguments()
Definition: std_code.h:1718
const irep_idt & get_function() const
const irep_idt & get_comment() const
const irept::named_subt & get_pragmas() const
A struct tag type, i.e., struct_typet with an identifier.
Definition: std_types.h:493
Structure type, corresponds to C style structs.
Definition: std_types.h:231
const irep_idt & get_pretty_name() const
Definition: std_types.h:109
Base type for structs and unions.
Definition: std_types.h:62
irep_idt get_tag() const
Definition: std_types.h:168
const componentt & get_component(const irep_idt &component_name) const
Get the reference to a component with given name.
Definition: std_types.cpp:63
bool is_incomplete() const
A struct/union may be incomplete.
Definition: std_types.h:185
const componentst & components() const
Definition: std_types.h:147
std::vector< componentt > componentst
Definition: std_types.h:140
Expression to hold a symbol (variable)
Definition: std_expr.h:131
const irep_idt & get_identifier() const
Definition: std_expr.h:160
Symbol table entry.
Definition: symbol.h:28
irep_idt base_name
Base (non-scoped) name.
Definition: symbol.h:46
bool is_extern
Definition: symbol.h:74
bool is_file_local
Definition: symbol.h:73
bool is_static_lifetime
Definition: symbol.h:70
bool is_parameter
Definition: symbol.h:76
source_locationt location
Source code location of definition of symbol.
Definition: symbol.h:37
typet type
Type of symbol.
Definition: symbol.h:31
bool is_exported
Definition: symbol.h:63
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
const typet & subtype() const
Definition: type.h:187
Semantic type conversion.
Definition: std_expr.h:2068
static exprt conditional_cast(const exprt &expr, const typet &type)
Definition: std_expr.h:2076
The type of an expression, extends irept.
Definition: type.h:29
Generic base class for unary expressions.
Definition: std_expr.h:361
const exprt & op() const
Definition: std_expr.h:391
A union tag type, i.e., union_typet with an identifier.
Definition: c_types.h:199
The union type.
Definition: c_types.h:147
Fixed-width bit-vector with unsigned binary interpretation.
Operator to update elements in structs and arrays.
Definition: std_expr.h:2655
The vector type.
Definition: std_types.h:1052
const constant_exprt & size() const
Definition: std_types.cpp:275
const typet & element_type() const
The type of the elements of the vector.
Definition: std_types.h:1068
exprt & old()
Definition: std_expr.h:2481
bool has_prefix(const std::string &s, const std::string &prefix)
Definition: converter.cpp:13
#define CPROVER_PREFIX
int isdigit(int c)
Definition: ctype.c:24
int isxdigit(int c)
Definition: ctype.c:95
std::string expr2c(const exprt &expr, const namespacet &ns, const expr2c_configurationt &configuration)
Definition: expr2c.cpp:4149
static std::optional< exprt > build_sizeof_expr(const constant_exprt &expr, const namespacet &ns)
Definition: expr2c.cpp:1729
std::string type2c(const typet &type, const namespacet &ns, const expr2c_configurationt &configuration)
Definition: expr2c.cpp:4165
static std::string clean_identifier(const irep_idt &id)
Definition: expr2c.cpp:94
#define forall_operands(it, expr)
Definition: expr.h:20
#define forall_expr(it, expr)
Definition: expr.h:32
bool is_null_pointer(const constant_exprt &expr)
Returns true if expr has a pointer type and a value NULL; it also returns true when expr has value ze...
Definition: expr_util.cpp:369
Deprecated expression utility functions.
find_symbols_sett find_symbol_identifiers(const exprt &src)
Find identifiers of the sub expressions with id ID_symbol, considering both free and bound variables.
Definition: find_symbols.h:53
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
bool can_cast_expr< code_inputt >(const exprt &base)
bool can_cast_expr< code_outputt >(const exprt &base)
const code_function_callt & to_code_function_call(const goto_instruction_codet &code)
const std::string & id2string(const irep_idt &d)
Definition: irep.h:40
std::string from_type(const namespacet &ns, const irep_idt &identifier, const typet &type)
void irep2lisp(const irept &src, lispexprt &dest)
Definition: lispirep.cpp:43
literalt pos(literalt a)
Definition: literal.h:194
double remainder(double x, double y)
Definition: math.c:2396
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 std::string integer2string(const mp_integer &n, unsigned base)
Definition: mp_arith.cpp:103
API to expression classes for Pointers.
const r_or_w_ok_exprt & to_r_or_w_ok_expr(const exprt &expr)
Definition: pointer_expr.h:949
const annotated_pointer_constant_exprt & to_annotated_pointer_constant_expr(const exprt &expr)
Cast an exprt to an annotated_pointer_constant_exprt.
const prophecy_pointer_in_range_exprt & to_prophecy_pointer_in_range_expr(const exprt &expr)
Definition: pointer_expr.h:517
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 pointer_in_range_exprt & to_pointer_in_range_expr(const exprt &expr)
Definition: pointer_expr.h:432
const address_of_exprt & to_address_of_expr(const exprt &expr)
Cast an exprt to an address_of_exprt.
Definition: pointer_expr.h:577
std::optional< mp_integer > pointer_offset_bits(const typet &type, const namespacet &ns)
std::optional< exprt > size_of_expr(const typet &type, const namespacet &ns)
Pointer Logic.
#define SYMEX_DYNAMIC_PREFIX
BigInt mp_integer
Definition: smt_terms.h:17
#define CHECK_RETURN(CONDITION)
Definition: invariant.h:495
#define UNREACHABLE
This should be used to mark dead code.
Definition: invariant.h:525
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
Definition: invariant.h:534
const code_ifthenelset & to_code_ifthenelse(const codet &code)
Definition: std_code.h:530
const code_whilet & to_code_while(const codet &code)
Definition: std_code.h:654
const code_switch_caset & to_code_switch_case(const codet &code)
Definition: std_code.h:1077
const code_labelt & to_code_label(const codet &code)
Definition: std_code.h:1004
side_effect_expr_function_callt & to_side_effect_expr_function_call(exprt &expr)
Definition: std_code.h:1739
const code_dowhilet & to_code_dowhile(const codet &code)
Definition: std_code.h:716
const code_blockt & to_code_block(const codet &code)
Definition: std_code.h:203
const code_frontend_returnt & to_code_frontend_return(const codet &code)
Definition: std_code.h:943
const code_frontend_assignt & to_code_frontend_assign(const codet &code)
Definition: std_code.h:113
const code_fort & to_code_for(const codet &code)
Definition: std_code.h:823
code_asmt & to_code_asm(codet &code)
Definition: std_code.h:1282
const codet & to_code(const exprt &expr)
auto component(T &struct_expr, const irep_idt &name, const namespacet &ns) -> decltype(struct_expr.op0())
Definition: std_expr.cpp:80
const notequal_exprt & to_notequal_expr(const exprt &expr)
Cast an exprt to an notequal_exprt.
Definition: std_expr.h:1445
const if_exprt & to_if_expr(const exprt &expr)
Cast an exprt to an if_exprt.
Definition: std_expr.h:2450
const update_exprt & to_update_expr(const exprt &expr)
Cast an exprt to an update_exprt.
Definition: std_expr.h:2735
const let_exprt & to_let_expr(const exprt &expr)
Cast an exprt to a let_exprt.
Definition: std_expr.h:3320
const constant_exprt & to_constant_expr(const exprt &expr)
Cast an exprt to a constant_exprt.
Definition: std_expr.h:3037
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
Definition: std_expr.h:272
const mod_exprt & to_mod_expr(const exprt &expr)
Cast an exprt to a mod_exprt.
Definition: std_expr.h:1272
const typecast_exprt & to_typecast_expr(const exprt &expr)
Cast an exprt to a typecast_exprt.
Definition: std_expr.h:2102
const not_exprt & to_not_expr(const exprt &expr)
Cast an exprt to an not_exprt.
Definition: std_expr.h:2352
const union_exprt & to_union_expr(const exprt &expr)
Cast an exprt to a union_exprt.
Definition: std_expr.h:1811
const div_exprt & to_div_expr(const exprt &expr)
Cast an exprt to a div_exprt.
Definition: std_expr.h:1201
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 with_exprt & to_with_expr(const exprt &expr)
Cast an exprt to a with_exprt.
Definition: std_expr.h:2533
const binary_exprt & to_binary_expr(const exprt &expr)
Cast an exprt to a binary_exprt.
Definition: std_expr.h:715
const equal_exprt & to_equal_expr(const exprt &expr)
Cast an exprt to an equal_exprt.
Definition: std_expr.h:1402
const plus_exprt & to_plus_expr(const exprt &expr)
Cast an exprt to a plus_exprt.
Definition: std_expr.h:1041
const member_exprt & to_member_expr(const exprt &expr)
Cast an exprt to a member_exprt.
Definition: std_expr.h:2933
const unary_exprt & to_unary_expr(const exprt &expr)
Cast an exprt to a unary_exprt.
Definition: std_expr.h:426
const nondet_symbol_exprt & to_nondet_symbol_expr(const exprt &expr)
Cast an exprt to a nondet_symbol_exprt.
Definition: std_expr.h:343
const implies_exprt & to_implies_expr(const exprt &expr)
Cast an exprt to a implies_exprt.
Definition: std_expr.h:2208
const binary_relation_exprt & to_binary_relation_expr(const exprt &expr)
Cast an exprt to a binary_relation_exprt.
Definition: std_expr.h:895
const index_exprt & to_index_expr(const exprt &expr)
Cast an exprt to an index_exprt.
Definition: std_expr.h:1533
const vector_typet & to_vector_type(const typet &type)
Cast a typet to a vector_typet.
Definition: std_types.h:1104
const struct_typet & to_struct_type(const typet &type)
Cast a typet to a struct_typet.
Definition: std_types.h:308
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
Definition: std_types.h:788
bool is_constant(const typet &type)
This method tests, if the given typet is a constant.
Definition: std_types.h:29
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
Definition: std_types.h:888
bool can_cast_type< code_typet >(const typet &type)
Check whether a reference to a typet is a code_typet.
Definition: std_types.h:775
const complex_typet & to_complex_type(const typet &type)
Cast a typet to a complex_typet.
Definition: std_types.h:1146
const struct_union_typet & to_struct_union_type(const typet &type)
Cast a typet to a struct_union_typet.
Definition: std_types.h:214
const struct_tag_typet & to_struct_tag_type(const typet &type)
Cast a typet to a struct_tag_typet.
Definition: std_types.h:518
const struct_or_union_tag_typet & to_struct_or_union_tag_type(const typet &type)
Cast a typet to a struct_or_union_tag_typet.
Definition: std_types.h:478
const string_constantt & to_string_constant(const exprt &expr)
void replace(const union_find_replacet &replace_map, string_not_contains_constraintt &constraint)
std::string to_string(const string_not_contains_constraintt &expr)
Used for debug printing.
Stream & join_strings(Stream &&os, const It b, const It e, const Delimiter &delimiter, TransformFunc &&transform_func)
Prints items to an stream, separated by a constant delimiter.
Definition: string_utils.h:61
std::size_t long_double_width
Definition: config.h:146
std::size_t double_width
Definition: config.h:145
bool char_is_unsigned
Definition: config.h:150
std::size_t long_long_int_width
Definition: config.h:142
std::size_t long_int_width
Definition: config.h:138
std::size_t single_width
Definition: config.h:144
std::size_t short_int_width
Definition: config.h:141
std::size_t char_width
Definition: config.h:140
flavourt mode
Definition: config.h:253
std::size_t int_width
Definition: config.h:137
Used for configuring the behaviour of expr2c and type2c.
Definition: expr2c.h:21
bool print_enum_int_value
When printing an enum-typed constant, print the integer representation.
Definition: expr2c.h:43
static expr2c_configurationt clean_configuration
This prints compilable C that loses some of the internal details of the GOTO program.
Definition: expr2c.h:75
bool expand_typedef
Print the expanded type instead of a typedef name, even when a typedef is present.
Definition: expr2c.h:47
static expr2c_configurationt default_configuration
This prints a human readable C like syntax that closely mirrors the internals of the GOTO program.
Definition: expr2c.h:71
std::string true_string
This is the string that will be printed for the true boolean expression.
Definition: expr2c.h:34
bool print_struct_body_in_type
When printing a struct_typet, should the components of the struct be printed inline.
Definition: expr2c.h:28
bool use_library_macros
This is the string that will be printed for null pointers.
Definition: expr2c.h:40
bool include_struct_padding_components
When printing struct_typet or struct_exprt, include the artificial padding components introduced to k...
Definition: expr2c.h:24
std::string false_string
This is the string that will be printed for the false boolean expression.
Definition: expr2c.h:37
bool include_array_size
When printing array_typet, should the size of the array be printed.
Definition: expr2c.h:31
bool has_suffix(const std::string &s, const std::string &suffix)
Definition: suffix.h:17
Symbol table entry.
#define size_type
Definition: unistd.c:347
bool is_signed(const typet &t)
Convenience function – is the type signed?
Definition: util.cpp:45
dstringt irep_idt