CBMC
dump_c.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Dump Goto-Program as C/C++ Source
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
11 
12 #include "dump_c.h"
13 #include "dump_c_class.h"
14 
15 #include <util/byte_operators.h>
16 #include <util/c_types.h>
17 #include <util/config.h>
18 #include <util/expr_initializer.h>
19 #include <util/expr_util.h>
20 #include <util/find_symbols.h>
21 #include <util/get_base_name.h>
22 #include <util/invariant.h>
23 #include <util/prefix.h>
24 #include <util/replace_symbol.h>
25 #include <util/string_utils.h>
26 
27 #include <ansi-c/expr2c.h>
28 #include <cpp/expr2cpp.h>
30 
31 #include "goto_program2code.h"
32 
35 
42 
43 inline std::ostream &operator << (std::ostream &out, dump_ct &src)
44 {
45  src(out);
46  return out;
47 }
48 
49 void dump_ct::operator()(std::ostream &os)
50 {
51  std::stringstream func_decl_stream;
52  std::stringstream compound_body_stream;
53  std::stringstream global_var_stream;
54  std::stringstream global_decl_stream;
55  std::stringstream global_decl_header_stream;
56  std::stringstream func_body_stream;
57  local_static_declst local_static_decls;
58 
59  // add copies of struct types when ID_C_transparent_union is only
60  // annotated to parameter
61  symbol_tablet symbols_transparent;
62  for(const auto &named_symbol : copied_symbol_table.symbols)
63  {
64  const symbolt &symbol=named_symbol.second;
65 
66  if(symbol.type.id()!=ID_code)
67  continue;
68 
69  code_typet &code_type=to_code_type(
70  copied_symbol_table.get_writeable_ref(named_symbol.first).type);
71  code_typet::parameterst &parameters=code_type.parameters();
72 
73  for(code_typet::parameterst::iterator
74  it2=parameters.begin();
75  it2!=parameters.end();
76  ++it2)
77  {
78  typet &type=it2->type();
79 
80  if(type.id() == ID_union_tag && type.get_bool(ID_C_transparent_union))
81  {
82  symbolt new_type_sym =
84 
85  new_type_sym.name=id2string(new_type_sym.name)+"$transparent";
86  new_type_sym.type.set(ID_C_transparent_union, true);
87 
88  // we might have it already, in which case this has no effect
89  symbols_transparent.add(new_type_sym);
90 
91  to_union_tag_type(type).set_identifier(new_type_sym.name);
92  type.remove(ID_C_transparent_union);
93  }
94  }
95  }
96  for(const auto &symbol_pair : symbols_transparent.symbols)
97  {
98  copied_symbol_table.add(symbol_pair.second);
99  }
100 
101  typedef std::unordered_map<irep_idt, unsigned> unique_tagst;
102  unique_tagst unique_tags;
103 
104  // add tags to anonymous union/struct/enum,
105  // and prepare lexicographic order
106  std::set<std::string> symbols_sorted;
107  for(const auto &named_symbol : copied_symbol_table.symbols)
108  {
109  symbolt &symbol = copied_symbol_table.get_writeable_ref(named_symbol.first);
110  bool tag_added=false;
111 
112  // TODO we could get rid of some of the ID_anonymous by looking up
113  // the origin symbol types in typedef_types and adjusting any other
114  // uses of ID_tag
115  if((symbol.type.id()==ID_union || symbol.type.id()==ID_struct) &&
116  symbol.type.get(ID_tag).empty())
117  {
118  PRECONDITION(symbol.is_type);
119  symbol.type.set(ID_tag, ID_anonymous);
120  tag_added=true;
121  }
122  else if(symbol.type.id()==ID_c_enum &&
123  symbol.type.find(ID_tag).get(ID_C_base_name).empty())
124  {
125  PRECONDITION(symbol.is_type);
126  symbol.type.add(ID_tag).set(ID_C_base_name, ID_anonymous);
127  tag_added=true;
128  }
129 
130  const std::string name_str=id2string(named_symbol.first);
131  if(symbol.is_type &&
132  (symbol.type.id()==ID_union ||
133  symbol.type.id()==ID_struct ||
134  symbol.type.id()==ID_c_enum))
135  {
136  std::string new_tag=symbol.type.id()==ID_c_enum?
137  symbol.type.find(ID_tag).get_string(ID_C_base_name):
138  symbol.type.get_string(ID_tag);
139 
140  std::string::size_type tag_pos=new_tag.rfind("tag-");
141  if(tag_pos!=std::string::npos)
142  new_tag.erase(0, tag_pos+4);
143  const std::string new_tag_base=new_tag;
144 
145  for(std::pair<unique_tagst::iterator, bool>
146  unique_entry=unique_tags.insert(std::make_pair(new_tag, 0));
147  !unique_entry.second;
148  unique_entry=unique_tags.insert(std::make_pair(new_tag, 0)))
149  {
150  new_tag=new_tag_base+"$"+
151  std::to_string(unique_entry.first->second);
152  ++(unique_entry.first->second);
153  }
154 
155  if(symbol.type.id()==ID_c_enum)
156  {
157  symbol.type.add(ID_tag).set(ID_C_base_name, new_tag);
158  symbol.base_name=new_tag;
159  }
160  else
161  symbol.type.set(ID_tag, new_tag);
162  }
163 
164  // we don't want to dump in full all definitions; in particular
165  // do not dump anonymous types that are defined in system headers
166  if((!tag_added || symbol.is_type) &&
168  symbol.name!=goto_functions.entry_point())
169  continue;
170 
171  bool inserted=symbols_sorted.insert(name_str).second;
172  CHECK_RETURN(inserted);
173  }
174 
176 
177  // collect all declarations we might need, include local static variables
178  bool skip_function_main=false;
179  std::vector<std::string> header_files;
180  for(std::set<std::string>::const_iterator
181  it=symbols_sorted.begin();
182  it!=symbols_sorted.end();
183  ++it)
184  {
185  const symbolt &symbol=ns.lookup(*it);
186  const irep_idt &type_id=symbol.type.id();
187 
188  if(symbol.is_type &&
189  symbol.location.get_function().empty() &&
190  (type_id==ID_struct ||
191  type_id==ID_union ||
192  type_id==ID_c_enum))
193  {
195  {
196  global_decl_stream << "// " << symbol.name << '\n';
197  global_decl_stream << "// " << symbol.location << '\n';
198 
199  std::string location_file =
200  get_base_name(id2string(symbol.location.get_file()), false);
201  // collect header the types are borrowed from
202  // expect header files to end in .h
203  if(
204  location_file.length() > 1 &&
205  location_file[location_file.length() - 1] == 'h')
206  {
207  std::vector<std::string>::iterator it =
208  find(header_files.begin(), header_files.end(), location_file);
209  if(it == header_files.end())
210  {
211  header_files.push_back(location_file);
212  global_decl_header_stream << "#include \"" << location_file
213  << "\"\n";
214  }
215  }
216 
217  if(type_id==ID_c_enum)
218  convert_compound_enum(symbol.type, global_decl_stream);
219  else if(type_id == ID_struct)
220  {
221  global_decl_stream << type_to_string(struct_tag_typet{symbol.name})
222  << ";\n\n";
223  }
224  else
225  {
226  global_decl_stream << type_to_string(union_tag_typet{symbol.name})
227  << ";\n\n";
228  }
229  }
230  }
231  else if(
232  symbol.is_static_lifetime && symbol.type.id() != ID_code &&
233  !symbol.type.get_bool(ID_C_do_not_dump))
235  symbol,
236  global_var_stream,
237  local_static_decls);
238  else if(symbol.type.id()==ID_code)
239  {
240  goto_functionst::function_mapt::const_iterator func_entry=
241  goto_functions.function_map.find(symbol.name);
242 
243  if(
244  !harness && func_entry != goto_functions.function_map.end() &&
245  func_entry->second.body_available() &&
246  (symbol.name == ID_main ||
247  (config.main.has_value() && symbol.name == config.main.value())))
248  {
249  skip_function_main=true;
250  }
251  }
252  }
253 
254  // function declarations and definitions
255  for(std::set<std::string>::const_iterator
256  it=symbols_sorted.begin();
257  it!=symbols_sorted.end();
258  ++it)
259  {
260  const symbolt &symbol=ns.lookup(*it);
261 
262  if(symbol.type.id()!=ID_code ||
263  symbol.is_type)
264  continue;
265 
267  symbol,
268  skip_function_main,
269  func_decl_stream,
270  func_body_stream,
271  local_static_decls);
272  }
273 
274  // (possibly modified) compound types
275  for(std::set<std::string>::const_iterator
276  it=symbols_sorted.begin();
277  it!=symbols_sorted.end();
278  ++it)
279  {
280  const symbolt &symbol=ns.lookup(*it);
281 
282  if(
283  symbol.is_type &&
284  (symbol.type.id() == ID_struct || symbol.type.id() == ID_union))
286  symbol,
287  compound_body_stream);
288  }
289 
290  // Dump the code to the target stream;
291  // the statements before to this point collect the code to dump!
292  for(std::set<std::string>::const_iterator
293  it=system_headers.begin();
294  it!=system_headers.end();
295  ++it)
296  os << "#include <" << *it << ">\n";
297  if(!system_headers.empty())
298  os << '\n';
299 
300  if(!global_decl_header_stream.str().empty() && dump_c_config.include_headers)
301  os << global_decl_header_stream.str() << '\n';
302 
303  if(global_var_stream.str().find("NULL")!=std::string::npos ||
304  func_body_stream.str().find("NULL")!=std::string::npos)
305  {
306  os << "#ifndef NULL\n"
307  << "#define NULL ((void*)0)\n"
308  << "#endif\n\n";
309  }
310  if(func_body_stream.str().find("FENCE")!=std::string::npos)
311  {
312  os << "#ifndef FENCE\n"
313  << "#define FENCE(x) ((void)0)\n"
314  << "#endif\n\n";
315  }
316  if(func_body_stream.str().find("IEEE_FLOAT_")!=std::string::npos)
317  {
318  os << "#ifndef IEEE_FLOAT_EQUAL\n"
319  << "#define IEEE_FLOAT_EQUAL(x,y) ((x)==(y))\n"
320  << "#endif\n"
321  << "#ifndef IEEE_FLOAT_NOTEQUAL\n"
322  << "#define IEEE_FLOAT_NOTEQUAL(x,y) ((x)!=(y))\n"
323  << "#endif\n\n";
324  }
325 
326  if(!global_decl_stream.str().empty() && dump_c_config.include_global_decls)
327  os << global_decl_stream.str() << '\n';
328 
330  dump_typedefs(os);
331 
332  if(!func_decl_stream.str().empty() && dump_c_config.include_function_decls)
333  os << func_decl_stream.str() << '\n';
334  if(!compound_body_stream.str().empty() && dump_c_config.include_compounds)
335  os << compound_body_stream.str() << '\n';
336  if(!global_var_stream.str().empty() && dump_c_config.include_global_vars)
337  os << global_var_stream.str() << '\n';
339  os << func_body_stream.str();
340 }
341 
344  const symbolt &symbol,
345  std::ostream &os_body)
346 {
347  if(
348  !symbol.location.get_function().empty() ||
349  symbol.type.get_bool(ID_C_do_not_dump))
350  {
351  return;
352  }
353 
354  // do compound type body
355  if(symbol.type.id() == ID_struct)
357  symbol.type,
358  struct_tag_typet(symbol.name),
360  os_body);
361  else if(symbol.type.id() == ID_union)
363  symbol.type,
364  union_tag_typet(symbol.name),
366  os_body);
367  else if(symbol.type.id() == ID_c_enum)
369  symbol.type,
370  c_enum_tag_typet(symbol.name),
372  os_body);
373 }
374 
376  const typet &type,
377  const typet &unresolved,
378  bool recursive,
379  std::ostream &os)
380 {
381  if(
382  type.id() == ID_c_enum_tag || type.id() == ID_struct_tag ||
383  type.id() == ID_union_tag)
384  {
385  const symbolt &symbol = ns.lookup(to_tag_type(type));
386  DATA_INVARIANT(symbol.is_type, "tag expected to be type symbol");
387 
389  convert_compound(symbol.type, unresolved, recursive, os);
390  }
391  else if(type.id()==ID_array || type.id()==ID_pointer)
392  {
393  if(!recursive)
394  return;
395 
397  to_type_with_subtype(type).subtype(),
398  to_type_with_subtype(type).subtype(),
399  recursive,
400  os);
401 
402  // sizeof may contain a type symbol that has to be declared first
403  if(type.id()==ID_array)
404  {
405  find_symbols_sett syms;
406  find_non_pointer_type_symbols(to_array_type(type).size(), syms);
407 
408  for(find_symbols_sett::const_iterator
409  it=syms.begin();
410  it!=syms.end();
411  ++it)
412  {
413  const symbolt &type_symbol = ns.lookup(*it);
414  irep_idt tag_kind =
415  type_symbol.type.id() == ID_c_enum
416  ? ID_c_enum_tag
417  : (type_symbol.type.id() == ID_union ? ID_union_tag
418  : ID_struct_tag);
419  tag_typet s_type(tag_kind, *it);
420  convert_compound(s_type, s_type, recursive, os);
421  }
422  }
423  }
424  else if(type.id()==ID_struct || type.id()==ID_union)
425  convert_compound(to_struct_union_type(type), unresolved, recursive, os);
426  else if(type.id()==ID_c_enum)
427  convert_compound_enum(type, os);
428 }
429 
431  const struct_union_typet &type,
432  const typet &unresolved,
433  bool recursive,
434  std::ostream &os)
435 {
436  const irep_idt &name=type.get(ID_tag);
437 
438  if(!converted_compound.insert(name).second || type.get_bool(ID_C_do_not_dump))
439  return;
440 
441  // make sure typedef names used in the declaration are available
442  collect_typedefs(type, true);
443 
444  const irept &bases = type.find(ID_bases);
445  std::stringstream base_decls;
446  for(const auto &parent : bases.get_sub())
447  {
448  UNREACHABLE;
449  (void)parent;
450 #if 0
451  assert(parent.id() == ID_base);
452  assert(parent.get(ID_type) == ID_struct_tag);
453 
454  const irep_idt &base_id=
455  parent.find(ID_type).get(ID_identifier);
456  const irep_idt &renamed_base_id=global_renaming[base_id];
457  const symbolt &parsymb=ns.lookup(renamed_base_id);
458 
459  convert_compound_rec(parsymb.type, os);
460 
461  base_decls << id2string(renamed_base_id) +
462  (parent_it+1==bases.get_sub().end()?"":", ");
463 #endif
464  }
465 
466 #if 0
467  // for the constructor
468  string constructor_args;
469  string constructor_body;
470 
471  std::string component_name = id2string(renaming[compo.get(ID_name)]);
472  assert(component_name != "");
473 
474  if(it != struct_type.components().begin()) constructor_args += ", ";
475 
476  if(compo.type().id() == ID_pointer)
477  constructor_args += type_to_string(compo.type()) + component_name;
478  else
479  constructor_args += "const " + type_to_string(compo.type()) + "& " + component_name;
480 
481  constructor_body += indent + indent + "this->"+component_name + " = " + component_name + ";\n";
482 #endif
483 
484  std::stringstream struct_body;
485 
486  for(const auto &comp : type.components())
487  {
488  const typet &comp_type = comp.type();
489 
490  if(comp_type.id()==ID_code ||
491  comp.get_bool(ID_from_base) ||
492  comp.get_is_padding())
493  continue;
494 
495  const typet *non_array_type = &comp_type;
496  while(non_array_type->id()==ID_array)
497  non_array_type = &(to_array_type(*non_array_type).element_type());
498 
499  bool is_anon =
500  can_cast_type<tag_typet>(comp.type()) &&
501  has_prefix(
502  id2string(to_tag_type(comp.type()).get_identifier()), "tag-#anon");
503 
504  if(recursive)
505  {
506  if(non_array_type->id() != ID_pointer && !is_anon)
507  convert_compound(comp.type(), comp.type(), recursive, os);
508  else
509  collect_typedefs(comp.type(), true);
510  }
511 
512  irep_idt comp_name=comp.get_name();
513 
514  struct_body << indent(1) << "// " << comp_name << '\n';
515  struct_body << indent(1);
516 
517  // component names such as "main" would collide with other objects in the
518  // namespace
519  std::string fake_unique_name="NO/SUCH/NS::"+id2string(comp_name);
520  typet comp_type_to_use = comp.type();
521  if(is_anon)
522  {
523  comp_type_to_use = ns.follow(comp.type());
524  comp_type_to_use.remove(ID_tag);
525  if(
526  recursive && (comp_type_to_use.id() == ID_struct ||
527  comp_type_to_use.id() == ID_union))
528  {
529  const auto &sub_comps =
530  to_struct_union_type(comp_type_to_use).components();
531  for(const auto &sc : sub_comps)
532  convert_compound(sc.type(), sc.type(), recursive, os);
533  }
534  }
535  std::string s = make_decl(fake_unique_name, comp_type_to_use);
536  POSTCONDITION(s.find("NO/SUCH/NS")==std::string::npos);
537 
538  if(comp_type.id()==ID_c_bit_field &&
539  to_c_bit_field_type(comp_type).get_width()==0)
540  {
541  comp_name.clear();
542  s=type_to_string(comp_type);
543  }
544 
545  if(s.find(CPROVER_PREFIX "bitvector") == std::string::npos)
546  {
547  struct_body << s;
548  }
549  else if(comp_type.id()==ID_signedbv)
550  {
551  const signedbv_typet &t=to_signedbv_type(comp_type);
553  struct_body << "long long int " << comp_name
554  << " : " << t.get_width();
555  else if(mode == ID_cpp)
556  struct_body << "__signedbv<" << t.get_width() << "> "
557  << comp_name;
558  else
559  struct_body << s;
560  }
561  else if(comp_type.id()==ID_unsignedbv)
562  {
563  const unsignedbv_typet &t=to_unsignedbv_type(comp_type);
565  struct_body << "unsigned long long " << comp_name
566  << " : " << t.get_width();
567  else if(mode == ID_cpp)
568  struct_body << "__unsignedbv<" << t.get_width() << "> "
569  << comp_name;
570  else
571  struct_body << s;
572  }
573  else
574  UNREACHABLE;
575 
576  struct_body << ";\n";
577  }
578 
579  typet unresolved_clean=unresolved;
580  irep_idt typedef_str;
581  for(auto td_entry : typedef_types)
582  {
583  if(
584  td_entry.first.get(ID_identifier) == unresolved.get(ID_identifier) &&
585  (td_entry.first.source_location() == unresolved.source_location()))
586  {
587  unresolved_clean.remove(ID_C_typedef);
588  typedef_str = td_entry.second;
589  std::pair<typedef_mapt::iterator, bool> td_map_entry =
590  typedef_map.insert({typedef_str, typedef_infot(typedef_str)});
591  PRECONDITION(!td_map_entry.second);
592  if(!td_map_entry.first->second.early)
593  td_map_entry.first->second.type_decl_str.clear();
594  os << "typedef ";
595  break;
596  }
597  }
598 
599  os << type_to_string(unresolved_clean);
600  if(!base_decls.str().empty())
601  {
602  PRECONDITION(mode == ID_cpp);
603  os << ": " << base_decls.str();
604  }
605  os << '\n';
606  os << "{\n";
607  os << struct_body.str();
608 
609  /*
610  if(!struct_type.components().empty())
611  {
612  os << indent << name << "(){}\n";
613  os << indent << "explicit " << name
614  << "(" + constructor_args + ")\n";
615  os << indent << "{\n";
616  os << constructor_body;
617  os << indent << "}\n";
618  }
619  */
620 
621  os << "}";
622  if(type.get_bool(ID_C_transparent_union))
623  os << " __attribute__ ((__transparent_union__))";
624  if(type.get_bool(ID_C_packed))
625  os << " __attribute__ ((__packed__))";
626  if(!typedef_str.empty())
627  os << " " << typedef_str;
628  os << ";\n\n";
629 }
630 
632  const typet &type,
633  std::ostream &os)
634 {
635  PRECONDITION(type.id()==ID_c_enum);
636 
637  const irept &tag=type.find(ID_tag);
638  const irep_idt &name=tag.get(ID_C_base_name);
639 
640  if(tag.is_nil() ||
641  !converted_enum.insert(name).second)
642  return;
643 
644  c_enum_typet enum_type=to_c_enum_type(type);
645  c_enum_typet::memberst &members=
646  (c_enum_typet::memberst &)(enum_type.add(ID_body).get_sub());
647  for(c_enum_typet::memberst::iterator
648  it=members.begin();
649  it!=members.end();
650  ++it)
651  {
652  const irep_idt bn=it->get_base_name();
653 
654  if(declared_enum_constants.find(bn)!=
655  declared_enum_constants.end() ||
657  {
658  std::string new_bn=id2string(name)+"$$"+id2string(bn);
659  it->set_base_name(new_bn);
660  }
661 
663  std::make_pair(bn, it->get_base_name()));
664  }
665 
666  os << type_to_string(enum_type);
667 
668  if(enum_type.get_bool(ID_C_packed))
669  os << " __attribute__ ((__packed__))";
670 
671  os << ";\n\n";
672 }
673 
675  code_frontend_declt &decl,
676  std::list<irep_idt> &local_static,
677  std::list<irep_idt> &local_type_decls)
678 {
679  goto_programt tmp;
680  tmp.add(goto_programt::make_decl(decl.symbol()));
681 
682  if(optionalt<exprt> value = decl.initial_value())
683  {
684  decl.set_initial_value({});
685  tmp.add(goto_programt::make_assignment(decl.symbol(), std::move(*value)));
686  }
687 
689 
690  // goto_program2codet requires valid location numbers:
691  tmp.update();
692 
693  std::unordered_set<irep_idt> typedef_names;
694  for(const auto &td : typedef_map)
695  typedef_names.insert(td.first);
696 
697  code_blockt b;
698  goto_program2codet p2s(
699  irep_idt(),
700  tmp,
702  b,
703  local_static,
704  local_type_decls,
705  typedef_names,
707  p2s();
708 
709  POSTCONDITION(b.statements().size() == 1);
710  decl.swap(b.op0());
711 }
712 
718 void dump_ct::collect_typedefs(const typet &type, bool early)
719 {
720  std::unordered_set<irep_idt> deps;
721  collect_typedefs_rec(type, early, deps);
722 }
723 
732  const typet &type,
733  bool early,
734  std::unordered_set<irep_idt> &dependencies)
735 {
736  std::unordered_set<irep_idt> local_deps;
737 
738  if(type.id()==ID_code)
739  {
740  const code_typet &code_type=to_code_type(type);
741 
742  collect_typedefs_rec(code_type.return_type(), early, local_deps);
743  for(const auto &param : code_type.parameters())
744  collect_typedefs_rec(param.type(), early, local_deps);
745  }
746  else if(type.id()==ID_pointer || type.id()==ID_array)
747  {
749  to_type_with_subtype(type).subtype(), early, local_deps);
750  }
751  else if(
752  type.id() == ID_c_enum_tag || type.id() == ID_struct_tag ||
753  type.id() == ID_union_tag)
754  {
755  const symbolt &symbol = ns.lookup(to_tag_type(type));
756  collect_typedefs_rec(symbol.type, early, local_deps);
757  }
758 
759  const irep_idt &typedef_str=type.get(ID_C_typedef);
760 
761  if(!typedef_str.empty())
762  {
763  std::pair<typedef_mapt::iterator, bool> entry=
764  typedef_map.insert({typedef_str, typedef_infot(typedef_str)});
765 
766  if(entry.second ||
767  (early && entry.first->second.type_decl_str.empty()))
768  {
769  if(typedef_str=="__gnuc_va_list" || typedef_str == "va_list")
770  {
771  system_headers.insert("stdarg.h");
772  early=false;
773  }
774  else
775  {
776  typet t=type;
777  t.remove(ID_C_typedef);
778 
779  std::ostringstream oss;
780  oss << "typedef " << make_decl(typedef_str, t) << ';';
781 
782  entry.first->second.type_decl_str=oss.str();
783  entry.first->second.dependencies=local_deps;
784  }
785  }
786 
787  if(early)
788  {
789  entry.first->second.early=true;
790 
791  for(const auto &d : local_deps)
792  {
793  auto td_entry=typedef_map.find(d);
794  PRECONDITION(td_entry!=typedef_map.end());
795  td_entry->second.early=true;
796  }
797  }
798 
799  dependencies.insert(typedef_str);
800  }
801 
802  dependencies.insert(local_deps.begin(), local_deps.end());
803 }
804 
807 {
808  // sort the symbols first to ensure deterministic replacement in
809  // typedef_types below as there could be redundant declarations
810  // typedef int x;
811  // typedef int y;
812  std::map<std::string, symbolt> symbols_sorted;
813  for(const auto &symbol_entry : copied_symbol_table.symbols)
814  symbols_sorted.insert(
815  {id2string(symbol_entry.first), symbol_entry.second});
816 
817  for(const auto &symbol_entry : symbols_sorted)
818  {
819  const symbolt &symbol=symbol_entry.second;
820 
821  if(symbol.is_macro && symbol.is_type &&
822  symbol.location.get_function().empty())
823  {
824  const irep_idt &typedef_str=symbol.type.get(ID_C_typedef);
825  PRECONDITION(!typedef_str.empty());
826  typedef_types[symbol.type]=typedef_str;
828  typedef_map.insert({typedef_str, typedef_infot(typedef_str)});
829  else
830  collect_typedefs(symbol.type, false);
831  }
832  }
833 }
834 
837 void dump_ct::dump_typedefs(std::ostream &os) const
838 {
839  // we need to compute a topological sort; we do so by picking all
840  // typedefs the dependencies of which have been emitted into to_insert
841  std::vector<typedef_infot> typedefs_sorted;
842  typedefs_sorted.reserve(typedef_map.size());
843 
844  // elements in to_insert are lexicographically sorted and ready for
845  // output
846  std::map<std::string, typedef_infot> to_insert;
847 
848  std::unordered_set<irep_idt> typedefs_done;
849  std::unordered_map<irep_idt, std::unordered_set<irep_idt>> forward_deps,
850  reverse_deps;
851 
852  for(const auto &td : typedef_map)
853  if(!td.second.type_decl_str.empty())
854  {
855  if(td.second.dependencies.empty())
856  // those can be dumped immediately
857  to_insert.insert({id2string(td.first), td.second});
858  else
859  {
860  // delay them until dependencies are dumped
861  forward_deps.insert({td.first, td.second.dependencies});
862  for(const auto &d : td.second.dependencies)
863  reverse_deps[d].insert(td.first);
864  }
865  }
866 
867  while(!to_insert.empty())
868  {
869  // the topologically next element (lexicographically ranked first
870  // among all the dependencies of which have been dumped)
871  typedef_infot t=to_insert.begin()->second;
872  to_insert.erase(to_insert.begin());
873  // move to the output queue
874  typedefs_sorted.push_back(t);
875 
876  // find any depending typedefs that are now valid, or at least
877  // reduce the remaining dependencies
878  auto r_it=reverse_deps.find(t.typedef_name);
879  if(r_it==reverse_deps.end())
880  continue;
881 
882  // reduce remaining dependencies
883  std::unordered_set<irep_idt> &r_deps = r_it->second;
884  for(std::unordered_set<irep_idt>::iterator it = r_deps.begin();
885  it != r_deps.end();) // no ++it
886  {
887  auto f_it=forward_deps.find(*it);
888  if(f_it==forward_deps.end()) // might be done already
889  {
890  it=r_deps.erase(it);
891  continue;
892  }
893 
894  // update dependencies
895  std::unordered_set<irep_idt> &f_deps = f_it->second;
896  PRECONDITION(!f_deps.empty());
897  PRECONDITION(f_deps.find(t.typedef_name)!=f_deps.end());
898  f_deps.erase(t.typedef_name);
899 
900  if(f_deps.empty()) // all depenencies done now!
901  {
902  const auto td_entry=typedef_map.find(*it);
903  PRECONDITION(td_entry!=typedef_map.end());
904  to_insert.insert({id2string(*it), td_entry->second});
905  forward_deps.erase(*it);
906  it=r_deps.erase(it);
907  }
908  else
909  ++it;
910  }
911  }
912 
913  POSTCONDITION(forward_deps.empty());
914 
915  for(const auto &td : typedefs_sorted)
916  os << td.type_decl_str << '\n';
917 
918  if(!typedefs_sorted.empty())
919  os << '\n';
920 }
921 
923  const symbolt &symbol,
924  std::ostream &os,
925  local_static_declst &local_static_decls)
926 {
927  const irep_idt &func=symbol.location.get_function();
928  if((func.empty() || symbol.is_extern || symbol.value.is_not_nil()) &&
929  !converted_global.insert(symbol.name).second)
930  return;
931 
932  code_frontend_declt d(symbol.symbol_expr());
933 
935 
936  // add a tentative declaration to cater for symbols in the initializer
937  // relying on it this symbol
938  if((func.empty() || symbol.is_extern) &&
939  (symbol.value.is_nil() || !syms.empty()))
940  {
941  os << "// " << symbol.name << '\n';
942  os << "// " << symbol.location << '\n';
943  os << expr_to_string(d) << '\n';
944  }
945 
946  if(!symbol.value.is_nil())
947  {
948  std::set<std::string> symbols_sorted;
949  for(find_symbols_sett::const_iterator
950  it=syms.begin();
951  it!=syms.end();
952  ++it)
953  {
954  bool inserted=symbols_sorted.insert(id2string(*it)).second;
955  CHECK_RETURN(inserted);
956  }
957 
958  for(std::set<std::string>::const_iterator
959  it=symbols_sorted.begin();
960  it!=symbols_sorted.end();
961  ++it)
962  {
963  const symbolt &sym=ns.lookup(*it);
964  if(!sym.is_type && sym.is_static_lifetime && sym.type.id()!=ID_code)
965  convert_global_variable(sym, os, local_static_decls);
966  }
967 
968  d.copy_to_operands(symbol.value);
969  }
970 
971  if(!func.empty() && !symbol.is_extern)
972  {
973  local_static_decls.emplace(symbol.name, d);
974  }
975  else if(!symbol.value.is_nil())
976  {
977  os << "// " << symbol.name << '\n';
978  os << "// " << symbol.location << '\n';
979 
980  std::list<irep_idt> empty_static, empty_types;
981  cleanup_decl(d, empty_static, empty_types);
982  CHECK_RETURN(empty_static.empty());
983  os << expr_to_string(d) << '\n';
984  }
985 }
986 
991 {
993  code_blockt decls;
994 
995  const symbolt *argc_sym=nullptr;
996  if(!ns.lookup("argc'", argc_sym))
997  {
998  symbol_exprt argc("argc", argc_sym->type);
999  replace.insert(argc_sym->symbol_expr(), argc);
1000  code_declt d(argc);
1001  decls.add(d);
1002  }
1003  const symbolt *argv_sym=nullptr;
1004  if(!ns.lookup("argv'", argv_sym))
1005  {
1006  symbol_exprt argv("argv", argv_sym->type);
1007  // replace argc' by argc in the type of argv['] to maintain type consistency
1008  // while replacing
1009  replace(argv);
1010  replace.insert(symbol_exprt(argv_sym->name, argv.type()), argv);
1011  code_declt d(argv);
1012  decls.add(d);
1013  }
1014  const symbolt *return_sym=nullptr;
1015  if(!ns.lookup("return'", return_sym))
1016  {
1017  symbol_exprt return_value("return_value", return_sym->type);
1018  replace.insert(return_sym->symbol_expr(), return_value);
1019  code_declt d(return_value);
1020  decls.add(d);
1021  }
1022 
1023  for(auto &code : b.statements())
1024  {
1025  if(code.get_statement()==ID_function_call)
1026  {
1027  exprt &func=to_code_function_call(code).function();
1028  if(func.id()==ID_symbol)
1029  {
1030  symbol_exprt &s=to_symbol_expr(func);
1031  if(s.get_identifier()==ID_main)
1033  else if(s.get_identifier() == INITIALIZE_FUNCTION)
1034  continue;
1035  }
1036  }
1037 
1038  decls.add(code);
1039  }
1040 
1041  b.swap(decls);
1042  replace(b);
1043 }
1044 
1046  const symbolt &symbol,
1047  const bool skip_main,
1048  std::ostream &os_decl,
1049  std::ostream &os_body,
1050  local_static_declst &local_static_decls)
1051 {
1052  // don't dump artificial main
1053  if(skip_main && symbol.name==goto_functionst::entry_point())
1054  return;
1055 
1056  // convert the goto program back to code - this might change
1057  // the function type
1058  goto_functionst::function_mapt::const_iterator func_entry=
1059  goto_functions.function_map.find(symbol.name);
1060  if(func_entry!=goto_functions.function_map.end() &&
1061  func_entry->second.body_available())
1062  {
1063  code_blockt b;
1064  std::list<irep_idt> type_decls, local_static;
1065 
1066  std::unordered_set<irep_idt> typedef_names;
1067  for(const auto &td : typedef_map)
1068  typedef_names.insert(td.first);
1069 
1070  goto_program2codet p2s(
1071  symbol.name,
1072  func_entry->second.body,
1074  b,
1075  local_static,
1076  type_decls,
1077  typedef_names,
1078  system_headers);
1079  p2s();
1080 
1082  b,
1083  local_static,
1084  local_static_decls,
1085  type_decls);
1086 
1087  convertedt converted_c_bak(converted_compound);
1088  convertedt converted_e_bak(converted_enum);
1089 
1091  enum_constants_bak(declared_enum_constants);
1092 
1094  b,
1095  type_decls);
1096 
1097  converted_enum.swap(converted_e_bak);
1098  converted_compound.swap(converted_c_bak);
1099 
1100  if(harness && symbol.name==goto_functions.entry_point())
1101  cleanup_harness(b);
1102 
1103  os_body << "// " << symbol.name << '\n';
1104  os_body << "// " << symbol.location << '\n';
1105  if(symbol.name==goto_functions.entry_point())
1106  os_body << make_decl(ID_main, symbol.type) << '\n';
1107  else if(!harness || symbol.name!=ID_main)
1108  os_body << make_decl(symbol.name, symbol.type) << '\n';
1109  else if(harness && symbol.name==ID_main)
1110  {
1111  os_body << make_decl(CPROVER_PREFIX+id2string(symbol.name), symbol.type)
1112  << '\n';
1113  }
1114  os_body << expr_to_string(b);
1115  os_body << "\n\n";
1116 
1117  declared_enum_constants.swap(enum_constants_bak);
1118  }
1119 
1120  if(symbol.name!=goto_functionst::entry_point() &&
1121  symbol.name!=ID_main)
1122  {
1123  os_decl << "// " << symbol.name << '\n';
1124  os_decl << "// " << symbol.location << '\n';
1125  os_decl << make_decl(symbol.name, symbol.type) << ";\n";
1126  }
1127  else if(harness && symbol.name==ID_main)
1128  {
1129  os_decl << "// " << symbol.name << '\n';
1130  os_decl << "// " << symbol.location << '\n';
1131  os_decl << make_decl(CPROVER_PREFIX+id2string(symbol.name), symbol.type)
1132  << ";\n";
1133  }
1134 
1135  // make sure typedef names used in the function declaration are
1136  // available
1137  collect_typedefs(symbol.type, true);
1138 }
1139 
1141  const irep_idt &identifier,
1142  codet &root,
1143  code_blockt* &dest,
1144  exprt::operandst::iterator &before)
1145 {
1146  if(!root.has_operands())
1147  return false;
1148 
1149  code_blockt *our_dest=nullptr;
1150 
1151  exprt::operandst &operands=root.operands();
1152  exprt::operandst::iterator first_found=operands.end();
1153 
1154  Forall_expr(it, operands)
1155  {
1156  bool found=false;
1157 
1158  // be aware of the skip-carries-type hack
1159  if(it->id()==ID_code &&
1160  to_code(*it).get_statement()!=ID_skip)
1162  identifier,
1163  to_code(*it),
1164  our_dest,
1165  before);
1166  else
1167  {
1168  find_symbols_sett syms;
1169  find_type_and_expr_symbols(*it, syms);
1170 
1171  found=syms.find(identifier)!=syms.end();
1172  }
1173 
1174  if(!found)
1175  continue;
1176 
1177  if(!our_dest)
1178  {
1179  // first containing block
1180  if(root.get_statement()==ID_block)
1181  {
1182  dest=&(to_code_block(root));
1183  before=it;
1184  }
1185 
1186  return true;
1187  }
1188  else
1189  {
1190  // there is a containing block and this is the first operand
1191  // that contains identifier
1192  if(first_found==operands.end())
1193  first_found=it;
1194  // we have seen it already - pick the first occurrence in this
1195  // block
1196  else if(root.get_statement()==ID_block)
1197  {
1198  dest=&(to_code_block(root));
1199  before=first_found;
1200 
1201  return true;
1202  }
1203  // we have seen it already - outer block has to deal with this
1204  else
1205  return true;
1206  }
1207  }
1208 
1209  if(first_found!=operands.end())
1210  {
1211  dest=our_dest;
1212 
1213  return true;
1214  }
1215 
1216  return false;
1217 }
1218 
1220  code_blockt &b,
1221  const std::list<irep_idt> &local_static,
1222  local_static_declst &local_static_decls,
1223  std::list<irep_idt> &type_decls)
1224 {
1225  // look up last identifier first as its value may introduce the
1226  // other ones
1227  for(std::list<irep_idt>::const_reverse_iterator
1228  it=local_static.rbegin();
1229  it!=local_static.rend();
1230  ++it)
1231  {
1232  local_static_declst::const_iterator d_it=
1233  local_static_decls.find(*it);
1234  PRECONDITION(d_it!=local_static_decls.end());
1235 
1236  code_frontend_declt d = d_it->second;
1237  std::list<irep_idt> redundant;
1238  cleanup_decl(d, redundant, type_decls);
1239 
1240  code_blockt *dest_ptr=nullptr;
1241  exprt::operandst::iterator before=b.operands().end();
1242 
1243  // some use of static variables might be optimised out if it is
1244  // within an if(false) { ... } block
1245  if(find_block_position_rec(*it, b, dest_ptr, before))
1246  {
1247  CHECK_RETURN(dest_ptr!=nullptr);
1248  dest_ptr->operands().insert(before, d);
1249  }
1250  }
1251 }
1252 
1254  code_blockt &b,
1255  const std::list<irep_idt> &type_decls)
1256 {
1257  // look up last identifier first as its value may introduce the
1258  // other ones
1259  for(std::list<irep_idt>::const_reverse_iterator
1260  it=type_decls.rbegin();
1261  it!=type_decls.rend();
1262  ++it)
1263  {
1264  const typet &type=ns.lookup(*it).type;
1265  // feed through plain C to expr2c by ending and re-starting
1266  // a comment block ...
1267  std::ostringstream os_body;
1268  os_body << *it << " */\n";
1269  irep_idt tag_kind =
1270  type.id() == ID_c_enum
1271  ? ID_c_enum_tag
1272  : (type.id() == ID_union ? ID_union_tag : ID_struct_tag);
1273  convert_compound(type, tag_typet(tag_kind, *it), false, os_body);
1274  os_body << "/*";
1275 
1276  code_skipt skip;
1277  skip.add_source_location().set_comment(os_body.str());
1278  // another hack to ensure symbols inside types are seen
1279  skip.type()=type;
1280 
1281  code_blockt *dest_ptr=nullptr;
1282  exprt::operandst::iterator before=b.operands().end();
1283 
1284  // we might not find it in case a transparent union type cast
1285  // has been removed by cleanup operations
1286  if(find_block_position_rec(*it, b, dest_ptr, before))
1287  {
1288  CHECK_RETURN(dest_ptr!=nullptr);
1289  dest_ptr->operands().insert(before, skip);
1290  }
1291  }
1292 }
1293 
1295 {
1296  Forall_operands(it, expr)
1297  cleanup_expr(*it);
1298 
1299  cleanup_type(expr.type());
1300 
1301  if(expr.id()==ID_struct)
1302  {
1303  struct_typet type=
1304  to_struct_type(ns.follow(expr.type()));
1305 
1306  struct_union_typet::componentst old_components;
1307  old_components.swap(type.components());
1308 
1309  exprt::operandst old_ops;
1310  old_ops.swap(expr.operands());
1311 
1312  PRECONDITION(old_components.size()==old_ops.size());
1313  exprt::operandst::iterator o_it=old_ops.begin();
1314  for(const auto &old_comp : old_components)
1315  {
1316  const bool is_zero_bit_field =
1317  old_comp.type().id() == ID_c_bit_field &&
1318  to_c_bit_field_type(old_comp.type()).get_width() == 0;
1319 
1320  if(!old_comp.get_is_padding() && !is_zero_bit_field)
1321  {
1322  type.components().push_back(old_comp);
1323  expr.add_to_operands(std::move(*o_it));
1324  }
1325  ++o_it;
1326  }
1327  expr.type().swap(type);
1328  }
1329  else if(expr.id()==ID_union)
1330  {
1331  union_exprt &u=to_union_expr(expr);
1332  const union_typet &u_type_f=to_union_type(ns.follow(u.type()));
1333 
1334  if(!u.type().get_bool(ID_C_transparent_union) &&
1335  !u_type_f.get_bool(ID_C_transparent_union))
1336  {
1337  if(u_type_f.get_component(u.get_component_name()).get_is_padding())
1338  // we just use an empty struct to fake an empty union
1339  expr = struct_exprt({}, struct_typet());
1340  }
1341  // add a typecast for NULL
1342  else if(
1343  u.op().id() == ID_constant && is_null_pointer(to_constant_expr(u.op())) &&
1344  to_pointer_type(u.op().type()).base_type().id() == ID_empty)
1345  {
1346  const struct_union_typet::componentt &comp=
1347  u_type_f.get_component(u.get_component_name());
1348  const typet &u_op_type=comp.type();
1349  PRECONDITION(u_op_type.id()==ID_pointer);
1350 
1351  typecast_exprt tc(u.op(), u_op_type);
1352  expr.swap(tc);
1353  }
1354  else
1355  {
1356  exprt tmp;
1357  tmp.swap(u.op());
1358  expr.swap(tmp);
1359  }
1360  }
1361  else if(
1362  expr.id() == ID_typecast &&
1363  to_typecast_expr(expr).op().id() == ID_typecast &&
1364  expr.type() == to_typecast_expr(expr).op().type())
1365  {
1366  exprt tmp = to_typecast_expr(expr).op();
1367  expr.swap(tmp);
1368  }
1369  else if(expr.id()==ID_code &&
1370  to_code(expr).get_statement()==ID_function_call &&
1371  to_code_function_call(to_code(expr)).function().id()==ID_symbol)
1372  {
1374  const symbol_exprt &fn=to_symbol_expr(call.function());
1375  code_function_callt::argumentst &arguments=call.arguments();
1376 
1377  // don't edit function calls we might have introduced
1378  const symbolt *s;
1379  if(!ns.lookup(fn.get_identifier(), s))
1380  {
1381  const symbolt &fn_sym=ns.lookup(fn.get_identifier());
1382  const code_typet &code_type=to_code_type(fn_sym.type);
1383  const code_typet::parameterst &parameters=code_type.parameters();
1384 
1385  if(parameters.size()==arguments.size())
1386  {
1387  code_typet::parameterst::const_iterator it=parameters.begin();
1388  for(auto &argument : arguments)
1389  {
1390  const typet &type=ns.follow(it->type());
1391  if(type.id()==ID_union &&
1392  type.get_bool(ID_C_transparent_union))
1393  {
1394  if(argument.id() == ID_typecast && argument.type() == type)
1395  argument = to_typecast_expr(argument).op();
1396 
1397  // add a typecast for NULL or 0
1398  if(
1399  argument.id() == ID_constant &&
1400  is_null_pointer(to_constant_expr(argument)))
1401  {
1402  const typet &comp_type=
1403  to_union_type(type).components().front().type();
1404 
1405  if(comp_type.id()==ID_pointer)
1406  argument = typecast_exprt(argument, comp_type);
1407  }
1408  }
1409 
1410  ++it;
1411  }
1412  }
1413  }
1414  }
1415  else if(expr.id()==ID_constant &&
1416  expr.type().id()==ID_signedbv)
1417  {
1418  #if 0
1419  const irep_idt &cformat=expr.get(ID_C_cformat);
1420 
1421  if(!cformat.empty())
1422  {
1423  declared_enum_constants_mapt::const_iterator entry=
1424  declared_enum_constants.find(cformat);
1425 
1426  if(entry!=declared_enum_constants.end() &&
1427  entry->first!=entry->second)
1428  expr.set(ID_C_cformat, entry->second);
1429  else if(entry==declared_enum_constants.end() &&
1430  !std::isdigit(id2string(cformat)[0]))
1431  expr.remove(ID_C_cformat);
1432  }
1433  #endif
1434  }
1435  else if(
1436  expr.id() == ID_byte_update_little_endian ||
1437  expr.id() == ID_byte_update_big_endian)
1438  {
1439  const byte_update_exprt &bu = to_byte_update_expr(expr);
1440 
1441  if(bu.op().id() == ID_union && bu.offset().is_zero())
1442  {
1443  const union_exprt &union_expr = to_union_expr(bu.op());
1444  const union_typet &union_type =
1445  to_union_type(ns.follow(union_expr.type()));
1446 
1447  for(const auto &comp : union_type.components())
1448  {
1449  if(bu.value().type() == comp.type())
1450  {
1451  exprt member1{ID_member};
1452  member1.set(ID_component_name, union_expr.get_component_name());
1453  exprt designated_initializer1{ID_designated_initializer};
1454  designated_initializer1.add_to_operands(union_expr.op());
1455  designated_initializer1.add(ID_designator).move_to_sub(member1);
1456 
1457  exprt member2{ID_member};
1458  member2.set(ID_component_name, comp.get_name());
1459  exprt designated_initializer2{ID_designated_initializer};
1460  designated_initializer2.add_to_operands(bu.value());
1461  designated_initializer2.add(ID_designator).move_to_sub(member2);
1462 
1463  binary_exprt initializer_list{std::move(designated_initializer1),
1464  ID_initializer_list,
1465  std::move(designated_initializer2)};
1466  expr.swap(initializer_list);
1467 
1468  return;
1469  }
1470  }
1471  }
1472  else if(
1473  bu.op().id() == ID_side_effect &&
1474  to_side_effect_expr(bu.op()).get_statement() == ID_nondet &&
1475  ns.follow(bu.op().type()).id() == ID_union && bu.offset().is_zero())
1476  {
1477  const union_typet &union_type = to_union_type(ns.follow(bu.op().type()));
1478 
1479  for(const auto &comp : union_type.components())
1480  {
1481  if(bu.value().type() == comp.type())
1482  {
1483  union_exprt union_expr{comp.get_name(), bu.value(), bu.op().type()};
1484  expr.swap(union_expr);
1485 
1486  return;
1487  }
1488  }
1489  }
1490 
1491  optionalt<exprt> clean_init;
1492  if(
1493  ns.follow(bu.type()).id() == ID_union &&
1495  {
1496  clean_init = zero_initializer(bu.op().type(), source_locationt{}, ns)
1497  .value_or(nil_exprt{});
1498  if(clean_init->id() != ID_struct || clean_init->has_operands())
1499  cleanup_expr(*clean_init);
1500  }
1501 
1502  if(clean_init.has_value() && bu.op() == *clean_init)
1503  {
1504  const union_typet &union_type = to_union_type(ns.follow(bu.type()));
1505 
1506  for(const auto &comp : union_type.components())
1507  {
1508  if(bu.value().type() == comp.type())
1509  {
1510  union_exprt union_expr{comp.get_name(), bu.value(), bu.type()};
1511  expr.swap(union_expr);
1512 
1513  return;
1514  }
1515  }
1516 
1517  // we still haven't found a suitable component, so just ignore types and
1518  // build an initializer list without designators
1519  expr = unary_exprt{ID_initializer_list, bu.value()};
1520  }
1521  }
1522 }
1523 
1525 {
1526  for(typet &subtype : to_type_with_subtypes(type).subtypes())
1527  cleanup_type(subtype);
1528 
1529  if(type.id()==ID_code)
1530  {
1531  code_typet &code_type=to_code_type(type);
1532 
1533  cleanup_type(code_type.return_type());
1534 
1535  for(code_typet::parameterst::iterator
1536  it=code_type.parameters().begin();
1537  it!=code_type.parameters().end();
1538  ++it)
1539  cleanup_type(it->type());
1540  }
1541 
1542  if(type.id()==ID_array)
1543  cleanup_expr(to_array_type(type).size());
1544 }
1545 
1547 {
1548  // future TODO: with C++20 we can actually use designated initializers as
1549  // commented out below
1550  static expr2c_configurationt configuration{
1551  /* .include_struct_padding_components = */ true,
1552  /* .print_struct_body_in_type = */ true,
1553  /* .include_array_size = */ true,
1554  /* .true_string = */ "1",
1555  /* .false_string = */ "0",
1556  /* .use_library_macros = */ true,
1557  /* .print_enum_int_value = */ false,
1558  /* .expand_typedef = */ false};
1559 
1560  return configuration;
1561 }
1562 
1563 std::string dump_ct::type_to_string(const typet &type)
1564 {
1565  std::string ret;
1566  typet t=type;
1567  cleanup_type(t);
1568 
1569  if(mode == ID_C)
1570  return type2c(t, ns, expr2c_configuration());
1571  else if(mode == ID_cpp)
1572  return type2cpp(t, ns);
1573  else
1574  UNREACHABLE;
1575 }
1576 
1577 std::string dump_ct::expr_to_string(const exprt &expr)
1578 {
1579  std::string ret;
1580  exprt e=expr;
1581  cleanup_expr(e);
1582 
1583  if(mode == ID_C)
1584  return expr2c(e, ns, expr2c_configuration());
1585  else if(mode == ID_cpp)
1586  return expr2cpp(e, ns);
1587  else
1588  UNREACHABLE;
1589 }
1590 
1591 void dump_c(
1592  const goto_functionst &src,
1593  const bool use_system_headers,
1594  const bool use_all_headers,
1595  const bool include_harness,
1596  const namespacet &ns,
1597  std::ostream &out)
1598 {
1599  dump_ct goto2c(
1600  src, use_system_headers, use_all_headers, include_harness, ns, ID_C);
1601  out << goto2c;
1602 }
1603 
1605  const goto_functionst &src,
1606  const bool use_system_headers,
1607  const bool use_all_headers,
1608  const bool include_harness,
1609  const namespacet &ns,
1610  std::ostream &out)
1611 {
1612  dump_ct goto2cpp(
1613  src, use_system_headers, use_all_headers, include_harness, ns, ID_cpp);
1614  out << goto2cpp;
1615 }
1616 
1617 static bool
1618 module_local_declaration(const symbolt &symbol, const std::string module)
1619 {
1620  std::string base_name =
1621  get_base_name(id2string(symbol.location.get_file()), true);
1622  std::string symbol_module = strip_string(id2string(symbol.module));
1623  return (base_name == module && symbol_module == module);
1624 }
1625 
1627  const goto_functionst &src,
1628  const bool use_system_headers,
1629  const bool use_all_headers,
1630  const bool include_harness,
1631  const namespacet &ns,
1632  const std::string module,
1633  std::ostream &out)
1634 {
1637  it != symbol_table.end();
1638  it++)
1639  {
1640  symbolt &new_symbol = it.get_writeable_symbol();
1641  if(module_local_declaration(new_symbol, module))
1642  {
1643  new_symbol.type.set(ID_C_do_not_dump, 0);
1644  }
1645  else
1646  {
1647  new_symbol.type.set(ID_C_do_not_dump, 1);
1648  }
1649  }
1650 
1651  namespacet new_ns(symbol_table);
1652  dump_ct goto2c(
1653  src,
1654  use_system_headers,
1655  use_all_headers,
1656  include_harness,
1657  new_ns,
1658  ID_C,
1660  out << goto2c;
1661 }
code_frontend_declt::initial_value
optionalt< exprt > initial_value() const
Returns the initial value to which the declared variable is initialized, or empty in the case where n...
Definition: std_code.h:373
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
exprt::copy_to_operands
void copy_to_operands(const exprt &expr)
Copy the given argument to the end of exprt's operands.
Definition: expr.h:155
tag_typet::get_identifier
const irep_idt & get_identifier() const
Definition: std_types.h:410
dump_ct::declared_enum_constants_mapt
std::unordered_map< irep_idt, irep_idt > declared_enum_constants_mapt
Definition: dump_c_class.h:170
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
symbol_table_baset::has_symbol
bool has_symbol(const irep_idt &name) const
Check whether a symbol exists in the symbol table.
Definition: symbol_table_base.h:87
dstringt
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:36
code_frontend_declt::set_initial_value
void set_initial_value(optionalt< exprt > initial_value)
Sets the value to which this declaration initializes the declared variable.
Definition: std_code.h:384
to_union_type
const union_typet & to_union_type(const typet &type)
Cast a typet to a union_typet.
Definition: c_types.h:162
source_locationt::get_function
const irep_idt & get_function() const
Definition: source_location.h:55
to_unsignedbv_type
const unsignedbv_typet & to_unsignedbv_type(const typet &type)
Cast a typet to an unsignedbv_typet.
Definition: bitvector_types.h:191
get_base_name
std::string get_base_name(const std::string &in, bool strip_suffix)
cleans a filename from path and extension
Definition: get_base_name.cpp:16
code_blockt
A codet representing sequential composition of program statements.
Definition: std_code.h:129
dump_ct::collect_typedefs_rec
void collect_typedefs_rec(const typet &type, bool early, std::unordered_set< irep_idt > &dependencies)
Find any typedef names contained in the input type and store their declaration strings in typedef_map...
Definition: dump_c.cpp:731
Forall_expr
#define Forall_expr(it, expr)
Definition: expr.h:36
dump_c_configurationt::enable_include_headers
dump_c_configurationt enable_include_headers()
Definition: dump_c_class.h:104
symbol_tablet
The symbol table.
Definition: symbol_table.h:13
tag_typet::set_identifier
void set_identifier(const irep_idt &identifier)
Definition: std_types.h:405
to_code_function_call
const code_function_callt & to_code_function_call(const goto_instruction_codet &code)
Definition: goto_instruction_code.h:385
c_enum_typet
The type of C enums.
Definition: c_types.h:216
dump_c_configurationt::disable_include_global_vars
dump_c_configurationt disable_include_global_vars()
Definition: dump_c_class.h:86
dump_ct::indent
static std::string indent(const unsigned n)
Definition: dump_c_class.h:194
dump_ct::goto_functions
const goto_functionst & goto_functions
Definition: dump_c_class.h:156
source_locationt::set_comment
void set_comment(const irep_idt &comment)
Definition: source_location.h:135
dump_c_configurationt::default_configuration
static dump_c_configurationt default_configuration
The default used for dump-c and dump-cpp.
Definition: dump_c_class.h:57
find_type_and_expr_symbols
void find_type_and_expr_symbols(const exprt &src, find_symbols_sett &dest)
Find identifiers of the sub expressions with id ID_symbol, considering both free and bound variables,...
Definition: find_symbols.cpp:283
byte_update_exprt
Expression corresponding to op() where the bytes starting at position offset (given in number of byte...
Definition: byte_operators.h:77
Forall_operands
#define Forall_operands(it, expr)
Definition: expr.h:27
symbolt::is_macro
bool is_macro
Definition: symbol.h:61
dump_ct::ns
const namespacet ns
Definition: dump_c_class.h:158
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
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
CHECK_RETURN
#define CHECK_RETURN(CONDITION)
Definition: invariant.h:495
string_utils.h
typet
The type of an expression, extends irept.
Definition: type.h:28
code_typet::parameterst
std::vector< parametert > parameterst
Definition: std_types.h:541
irept::find
const irept & find(const irep_idt &name) const
Definition: irep.cpp:106
dump_c_configurationt
Used for configuring the behaviour of dump_c.
Definition: dump_c_class.h:26
struct_union_typet
Base type for structs and unions.
Definition: std_types.h:61
symbolt::type
typet type
Type of symbol.
Definition: symbol.h:31
find_non_pointer_type_symbols
void find_non_pointer_type_symbols(const exprt &src, find_symbols_sett &dest)
Collect type tags contained in src when the expression of such a type is not a pointer,...
Definition: find_symbols.cpp:261
byte_update_exprt::offset
const exprt & offset() const
Definition: byte_operators.h:106
c_enum_typet::memberst
std::vector< c_enum_membert > memberst
Definition: c_types.h:253
replace_symbol.h
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
prefix.h
replace
void replace(const union_find_replacet &replace_map, string_not_contains_constraintt &constraint)
Definition: string_constraint.cpp:70
goto_programt::update
void update()
Update all indices.
Definition: goto_program.cpp:617
configt::main
optionalt< std::string > main
Definition: config.h:341
invariant.h
dump_c_configurationt::follow_compounds
bool follow_compounds
Define whether to follow compunds recursively.
Definition: dump_c_class.h:47
code_declt
A goto_instruction_codet representing the declaration of a local variable.
Definition: goto_instruction_code.h:204
union_exprt
Union constructor from single element.
Definition: std_expr.h:1707
goto_programt::make_end_function
static instructiont make_end_function(const source_locationt &l=source_locationt::nil())
Definition: goto_program.h:992
goto_programt::add
targett add(instructiont &&instruction)
Adds a given instruction at the end.
Definition: goto_program.h:709
to_type_with_subtype
const type_with_subtypet & to_type_with_subtype(const typet &type)
Definition: type.h:193
to_type_with_subtypes
const type_with_subtypest & to_type_with_subtypes(const typet &type)
Definition: type.h:237
dump_ct::convert_function_declaration
void convert_function_declaration(const symbolt &symbol, const bool skip_main, std::ostream &os_decl, std::ostream &os_body, local_static_declst &local_static_decls)
Definition: dump_c.cpp:1045
code_frontend_declt
A codet representing the declaration of a local variable.
Definition: std_code.h:346
dump_ct::system_symbols
system_library_symbolst system_symbols
Definition: dump_c_class.h:168
exprt
Base class for all expressions.
Definition: expr.h:55
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
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
expr2cpp.h
dump_ct::convert_compound
void convert_compound(const typet &type, const typet &unresolved, bool recursive, std::ostream &os)
Definition: dump_c.cpp:375
irep_idt
dstringt irep_idt
Definition: irep.h:37
to_string
std::string to_string(const string_not_contains_constraintt &expr)
Used for debug printing.
Definition: string_constraint.cpp:58
find_block_position_rec
static bool find_block_position_rec(const irep_idt &identifier, codet &root, code_blockt *&dest, exprt::operandst::iterator &before)
Definition: dump_c.cpp:1140
expr2cpp
std::string expr2cpp(const exprt &expr, const namespacet &ns)
Definition: expr2cpp.cpp:495
to_side_effect_expr
side_effect_exprt & to_side_effect_expr(exprt &expr)
Definition: std_code.h:1506
configt::ansi_c
struct configt::ansi_ct ansi_c
dump_c_configurationt::disable_include_function_bodies
dump_c_configurationt disable_include_function_bodies()
Definition: dump_c_class.h:68
expr2c_configuration
static expr2c_configurationt expr2c_configuration()
Definition: dump_c.cpp:1546
goto_functionst::function_map
function_mapt function_map
Definition: goto_functions.h:29
dump_ct::typedef_map
typedef_mapt typedef_map
Definition: dump_c_class.h:187
symbol_exprt
Expression to hold a symbol (variable)
Definition: std_expr.h:112
goto_programt::make_decl
static instructiont make_decl(const symbol_exprt &symbol, const source_locationt &l=source_locationt::nil())
Definition: goto_program.h:955
dump_ct::insert_local_type_decls
void insert_local_type_decls(code_blockt &b, const std::list< irep_idt > &type_decls)
Definition: dump_c.cpp:1253
dump_ct::expr_to_string
std::string expr_to_string(const exprt &expr)
Definition: dump_c.cpp:1577
dump_ct::converted_compound
convertedt converted_compound
Definition: dump_c_class.h:164
goto_programt::make_assignment
static instructiont make_assignment(const code_assignt &_code, const source_locationt &l=source_locationt::nil())
Create an assignment instruction.
Definition: goto_program.h:1056
zero_initializer
optionalt< exprt > zero_initializer(const typet &type, const source_locationt &source_location, const namespacet &ns)
Create the equivalent of zero for type type.
Definition: expr_initializer.cpp:297
symbol_tablet::begin
virtual iteratort begin() override
Definition: symbol_table.h:108
union_tag_typet
A union tag type, i.e., union_typet with an identifier.
Definition: c_types.h:176
dump_ct::harness
const bool harness
Definition: dump_c_class.h:161
unsignedbv_typet
Fixed-width bit-vector with unsigned binary interpretation.
Definition: bitvector_types.h:158
dump_ct::system_headers
std::set< std::string > system_headers
Definition: dump_c_class.h:166
irept::get
const irep_idt & get(const irep_idt &name) const
Definition: irep.cpp:45
dump_ct::make_decl
std::string make_decl(const irep_idt &identifier, const typet &type)
Definition: dump_c_class.h:199
struct_exprt
Struct constructor from list of elements.
Definition: std_expr.h:1818
dump_ct::dump_typedefs
void dump_typedefs(std::ostream &os) const
Print all typedefs that are not covered via typedef struct xyz { ...
Definition: dump_c.cpp:837
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
exprt::type
typet & type()
Return the type of the expression.
Definition: expr.h:84
namespacet::lookup
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
Definition: namespace.cpp:138
dump_ct::declared_enum_constants
declared_enum_constants_mapt declared_enum_constants
Definition: dump_c_class.h:171
code_function_callt
goto_instruction_codet representation of a function call statement.
Definition: goto_instruction_code.h:271
irept::is_not_nil
bool is_not_nil() const
Definition: irep.h:380
dump_c_configurationt::include_typedefs
bool include_typedefs
Include the typedefs in the dump.
Definition: dump_c_class.h:38
operator<<
std::ostream & operator<<(std::ostream &out, dump_ct &src)
Definition: dump_c.cpp:43
strip_string
std::string strip_string(const std::string &s)
Remove all whitespace characters from either end of a string.
Definition: string_utils.cpp:21
dump_ct::converted_global
convertedt converted_global
Definition: dump_c_class.h:164
byte_operators.h
Expression classes for byte-level operators.
to_code_type
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
Definition: std_types.h:744
expr_initializer.h
find_symbols.h
dump_ct::cleanup_type
void cleanup_type(typet &type)
Definition: dump_c.cpp:1524
to_tag_type
const tag_typet & to_tag_type(const typet &type)
Cast a typet to a tag_typet.
Definition: std_types.h:434
has_prefix
bool has_prefix(const std::string &s, const std::string &prefix)
Definition: converter.cpp:13
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
symbol_tablet::end
virtual iteratort end() override
Definition: symbol_table.h:112
symbol_table_baset::get_writeable_ref
symbolt & get_writeable_ref(const irep_idt &name)
Find a symbol in the symbol table for read-write access.
Definition: symbol_table_base.h:121
id2string
const std::string & id2string(const irep_idt &d)
Definition: irep.h:47
dump_ct::convert_compound_enum
void convert_compound_enum(const typet &type, std::ostream &os)
Definition: dump_c.cpp:631
dump_ct::cleanup_expr
void cleanup_expr(exprt &expr)
Definition: dump_c.cpp:1294
get_identifier
static optionalt< smt_termt > get_identifier(const exprt &expr, const std::unordered_map< exprt, smt_identifier_termt, irep_hash > &expression_handle_identifiers, const std::unordered_map< exprt, smt_identifier_termt, irep_hash > &expression_identifiers)
Definition: smt2_incremental_decision_procedure.cpp:328
to_byte_update_expr
const byte_update_exprt & to_byte_update_expr(const exprt &expr)
Definition: byte_operators.h:117
type2cpp
std::string type2cpp(const typet &type, const namespacet &ns)
Definition: expr2cpp.cpp:502
irept::set
void set(const irep_idt &name, const irep_idt &value)
Definition: irep.h:420
expr2c.h
dump_c
void dump_c(const goto_functionst &src, const bool use_system_headers, const bool use_all_headers, const bool include_harness, const namespacet &ns, std::ostream &out)
Definition: dump_c.cpp:1591
expr2c
std::string expr2c(const exprt &expr, const namespacet &ns, const expr2c_configurationt &configuration)
Definition: expr2c.cpp:4046
PRECONDITION
#define PRECONDITION(CONDITION)
Definition: invariant.h:463
typet::source_location
const source_locationt & source_location() const
Definition: type.h:90
symbol_exprt::get_identifier
const irep_idt & get_identifier() const
Definition: std_expr.h:142
nil_exprt
The NIL expression.
Definition: std_expr.h:3025
struct_union_typet::componentt::get_is_padding
bool get_is_padding() const
Definition: std_types.h:129
signedbv_typet
Fixed-width bit-vector with two's complement interpretation.
Definition: bitvector_types.h:207
dump_ct::convertedt
std::unordered_set< irep_idt > convertedt
Definition: dump_c_class.h:163
symbolt::symbol_expr
class symbol_exprt symbol_expr() const
Produces a symbol_exprt for a symbol.
Definition: symbol.cpp:121
module_local_declaration
static bool module_local_declaration(const symbolt &symbol, const std::string module)
Definition: dump_c.cpp:1618
INITIALIZE_FUNCTION
#define INITIALIZE_FUNCTION
Definition: static_lifetime_init.h:22
dump_c_type_header
void dump_c_type_header(const goto_functionst &src, const bool use_system_headers, const bool use_all_headers, const bool include_harness, const namespacet &ns, const std::string module, std::ostream &out)
Definition: dump_c.cpp:1626
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
goto_program2code.h
irept::swap
void swap(irept &irep)
Definition: irep.h:442
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
irept::is_nil
bool is_nil() const
Definition: irep.h:376
irept::id
const irep_idt & id() const
Definition: irep.h:396
dump_ct::insert_local_static_decls
void insert_local_static_decls(code_blockt &b, const std::list< irep_idt > &local_static, local_static_declst &local_static_decls, std::list< irep_idt > &type_decls)
Definition: dump_c.cpp:1219
exprt::operandst
std::vector< exprt > operandst
Definition: expr.h:58
code_function_callt::argumentst
exprt::operandst argumentst
Definition: goto_instruction_code.h:281
dstringt::empty
bool empty() const
Definition: dstring.h:88
get_base_name.h
dump_c_configurationt::include_compounds
bool include_compounds
Include struct definitions in the dump.
Definition: dump_c_class.h:44
dump_ct::operator()
void operator()(std::ostream &out)
Definition: dump_c.cpp:49
code_blockt::add
void add(const codet &code)
Definition: std_code.h:168
union_typet
The union type.
Definition: c_types.h:124
tag_typet
A tag-based type, i.e., typet with an identifier.
Definition: std_types.h:395
unary_exprt::op
const exprt & op() const
Definition: std_expr.h:326
dump_c_configurationt::include_headers
bool include_headers
Include headers type declarations are borrowed from.
Definition: dump_c_class.h:50
code_typet::parameters
const parameterst & parameters() const
Definition: std_types.h:655
dump_c_configurationt::include_function_decls
bool include_function_decls
Include the function declarations in the dump.
Definition: dump_c_class.h:29
code_function_callt::arguments
argumentst & arguments()
Definition: goto_instruction_code.h:317
optionalt
nonstd::optional< T > optionalt
Definition: optional.h:35
side_effect_exprt::get_statement
const irep_idt & get_statement() const
Definition: std_code.h:1472
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
source_locationt
Definition: source_location.h:18
bitvector_typet::get_width
std::size_t get_width() const
Definition: std_types.h:876
union_exprt::get_component_name
irep_idt get_component_name() const
Definition: std_expr.h:1716
exprt::is_zero
bool is_zero() const
Return whether the expression is a constant representing 0.
Definition: expr.cpp:65
symbol_table_baset::add
bool add(const symbolt &symbol)
Add a new symbol to the symbol table.
Definition: symbol_table_base.cpp:18
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
expr_util.h
Deprecated expression utility functions.
goto_functionst
A collection of goto functions.
Definition: goto_functions.h:24
dump_ct::mode
const irep_idt mode
Definition: dump_c_class.h:160
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
symbolt::value
exprt value
Initial value of symbol.
Definition: symbol.h:34
dump_c_configurationt::include_global_decls
bool include_global_decls
Include the global declarations in the dump.
Definition: dump_c_class.h:35
POSTCONDITION
#define POSTCONDITION(CONDITION)
Definition: invariant.h:479
namespacet::get_symbol_table
const symbol_table_baset & get_symbol_table() const
Return first symbol table registered with the namespace.
Definition: namespace.h:123
struct_typet
Structure type, corresponds to C style structs.
Definition: std_types.h:230
byte_update_exprt::value
const exprt & value() const
Definition: byte_operators.h:107
irept::add
irept & add(const irep_idt &name)
Definition: irep.cpp:116
c_enum_tag_typet
C enum tag type, i.e., c_enum_typet with an identifier.
Definition: c_types.h:318
code_skipt
A codet representing a skip statement.
Definition: std_code.h:321
symbolt::is_extern
bool is_extern
Definition: symbol.h:66
find_symbols_sett
std::unordered_set< irep_idt > find_symbols_sett
Definition: find_symbols.h:21
dump_c_configurationt::disable_include_function_decls
dump_c_configurationt disable_include_function_decls()
Definition: dump_c_class.h:62
dump_c_configurationt::include_global_vars
bool include_global_vars
Include global variable definitions in the dump.
Definition: dump_c_class.h:41
namespace_baset::follow
const typet & follow(const typet &) const
Resolve type symbol to the type it points to.
Definition: namespace.cpp:49
symbol_table_baset::iteratort
Definition: symbol_table_base.h:154
symbolt::location
source_locationt location
Source code location of definition of symbol.
Definition: symbol.h:37
dump_c_configurationt::include_function_bodies
bool include_function_bodies
Include the functions in the dump.
Definition: dump_c_class.h:32
dump_ct::typedef_infot::typedef_name
irep_idt typedef_name
Definition: dump_c_class.h:175
dump_c_class.h
symbolt
Symbol table entry.
Definition: symbol.h:27
dump_ct::copied_symbol_table
symbol_tablet copied_symbol_table
Definition: dump_c_class.h:157
to_typecast_expr
const typecast_exprt & to_typecast_expr(const exprt &expr)
Cast an exprt to a typecast_exprt.
Definition: std_expr.h:2051
dump_ct::typedef_infot
Definition: dump_c_class.h:173
symbol_table_baset::symbols
const symbolst & symbols
Read-only field, used to look up symbols given their names.
Definition: symbol_table_base.h:30
dump_ct::typedef_types
typedef_typest typedef_types
Definition: dump_c_class.h:189
symbolt::is_type
bool is_type
Definition: symbol.h:61
dump_ct::cleanup_harness
void cleanup_harness(code_blockt &b)
Replace CPROVER internal symbols in b by printable values and generate necessary declarations.
Definition: dump_c.cpp:990
goto_program2codet
Definition: goto_program2code.h:22
dump_ct::local_static_declst
std::unordered_map< irep_idt, code_frontend_declt > local_static_declst
Definition: dump_c_class.h:238
pointer_typet::base_type
const typet & base_type() const
The type of the data what we point to.
Definition: pointer_expr.h:35
CPROVER_PREFIX
#define CPROVER_PREFIX
Definition: cprover_prefix.h:14
irept::get_sub
subt & get_sub()
Definition: irep.h:456
to_array_type
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
Definition: std_types.h:844
exprt::add_to_operands
void add_to_operands(const exprt &expr)
Add the given argument to the end of exprt's operands.
Definition: expr.h:162
symbolt::is_static_lifetime
bool is_static_lifetime
Definition: symbol.h:65
goto_programt
A generic container class for the GOTO intermediate representation of one function.
Definition: goto_program.h:72
config.h
dump_ct::cleanup_decl
void cleanup_decl(code_frontend_declt &decl, std::list< irep_idt > &local_static, std::list< irep_idt > &local_type_decls)
Definition: dump_c.cpp:674
dump_ct::convert_compound_declaration
void convert_compound_declaration(const symbolt &symbol, std::ostream &os_body)
declare compound types
Definition: dump_c.cpp:343
source_locationt::get_file
const irep_idt & get_file() const
Definition: source_location.h:35
system_library_symbolst::is_symbol_internal_symbol
bool is_symbol_internal_symbol(const symbolt &symbol, std::set< std::string > &out_system_headers) const
To find out if a symbol is an internal symbol.
Definition: system_library_symbols.cpp:261
code_typet::return_type
const typet & return_type() const
Definition: std_types.h:645
to_code_block
const code_blockt & to_code_block(const codet &code)
Definition: std_code.h:203
irept
There are a large number of kinds of tree structured or tree-like data in CPROVER.
Definition: irep.h:359
dump_ct::dump_c_config
const dump_c_configurationt dump_c_config
Definition: dump_c_class.h:159
dump_c_configurationt::type_header_configuration
static dump_c_configurationt type_header_configuration
The config used for dump-c-type-header.
Definition: dump_c_class.h:60
dump_ct::convert_global_variable
void convert_global_variable(const symbolt &symbol, std::ostream &os, local_static_declst &local_static_decls)
Definition: dump_c.cpp:922
exprt::operands
operandst & operands()
Definition: expr.h:94
type2c
std::string type2c(const typet &type, const namespacet &ns, const expr2c_configurationt &configuration)
Definition: expr2c.cpp:4062
goto_functionst::entry_point
static irep_idt entry_point()
Get the identifier of the entry point to a goto model.
Definition: goto_functions.h:92
dump_ct::collect_typedefs
void collect_typedefs(const typet &type, bool early)
Find any typedef names contained in the input type and store their declaration strings in typedef_map...
Definition: dump_c.cpp:718
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
irept::remove
void remove(const irep_idt &name)
Definition: irep.cpp:96
static_lifetime_init.h
exprt::add_source_location
source_locationt & add_source_location()
Definition: expr.h:216
expr2c_configurationt
Used for configuring the behaviour of expr2c and type2c.
Definition: expr2c.h:20
typecast_exprt
Semantic type conversion.
Definition: std_expr.h:2016
size_type
unsignedbv_typet size_type()
Definition: c_types.cpp:68
codet::get_statement
const irep_idt & get_statement() const
Definition: std_code_base.h:65
symbolt::module
irep_idt module
Name of module the symbol belongs to.
Definition: symbol.h:43
code_frontend_declt::symbol
symbol_exprt & symbol()
Definition: std_code.h:354
dump_c.h
dump_ct
Definition: dump_c_class.h:111
exprt::source_location
const source_locationt & source_location() const
Definition: expr.h:211
byte_update_exprt::op
const exprt & op() const
Definition: byte_operators.h:105
goto_modelt::symbol_table
symbol_tablet symbol_table
Symbol table.
Definition: goto_model.h:30
can_cast_type< tag_typet >
bool can_cast_type< tag_typet >(const typet &type)
Check whether a reference to a typet is a tag_typet.
Definition: std_types.h:420
c_types.h
symbol_exprt::set_identifier
void set_identifier(const irep_idt &identifier)
Definition: std_expr.h:137
symbolt::name
irep_idt name
The unique identifier.
Definition: symbol.h:40
dump_cpp
void dump_cpp(const goto_functionst &src, const bool use_system_headers, const bool use_all_headers, const bool include_harness, const namespacet &ns, std::ostream &out)
Definition: dump_c.cpp:1604
irept::get_bool
bool get_bool(const irep_idt &name) const
Definition: irep.cpp:58
dump_ct::type_to_string
std::string type_to_string(const typet &type)
Definition: dump_c.cpp:1563
code_function_callt::function
exprt & function()
Definition: goto_instruction_code.h:307
dump_ct::converted_enum
convertedt converted_enum
Definition: dump_c_class.h:164
dump_ct::gather_global_typedefs
void gather_global_typedefs()
Find all global typdefs in the symbol table and store them in typedef_types.
Definition: dump_c.cpp:806
replace_symbolt
Replace a symbol expression by a given expression.
Definition: replace_symbol.h:27
array_typet::element_type
const typet & element_type() const
The type of the elements of the array.
Definition: std_types.h:785
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