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