cprover
cpp_typecheck_compound_type.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: C++ Language Type Checking
4 
5 Author: Daniel Kroening, kroening@cs.cmu.edu
6 
7 \*******************************************************************/
8 
11 
12 #include "cpp_typecheck.h"
13 
14 #ifdef DEBUG
15 #include <iostream>
16 #endif
17 
18 #include <algorithm>
19 
20 #include <util/arith_tools.h>
21 #include <util/simplify_expr.h>
22 #include <util/std_types.h>
23 #include <util/c_types.h>
24 
25 #include <ansi-c/c_qualifiers.h>
26 
27 #include "cpp_type2name.h"
29 #include "cpp_convert_type.h"
30 #include "cpp_name.h"
31 
33 {
34  if(type.id()==ID_const)
35  return true;
36  else if(type.id()==ID_merged_type)
37  {
38  forall_subtypes(it, type)
39  if(has_const(*it))
40  return true;
41 
42  return false;
43  }
44  else
45  return false;
46 }
47 
49 {
50  if(type.id()==ID_volatile)
51  return true;
52  else if(type.id()==ID_merged_type)
53  {
54  forall_subtypes(it, type)
55  if(has_volatile(*it))
56  return true;
57 
58  return false;
59  }
60  else
61  return false;
62 }
63 
65 {
66  if(type.id() == ID_auto)
67  return true;
68  else if(
69  type.id() == ID_merged_type || type.id() == ID_frontend_pointer ||
70  type.id() == ID_pointer)
71  {
72  forall_subtypes(it, type)
73  if(has_auto(*it))
74  return true;
75 
76  return false;
77  }
78  else
79  return false;
80 }
81 
83  const irep_idt &base_name,
84  bool has_body,
85  bool tag_only_declaration)
86 {
87  // The scope of a compound identifier is difficult,
88  // and is different from C.
89  //
90  // For instance:
91  // class A { class B {} } --> A::B
92  // class A { class B; } --> A::B
93  // class A { class B *p; } --> ::B
94  // class B { }; class A { class B *p; } --> ::B
95  // class B { }; class A { class B; class B *p; } --> A::B
96 
97  // If there is a body, or it's a tag-only declaration,
98  // it's always in the current scope, even if we already have
99  // it in an upwards scope.
100 
101  if(has_body || tag_only_declaration)
102  return cpp_scopes.current_scope();
103 
104  // No body. Not a tag-only-declaration.
105  // Check if we have it already. If so, take it.
106 
107  // we should only look for tags, but we don't
108  const auto id_set =
110 
111  for(const auto &id : id_set)
112  if(id->is_class())
113  return static_cast<cpp_scopet &>(id->get_parent());
114 
115  // Tags without body that we don't have already
116  // and that are not a tag-only declaration go into
117  // the global scope of the namespace.
118  return cpp_scopes.get_global_scope();
119 }
120 
122  struct_union_typet &type)
123 {
124  // first save qualifiers
125  c_qualifierst qualifiers(type);
126 
127  // now clear them from the type
128  type.remove(ID_C_constant);
129  type.remove(ID_C_volatile);
130  type.remove(ID_C_restricted);
131 
132  // get the tag name
133  bool has_tag=type.find(ID_tag).is_not_nil();
134  irep_idt base_name;
135  cpp_scopet *dest_scope=nullptr;
136  bool has_body=type.find(ID_body).is_not_nil();
137  bool tag_only_declaration=type.get_bool(ID_C_tag_only_declaration);
138  bool is_union = type.id() == ID_union;
139 
140  if(!has_tag)
141  {
142  // most of these should be named by now; see
143  // cpp_declarationt::name_anon_struct_union()
144 
145  base_name=std::string("#anon_")+std::to_string(++anon_counter);
146  type.set(ID_C_is_anonymous, true);
147  dest_scope=&cpp_scopes.current_scope();
148  }
149  else
150  {
151  const cpp_namet &cpp_name=
152  to_cpp_name(type.find(ID_tag));
153 
154  // scope given?
155  if(cpp_name.is_simple_name())
156  {
157  base_name=cpp_name.get_base_name();
158 
159  // anonymous structs always go into the current scope
160  if(type.get_bool(ID_C_is_anonymous))
161  dest_scope=&cpp_scopes.current_scope();
162  else
163  dest_scope=&tag_scope(base_name, has_body, tag_only_declaration);
164  }
165  else
166  {
167  cpp_save_scopet cpp_save_scope(cpp_scopes);
168  cpp_typecheck_resolvet cpp_typecheck_resolve(*this);
170  dest_scope=
171  &cpp_typecheck_resolve.resolve_scope(cpp_name, base_name, t_args);
172  }
173  }
174 
175  // The identifier 'tag-X' matches what the C front-end does!
176  // The hyphen is deliberate to avoid collisions with other
177  // identifiers.
178  const irep_idt symbol_name=
179  dest_scope->prefix+
180  "tag-"+id2string(base_name)+
181  dest_scope->suffix;
182 
183  // check if we have it already
184 
185  if(const auto maybe_symbol=symbol_table.lookup(symbol_name))
186  {
187  // we do!
188  const symbolt &symbol=*maybe_symbol;
189 
190  if(has_body)
191  {
192  if(
193  symbol.type.id() == type.id() &&
195  {
196  // a previously incomplete struct/union becomes complete
197  symbolt &writeable_symbol = symbol_table.get_writeable_ref(symbol_name);
198  writeable_symbol.type.swap(type);
199  typecheck_compound_body(writeable_symbol);
200  }
201  else if(symbol.type.get_bool(ID_C_is_anonymous))
202  {
203  // we silently ignore
204  }
205  else
206  {
208  error() << "error: compound tag '" << base_name
209  << "' declared previously\n"
210  << "location of previous definition: " << symbol.location
211  << eom;
212  throw 0;
213  }
214  }
215  }
216  else
217  {
218  // produce new symbol
219  symbolt symbol;
220 
221  symbol.name=symbol_name;
222  symbol.base_name=base_name;
223  symbol.value.make_nil();
224  symbol.location=type.source_location();
225  symbol.mode=ID_cpp;
226  symbol.module=module;
227  symbol.type.swap(type);
228  symbol.is_type=true;
229  symbol.is_macro=false;
230  symbol.pretty_name=
232  id2string(symbol.base_name)+
234  symbol.type.set(
236 
237  // move early, must be visible before doing body
238  symbolt *new_symbol;
239 
240  if(symbol_table.move(symbol, new_symbol))
241  {
242  error().source_location=symbol.location;
243  error() << "cpp_typecheckt::typecheck_compound_type: "
244  << "symbol_table.move() failed" << eom;
245  throw 0;
246  }
247 
248  // put into dest_scope
249  cpp_idt &id=cpp_scopes.put_into_scope(*new_symbol, *dest_scope);
250 
252  id.is_scope=true;
253  id.prefix=cpp_scopes.current_scope().prefix+
254  id2string(new_symbol->base_name)+
256  id.class_identifier=new_symbol->name;
257  id.id_class=cpp_idt::id_classt::CLASS;
258 
259  if(has_body)
260  typecheck_compound_body(*new_symbol);
261  else
262  {
263  struct_union_typet new_type(new_symbol->type.id());
264  new_type.set(ID_tag, new_symbol->base_name);
265  new_type.make_incomplete();
266  new_type.add_source_location() = type.source_location();
267  new_symbol->type.swap(new_type);
268  }
269  }
270 
271  if(is_union)
272  {
273  // create union tag
274  union_tag_typet tag_type(symbol_name);
275  qualifiers.write(tag_type);
276  type.swap(tag_type);
277  }
278  else
279  {
280  // create struct tag
281  struct_tag_typet tag_type(symbol_name);
282  qualifiers.write(tag_type);
283  type.swap(tag_type);
284  }
285 }
286 
288  const symbolt &symbol,
289  const cpp_declarationt &declaration,
290  cpp_declaratort &declarator,
291  struct_typet::componentst &components,
292  const irep_idt &access,
293  bool is_static,
294  bool is_typedef,
295  bool is_mutable)
296 {
297  bool is_cast_operator=
298  declaration.type().id()=="cpp-cast-operator";
299 
300  if(is_cast_operator)
301  {
302  assert(declarator.name().get_sub().size()==2 &&
303  declarator.name().get_sub().front().id()==ID_operator);
304 
305  typet type=static_cast<typet &>(declarator.name().get_sub()[1]);
306  declarator.type().subtype()=type;
307 
308  cpp_namet::namet name("(" + cpp_type2name(type) + ")");
309  declarator.name().get_sub().back().swap(name);
310  }
311 
312  typet final_type=
313  declarator.merge_type(declaration.type());
314 
315  // this triggers template elaboration
316  elaborate_class_template(final_type);
317 
318  typecheck_type(final_type);
319 
320  cpp_namet cpp_name;
321  cpp_name.swap(declarator.name());
322 
323  irep_idt base_name;
324 
325  if(cpp_name.is_nil())
326  {
327  // Yes, there can be members without name.
328  base_name=irep_idt();
329  }
330  else if(cpp_name.is_simple_name())
331  {
332  base_name=cpp_name.get_base_name();
333  }
334  else
335  {
337  error() << "declarator in compound needs to be simple name"
338  << eom;
339  throw 0;
340  }
341 
342  bool is_method=!is_typedef && final_type.id()==ID_code;
343  bool is_constructor=declaration.is_constructor();
344  bool is_destructor=declaration.is_destructor();
345  bool is_virtual=declaration.member_spec().is_virtual();
346  bool is_explicit=declaration.member_spec().is_explicit();
347  bool is_inline=declaration.member_spec().is_inline();
348 
349  final_type.set(ID_C_member_name, symbol.name);
350 
351  // first do some sanity checks
352 
353  if(is_virtual && !is_method)
354  {
356  error() << "only methods can be virtual" << eom;
357  throw 0;
358  }
359 
360  if(is_inline && !is_method)
361  {
363  error() << "only methods can be inlined" << eom;
364  throw 0;
365  }
366 
367  if(is_virtual && is_static)
368  {
370  error() << "static methods cannot be virtual" << eom;
371  throw 0;
372  }
373 
374  if(is_cast_operator && is_static)
375  {
377  error() << "cast operators cannot be static" << eom;
378  throw 0;
379  }
380 
381  if(is_constructor && is_virtual)
382  {
384  error() << "constructors cannot be virtual" << eom;
385  throw 0;
386  }
387 
388  if(!is_constructor && is_explicit)
389  {
391  error() << "only constructors can be explicit" << eom;
392  throw 0;
393  }
394 
395  if(is_constructor && base_name != symbol.base_name)
396  {
398  error() << "member function must return a value or void" << eom;
399  throw 0;
400  }
401 
402  if(is_destructor &&
403  base_name!="~"+id2string(symbol.base_name))
404  {
406  error() << "destructor with wrong name" << eom;
407  throw 0;
408  }
409 
410  // now do actual work
411 
412  irep_idt identifier;
413 
414  // the below is a temporary hack
415  // if(is_method || is_static)
416  if(id2string(cpp_scopes.current_scope().prefix).find("#anon")==
417  std::string::npos ||
418  is_method || is_static)
419  {
420  // Identifiers for methods include the scope prefix.
421  // Identifiers for static members include the scope prefix.
422  identifier=
424  id2string(base_name);
425  }
426  else
427  {
428  // otherwise, we keep them simple
429  identifier=base_name;
430  }
431 
432  struct_typet::componentt component(identifier, final_type);
433  component.set(ID_access, access);
434  component.set_base_name(base_name);
435  component.set_pretty_name(base_name);
436  component.add_source_location()=cpp_name.source_location();
437 
438  if(cpp_name.is_operator())
439  {
440  component.set(ID_is_operator, true);
441  component.type().set(ID_C_is_operator, true);
442  }
443 
444  if(is_cast_operator)
445  component.set(ID_is_cast_operator, true);
446 
447  if(declaration.member_spec().is_explicit())
448  component.set(ID_is_explicit, true);
449 
450  // either blank, const, volatile, or const volatile
451  const typet &method_qualifier=
452  static_cast<const typet &>(declarator.add(ID_method_qualifier));
453 
454  if(is_static)
455  {
456  component.set(ID_is_static, true);
457  component.type().set(ID_C_is_static, true);
458  }
459 
460  if(is_typedef)
461  component.set(ID_is_type, true);
462 
463  if(is_mutable)
464  component.set(ID_is_mutable, true);
465 
466  exprt &value=declarator.value();
467  irept &initializers=declarator.member_initializers();
468 
469  if(is_method)
470  {
471  if(
472  value.id() == ID_code &&
473  to_code(value).get_statement() == ID_cpp_delete)
474  {
475  value.make_nil();
476  component.set(ID_access, ID_noaccess);
477  }
478 
479  component.set(ID_is_inline, declaration.member_spec().is_inline());
480 
481  // the 'virtual' name of the function
482  std::string virtual_name = id2string(component.get_base_name()) +
484 
485  if(has_const(method_qualifier))
486  virtual_name+="$const";
487 
488  if(has_volatile(method_qualifier))
489  virtual_name += "$volatile";
490 
491  if(to_code_type(component.type()).return_type().id() == ID_destructor)
492  virtual_name="@dtor";
493 
494  // The method may be virtual implicitly.
495  std::set<irep_idt> virtual_bases;
496 
497  for(const auto &comp : components)
498  {
499  if(comp.get_bool(ID_is_virtual))
500  {
501  if(comp.get(ID_virtual_name) == virtual_name)
502  {
503  is_virtual=true;
504  const code_typet &code_type=to_code_type(comp.type());
505  assert(!code_type.parameters().empty());
506  const typet &pointer_type=code_type.parameters()[0].type();
507  assert(pointer_type.id()==ID_pointer);
508  virtual_bases.insert(pointer_type.subtype().get(ID_identifier));
509  }
510  }
511  }
512 
513  if(!is_virtual)
514  {
516  symbol, component, initializers,
517  method_qualifier, value);
518 
519  if(!value.is_nil() && !is_static)
520  {
522  error() << "no initialization allowed here" << eom;
523  throw 0;
524  }
525  }
526  else // virtual
527  {
528  component.type().set(ID_C_is_virtual, true);
529  component.type().set(ID_C_virtual_name, virtual_name);
530 
531  // Check if it is a pure virtual method
532  if(value.is_not_nil() && value.id() == ID_constant)
533  {
534  mp_integer i;
535  to_integer(to_constant_expr(value), i);
536  if(i!=0)
537  {
538  error().source_location = declarator.name().source_location();
539  error() << "expected 0 to mark pure virtual method, got " << i << eom;
540  throw 0;
541  }
542  component.set(ID_is_pure_virtual, true);
543  value.make_nil();
544  }
545 
547  symbol,
548  component,
549  initializers,
550  method_qualifier,
551  value);
552 
553  // get the virtual-table symbol type
554  irep_idt vt_name="virtual_table::"+id2string(symbol.name);
555 
556  if(!symbol_table.has_symbol(vt_name))
557  {
558  // first time: create a virtual-table symbol type
559  symbolt vt_symb_type;
560  vt_symb_type.name= vt_name;
561  vt_symb_type.base_name="virtual_table::"+id2string(symbol.base_name);
562  vt_symb_type.pretty_name=vt_symb_type.base_name;
563  vt_symb_type.mode=ID_cpp;
564  vt_symb_type.module=module;
565  vt_symb_type.location=symbol.location;
566  vt_symb_type.type=struct_typet();
567  vt_symb_type.type.set(ID_name, vt_symb_type.name);
568  vt_symb_type.is_type=true;
569 
570  const bool failed=!symbol_table.insert(std::move(vt_symb_type)).second;
572 
573  // add a virtual-table pointer
575  id2string(symbol.name) + "::@vtable_pointer",
576  pointer_type(struct_tag_typet(vt_name)));
577  compo.set_base_name("@vtable_pointer");
578  compo.set_pretty_name(id2string(symbol.base_name) + "@vtable_pointer");
579  compo.set(ID_is_vtptr, true);
580  compo.set(ID_access, ID_public);
581  components.push_back(compo);
583  }
584 
586  INVARIANT(vt.id()==ID_struct, "Virtual tables must be stored as struct");
587  struct_typet &virtual_table=to_struct_type(vt);
588 
589  component.set(ID_virtual_name, virtual_name);
590  component.set(ID_is_virtual, is_virtual);
591 
592  // add an entry to the virtual table
593  struct_typet::componentt vt_entry(
594  id2string(vt_name) + "::" + virtual_name,
595  pointer_type(component.type()));
596  vt_entry.set_base_name(virtual_name);
597  vt_entry.set_pretty_name(virtual_name);
598  vt_entry.set(ID_access, ID_public);
599  vt_entry.add_source_location()=symbol.location;
600  virtual_table.components().push_back(vt_entry);
601 
602  // take care of overloading
603  while(!virtual_bases.empty())
604  {
605  irep_idt virtual_base=*virtual_bases.begin();
606 
607  // a new function that does 'late casting' of the 'this' parameter
608  symbolt func_symb;
609  func_symb.name=
610  id2string(component.get_name())+"::"+id2string(virtual_base);
611  func_symb.base_name = component.get_base_name();
612  func_symb.pretty_name = component.get_base_name();
613  func_symb.mode = symbol.mode;
614  func_symb.module=module;
615  func_symb.location=component.source_location();
616  func_symb.type=component.type();
617 
618  // change the type of the 'this' pointer
619  code_typet &code_type=to_code_type(func_symb.type);
620  code_typet::parametert &this_parameter = code_type.parameters().front();
621  this_parameter.type().subtype().set(ID_identifier, virtual_base);
622 
623  // create symbols for the parameters
624  code_typet::parameterst &args=code_type.parameters();
625  std::size_t i=0;
626  for(auto &arg : args)
627  {
628  irep_idt param_base_name = arg.get_base_name();
629 
630  if(param_base_name.empty())
631  param_base_name = "arg" + std::to_string(i++);
632 
633  symbolt arg_symb;
634  arg_symb.name =
635  id2string(func_symb.name) + "::" + id2string(param_base_name);
636  arg_symb.base_name = param_base_name;
637  arg_symb.pretty_name = param_base_name;
638  arg_symb.mode = symbol.mode;
639  arg_symb.location=func_symb.location;
640  arg_symb.type=arg.type();
641 
642  arg.set_identifier(arg_symb.name);
643 
644  // add the parameter to the symbol table
645  const bool failed=!symbol_table.insert(std::move(arg_symb)).second;
647  }
648 
649  // do the body of the function
650  typecast_exprt late_cast(
651  lookup(args[0].get_identifier()).symbol_expr(),
652  to_code_type(component.type()).parameters()[0].type());
653 
655  symbol_exprt(component.get_name(), component.type()),
656  {late_cast},
658  source_locationt{});
659  expr_call.arguments().reserve(args.size());
660 
661  for(const auto &arg : args)
662  {
663  expr_call.arguments().push_back(
664  lookup(arg.get_identifier()).symbol_expr());
665  }
666 
667  if(code_type.return_type().id()!=ID_empty &&
668  code_type.return_type().id()!=ID_destructor)
669  {
670  expr_call.type()=to_code_type(component.type()).return_type();
671 
672  func_symb.value =
673  code_returnt(already_typechecked_exprt{std::move(expr_call)})
674  .make_block();
675  }
676  else
677  {
678  func_symb.value =
679  code_expressiont(already_typechecked_exprt{std::move(expr_call)})
680  .make_block();
681  }
682 
683  // add this new function to the list of components
684 
686  new_compo.type()=func_symb.type;
687  new_compo.set_name(func_symb.name);
688  components.push_back(new_compo);
689 
690  // add the function to the symbol table
691  {
692  const bool failed=!symbol_table.insert(std::move(func_symb)).second;
694  }
695 
696  put_compound_into_scope(new_compo);
697 
698  // next base
699  virtual_bases.erase(virtual_bases.begin());
700  }
701  }
702  }
703 
704  if(is_static && !is_method) // static non-method member
705  {
706  // add as global variable to symbol_table
707  symbolt static_symbol;
708  static_symbol.mode=symbol.mode;
709  static_symbol.name=identifier;
710  static_symbol.type=component.type();
711  static_symbol.base_name = component.get_base_name();
712  static_symbol.is_lvalue=true;
713  static_symbol.is_static_lifetime=true;
714  static_symbol.location=cpp_name.source_location();
715  static_symbol.is_extern=true;
716 
717  // TODO: not sure about this: should be defined separately!
718  dynamic_initializations.push_back(static_symbol.name);
719 
720  symbolt *new_symbol;
721  if(symbol_table.move(static_symbol, new_symbol))
722  {
724  error() << "redeclaration of static member '" << static_symbol.base_name
725  << "'" << eom;
726  throw 0;
727  }
728 
729  if(value.is_not_nil())
730  {
731  if(cpp_is_pod(new_symbol->type))
732  {
733  new_symbol->value.swap(value);
735  }
736  else
737  {
738  symbol_exprt symexpr = symbol_exprt::typeless(new_symbol->name);
739 
740  exprt::operandst ops;
741  ops.push_back(value);
742  auto defcode = cpp_constructor(source_locationt(), symexpr, ops);
743  CHECK_RETURN(defcode.has_value());
744 
745  new_symbol->value.swap(defcode.value());
746  }
747  }
748  }
749 
750  // array members must have fixed size
752 
754 
755  components.push_back(component);
756 }
757 
760 {
761  if(type.id()==ID_array)
762  {
763  array_typet &array_type=to_array_type(type);
764 
765  if(array_type.size().is_not_nil())
766  {
767  if(array_type.size().id() == ID_symbol)
768  {
769  const symbol_exprt &s = to_symbol_expr(array_type.size());
770  const symbolt &symbol = lookup(s.get_identifier());
771 
772  if(cpp_is_pod(symbol.type) && symbol.type.get_bool(ID_C_constant))
773  array_type.size() = symbol.value;
774  }
775 
776  make_constant_index(array_type.size());
777  }
778 
779  // recursive call for multi-dimensional arrays
780  check_fixed_size_array(array_type.subtype());
781  }
782 }
783 
785  const struct_union_typet::componentt &compound)
786 {
787  const irep_idt &base_name=compound.get_base_name();
788  const irep_idt &name=compound.get_name();
789 
790  // nothing to do if no base_name (e.g., an anonymous bitfield)
791  if(base_name.empty())
792  return;
793 
794  if(compound.type().id()==ID_code)
795  {
796  // put the symbol into scope
797  cpp_idt &id=cpp_scopes.current_scope().insert(base_name);
798  id.id_class = compound.get_bool(ID_is_type) ? cpp_idt::id_classt::TYPEDEF
800  id.identifier=name;
801  id.class_identifier=cpp_scopes.current_scope().identifier;
802  id.is_member=true;
803  id.is_constructor =
804  to_code_type(compound.type()).return_type().id() == ID_constructor;
805  id.is_method=true;
806  id.is_static_member=compound.get_bool(ID_is_static);
807 
808  // create function block-scope in the scope
809  cpp_idt &id_block=
811  irep_idt(std::string("$block:") + base_name.c_str()));
812 
814  id_block.identifier=name;
816  id_block.is_method=true;
817  id_block.is_static_member=compound.get_bool(ID_is_static);
818 
819  id_block.is_scope=true;
820  id_block.prefix = compound.get_string(ID_prefix);
821  cpp_scopes.id_map[id.identifier]=&id_block;
822  }
823  else
824  {
825  // check if it's already there
826  const auto id_set =
828 
829  for(const auto &id_it : id_set)
830  {
831  const cpp_idt &id=*id_it;
832 
833  // the name is already in the scope
834  // this is ok if they belong to different categories
835  if(!id.is_class() && !id.is_enum())
836  {
838  error() << "'" << base_name << "' already in compound scope" << eom;
839  throw 0;
840  }
841  }
842 
843  // put into the scope
844  cpp_idt &id=cpp_scopes.current_scope().insert(base_name);
845  id.id_class=compound.get_bool(ID_is_type)?
848  id.identifier=name;
849  id.class_identifier=cpp_scopes.current_scope().identifier;
850  id.is_member=true;
851  id.is_method=false;
852  id.is_static_member=compound.get_bool(ID_is_static);
853  }
854 }
855 
857  symbolt &symbol,
858  cpp_declarationt &declaration)
859 {
860  // A friend of a class can be a function/method,
861  // or a struct/class/union type.
862 
863  if(declaration.is_template())
864  {
865  error().source_location=declaration.type().source_location();
866  error() << "friend template not supported" << eom;
867  throw 0;
868  }
869 
870  // we distinguish these whether there is a declarator
871  if(declaration.declarators().empty())
872  {
873  typet &ftype=declaration.type();
874 
875  // must be struct or union
876  if(ftype.id()!=ID_struct && ftype.id()!=ID_union)
877  {
878  error().source_location=declaration.type().source_location();
879  error() << "unexpected friend" << eom;
880  throw 0;
881  }
882 
883  if(ftype.find(ID_body).is_not_nil())
884  {
885  error().source_location=declaration.type().source_location();
886  error() << "friend declaration must not have compound body" << eom;
887  throw 0;
888  }
889 
890  cpp_save_scopet saved_scope(cpp_scopes);
892  typecheck_type(ftype);
893  symbol.type.add(ID_C_friends).move_to_sub(ftype);
894 
895  return;
896  }
897 
898  // It should be a friend function.
899  // Do the declarators.
900 
901 #ifdef DEBUG
902  std::cout << "friend declaration: " << declaration.pretty() << '\n';
903 #endif
904 
905  for(auto &sub_it : declaration.declarators())
906  {
907 #ifdef DEBUG
908  std::cout << "decl: " << sub_it.pretty() << "\n with value "
909  << sub_it.value().pretty() << '\n';
910  std::cout << " scope: " << cpp_scopes.current_scope().prefix << '\n';
911 #endif
912 
913  if(sub_it.value().is_not_nil())
914  declaration.member_spec().set_inline(true);
915 
916  cpp_declarator_convertert cpp_declarator_converter(*this);
917  cpp_declarator_converter.is_friend = true;
918  const symbolt &conv_symb = cpp_declarator_converter.convert(
919  declaration.type(),
920  declaration.storage_spec(),
921  declaration.member_spec(),
922  sub_it);
923  exprt symb_expr = cpp_symbol_expr(conv_symb);
924  symbol.type.add(ID_C_friends).move_to_sub(symb_expr);
925  }
926 }
927 
929 {
930  cpp_save_scopet saved_scope(cpp_scopes);
931 
932  // enter scope of compound
933  cpp_scopes.set_scope(symbol.name);
934 
935  assert(symbol.type.id()==ID_struct ||
936  symbol.type.id()==ID_union);
937 
938  struct_union_typet &type=
939  to_struct_union_type(symbol.type);
940 
941  // pull the base types in
942  if(!type.find(ID_bases).get_sub().empty())
943  {
944  if(type.id()==ID_union)
945  {
946  error().source_location=symbol.location;
947  error() << "union types must not have bases" << eom;
948  throw 0;
949  }
950 
952  }
953 
954  exprt &body=static_cast<exprt &>(type.add(ID_body));
955  struct_union_typet::componentst &components=type.components();
956 
957  symbol.type.set(ID_name, symbol.name);
958 
959  // default access
960  irep_idt access = type.default_access();
961 
962  bool found_ctor=false;
963  bool found_dtor=false;
964 
965  // we first do everything _but_ the constructors
966 
967  Forall_operands(it, body)
968  {
969  if(it->id()==ID_cpp_declaration)
970  {
971  cpp_declarationt &declaration=
972  to_cpp_declaration(*it);
973 
974  if(declaration.member_spec().is_friend())
975  {
976  typecheck_friend_declaration(symbol, declaration);
977  continue; // done
978  }
979 
980  if(declaration.is_template())
981  {
982  // remember access mode
983  declaration.set(ID_C_access, access);
984  convert_template_declaration(declaration);
985  continue;
986  }
987 
988  if(declaration.type().id().empty())
989  continue;
990 
991  bool is_typedef=declaration.is_typedef();
992 
993  // is it tag-only?
994  if(declaration.type().id()==ID_struct ||
995  declaration.type().id()==ID_union ||
996  declaration.type().id()==ID_c_enum)
997  if(declaration.declarators().empty())
998  declaration.type().set(ID_C_tag_only_declaration, true);
999 
1000  declaration.name_anon_struct_union();
1001  typecheck_type(declaration.type());
1002 
1003  bool is_static=declaration.storage_spec().is_static();
1004  bool is_mutable=declaration.storage_spec().is_mutable();
1005 
1006  if(declaration.storage_spec().is_extern() ||
1007  declaration.storage_spec().is_auto() ||
1008  declaration.storage_spec().is_register())
1009  {
1010  error().source_location=declaration.storage_spec().location();
1011  error() << "invalid storage class specified for field" << eom;
1012  throw 0;
1013  }
1014 
1015  typet final_type=follow(declaration.type());
1016 
1017  // anonymous member?
1018  if(declaration.declarators().empty() &&
1019  final_type.get_bool(ID_C_is_anonymous))
1020  {
1021  // we only allow this on struct/union types
1022  if(final_type.id()!=ID_union &&
1023  final_type.id()!=ID_struct)
1024  {
1025  error().source_location=declaration.type().source_location();
1026  error() << "member declaration does not declare anything"
1027  << eom;
1028  throw 0;
1029  }
1030 
1032  declaration, access, components);
1033 
1034  continue;
1035  }
1036 
1037  // declarators
1038  for(auto &declarator : declaration.declarators())
1039  {
1040  // Skip the constructors until all the data members
1041  // are discovered
1042  if(declaration.is_destructor())
1043  found_dtor=true;
1044 
1045  if(declaration.is_constructor())
1046  {
1047  found_ctor=true;
1048  continue;
1049  }
1050 
1052  symbol,
1053  declaration, declarator, components,
1054  access, is_static, is_typedef, is_mutable);
1055  }
1056  }
1057  else if(it->id()=="cpp-public")
1058  access=ID_public;
1059  else if(it->id()=="cpp-private")
1060  access=ID_private;
1061  else if(it->id()=="cpp-protected")
1062  access=ID_protected;
1063  else
1064  {
1065  }
1066  }
1067 
1068  // Add the default dtor, if needed
1069  // (we have to do the destructor before building the virtual tables,
1070  // as the destructor may be virtual!)
1071 
1072  if((found_ctor || !cpp_is_pod(symbol.type)) && !found_dtor)
1073  {
1074  // build declaration
1076  default_dtor(symbol, dtor);
1077 
1079  symbol,
1080  dtor, dtor.declarators()[0], components,
1081  ID_public, false, false, false);
1082  }
1083 
1084  // set up virtual tables before doing the constructors
1085  if(symbol.type.id()==ID_struct)
1086  do_virtual_table(symbol);
1087 
1088  if(!found_ctor && !cpp_is_pod(symbol.type))
1089  {
1090  // it's public!
1091  exprt cpp_public("cpp-public");
1092  body.add_to_operands(std::move(cpp_public));
1093 
1094  // build declaration
1095  cpp_declarationt ctor;
1096  default_ctor(symbol.type.source_location(), symbol.base_name, ctor);
1097  body.add_to_operands(std::move(ctor));
1098  }
1099 
1100  // Reset the access type
1101  access = type.default_access();
1102 
1103  // All the data members are now known.
1104  // We now deal with the constructors that we are given.
1105  Forall_operands(it, body)
1106  {
1107  if(it->id()==ID_cpp_declaration)
1108  {
1109  cpp_declarationt &declaration=
1110  to_cpp_declaration(*it);
1111 
1112  if(!declaration.is_constructor())
1113  continue;
1114 
1115  for(auto &declarator : declaration.declarators())
1116  {
1117  #if 0
1118  irep_idt ctor_base_name=
1119  declarator.name().get_base_name();
1120  #endif
1121 
1122  if(declarator.value().is_not_nil()) // body?
1123  {
1124  if(declarator.find(ID_member_initializers).is_nil())
1125  declarator.set(ID_member_initializers, ID_member_initializers);
1126 
1127  if(type.id() == ID_union)
1128  {
1130  {}, type.components(), declarator.member_initializers());
1131  }
1132  else
1133  {
1135  to_struct_type(type).bases(),
1136  type.components(),
1137  declarator.member_initializers());
1138  }
1139 
1141  type,
1142  declarator.member_initializers());
1143  }
1144 
1145  // Finally, we typecheck the constructor with the
1146  // full member-initialization list
1147  // Shall all be false
1148  bool is_static=declaration.storage_spec().is_static();
1149  bool is_mutable=declaration.storage_spec().is_mutable();
1150  bool is_typedef=declaration.is_typedef();
1151 
1153  symbol,
1154  declaration, declarator, components,
1155  access, is_static, is_typedef, is_mutable);
1156  }
1157  }
1158  else if(it->id()=="cpp-public")
1159  access=ID_public;
1160  else if(it->id()=="cpp-private")
1161  access=ID_private;
1162  else if(it->id()=="cpp-protected")
1163  access=ID_protected;
1164  else
1165  {
1166  }
1167  }
1168 
1169  if(!cpp_is_pod(symbol.type))
1170  {
1171  // Add the default copy constructor
1173 
1174  if(!find_cpctor(symbol))
1175  {
1176  // build declaration
1177  cpp_declarationt cpctor;
1178  default_cpctor(symbol, cpctor);
1179  assert(cpctor.declarators().size()==1);
1180 
1181  exprt value(ID_cpp_not_typechecked);
1182  value.copy_to_operands(cpctor.declarators()[0].value());
1183  cpctor.declarators()[0].value()=value;
1184 
1186  symbol,
1187  cpctor, cpctor.declarators()[0], components,
1188  ID_public, false, false, false);
1189  }
1190 
1191  // Add the default assignment operator
1192  if(!find_assignop(symbol))
1193  {
1194  // build declaration
1195  cpp_declarationt assignop;
1196  default_assignop(symbol, assignop);
1197  assert(assignop.declarators().size()==1);
1198 
1199  // The value will be typechecked only if the operator
1200  // is actually used
1201  cpp_declaratort declarator;
1202  assignop.declarators().push_back(declarator);
1203  assignop.declarators()[0].value() = exprt(ID_cpp_not_typechecked);
1204 
1206  symbol,
1207  assignop, assignop.declarators()[0], components,
1208  ID_public, false, false, false);
1209  }
1210  }
1211 
1212  // clean up!
1213  symbol.type.remove(ID_body);
1214 }
1215 
1217  irept &initializers,
1218  const code_typet &type,
1219  exprt &value)
1220 {
1221  // see if we have initializers
1222  if(!initializers.get_sub().empty())
1223  {
1224  const source_locationt &location=
1225  static_cast<const source_locationt &>(
1226  initializers.find(ID_C_source_location));
1227 
1228  if(type.return_type().id() != ID_constructor)
1229  {
1230  error().source_location=location;
1231  error() << "only constructors are allowed to "
1232  << "have member initializers" << eom;
1233  throw 0;
1234  }
1235 
1236  if(value.is_nil())
1237  {
1238  error().source_location=location;
1239  error() << "only constructors with body are allowed to "
1240  << "have member initializers" << eom;
1241  throw 0;
1242  }
1243 
1244  to_code(value).make_block();
1245 
1246  exprt::operandst::iterator o_it=value.operands().begin();
1247  forall_irep(it, initializers.get_sub())
1248  {
1249  o_it=value.operands().insert(o_it, static_cast<const exprt &>(*it));
1250  o_it++;
1251  }
1252  }
1253 }
1254 
1256  const symbolt &compound_symbol,
1258  irept &initializers,
1259  const typet &method_qualifier,
1260  exprt &value)
1261 {
1262  symbolt symbol;
1263 
1264  code_typet &type = to_code_type(component.type());
1265 
1266  if(component.get_bool(ID_is_static))
1267  {
1268  if(!method_qualifier.id().empty())
1269  {
1270  error().source_location=component.source_location();
1271  error() << "method is static -- no qualifiers allowed" << eom;
1272  throw 0;
1273  }
1274  }
1275  else
1276  {
1277  add_this_to_method_type(compound_symbol, type, method_qualifier);
1278  }
1279 
1280  if(value.id() == ID_cpp_not_typechecked && value.has_operands())
1281  {
1283  initializers, type, to_multi_ary_expr(value).op0());
1284  }
1285  else
1286  move_member_initializers(initializers, type, value);
1287 
1288  irep_idt f_id=
1290 
1291  const irep_idt identifier=
1293  id2string(component.get_base_name())+
1294  id2string(f_id);
1295 
1296  component.set_name(identifier);
1297  component.set(ID_prefix, id2string(identifier) + "::");
1298 
1299  if(value.is_not_nil())
1300  to_code_type(type).set_inlined(true);
1301 
1302  symbol.name=identifier;
1303  symbol.base_name=component.get_base_name();
1304  symbol.value.swap(value);
1305  symbol.mode = compound_symbol.mode;
1306  symbol.module=module;
1307  symbol.type=type;
1308  symbol.is_type=false;
1309  symbol.is_macro=false;
1310  symbol.location=component.source_location();
1311 
1312  // move early, it must be visible before doing any value
1313  symbolt *new_symbol;
1314 
1315  const bool symbol_exists = symbol_table.move(symbol, new_symbol);
1316  if(symbol_exists && new_symbol->is_weak)
1317  {
1318  // there might have been an earlier friend declaration
1319  *new_symbol = std::move(symbol);
1320  }
1321  else if(symbol_exists)
1322  {
1323  error().source_location=symbol.location;
1324  error() << "failed to insert new method symbol: " << symbol.name << '\n'
1325  << "name of previous symbol: " << new_symbol->name << '\n'
1326  << "location of previous symbol: " << new_symbol->location << eom;
1327 
1328  throw 0;
1329  }
1330 
1331  // Is this in a class template?
1332  // If so, we defer typechecking until used.
1334  deferred_typechecking.insert(new_symbol->name);
1335  else // remember for later typechecking of body
1336  add_method_body(new_symbol);
1337 }
1338 
1340  const symbolt &compound_symbol,
1341  code_typet &type,
1342  const typet &method_qualifier)
1343 {
1344  typet subtype;
1345 
1346  if(compound_symbol.type.id() == ID_union)
1347  subtype = union_tag_typet(compound_symbol.name);
1348  else
1349  subtype = struct_tag_typet(compound_symbol.name);
1350 
1351  if(has_const(method_qualifier))
1352  subtype.set(ID_C_constant, true);
1353 
1354  if(has_volatile(method_qualifier))
1355  subtype.set(ID_C_volatile, true);
1356 
1357  code_typet::parametert parameter(pointer_type(subtype));
1358  parameter.set_identifier(ID_this);
1359  parameter.set_base_name(ID_this);
1360  parameter.set_this();
1362  convert_parameter(compound_symbol.mode, parameter);
1363 
1364  code_typet::parameterst &parameters = type.parameters();
1365  parameters.insert(parameters.begin(), parameter);
1366 }
1367 
1369  const symbolt &struct_union_symbol)
1370 {
1371  const struct_union_typet &struct_union_type=
1372  to_struct_union_type(struct_union_symbol.type);
1373 
1374  const struct_union_typet::componentst &struct_union_components=
1375  struct_union_type.components();
1376 
1377  // do scoping -- the members of the struct/union
1378  // should be visible in the containing struct/union,
1379  // and that recursively!
1380 
1381  for(const auto &comp : struct_union_components)
1382  {
1383  if(comp.type().id()==ID_code)
1384  {
1385  error().source_location=struct_union_symbol.type.source_location();
1386  error() << "anonymous struct/union member '"
1387  << struct_union_symbol.base_name
1388  << "' shall not have function members" << eom;
1389  throw 0;
1390  }
1391 
1392  if(comp.get_anonymous())
1393  {
1394  const symbolt &symbol=lookup(comp.type().get(ID_identifier));
1395  // recursive call
1397  }
1398  else
1399  {
1400  const irep_idt &base_name=comp.get_base_name();
1401 
1402  if(cpp_scopes.current_scope().contains(base_name))
1403  {
1404  error().source_location=comp.source_location();
1405  error() << "'" << base_name << "' already in scope" << eom;
1406  throw 0;
1407  }
1408 
1409  cpp_idt &id=cpp_scopes.current_scope().insert(base_name);
1411  id.identifier=comp.get_name();
1412  id.class_identifier=struct_union_symbol.name;
1413  id.is_member=true;
1414  }
1415  }
1416 }
1417 
1419  const cpp_declarationt &declaration,
1420  const irep_idt &access,
1421  struct_typet::componentst &components)
1422 {
1423  symbolt &struct_union_symbol =
1424  symbol_table.get_writeable_ref(follow(declaration.type()).get(ID_name));
1425 
1426  if(declaration.storage_spec().is_static() ||
1427  declaration.storage_spec().is_mutable())
1428  {
1429  error().source_location=struct_union_symbol.type.source_location();
1430  error() << "storage class is not allowed here" << eom;
1431  throw 0;
1432  }
1433 
1434  if(!cpp_is_pod(struct_union_symbol.type))
1435  {
1436  error().source_location=struct_union_symbol.type.source_location();
1437  error() << "anonymous struct/union member is not POD" << eom;
1438  throw 0;
1439  }
1440 
1441  // produce an anonymous member
1442  irep_idt base_name="#anon_member"+std::to_string(components.size());
1443 
1444  irep_idt identifier=
1446  base_name.c_str();
1447 
1448  typet compound_type;
1449 
1450  if(struct_union_symbol.type.id() == ID_union)
1451  compound_type = union_tag_typet(struct_union_symbol.name);
1452  else
1453  compound_type = struct_tag_typet(struct_union_symbol.name);
1454 
1455  struct_typet::componentt component(identifier, compound_type);
1456  component.set_access(access);
1457  component.set_base_name(base_name);
1458  component.set_pretty_name(base_name);
1459  component.set_anonymous(true);
1460  component.add_source_location()=declaration.source_location();
1461 
1462  components.push_back(component);
1463 
1464  add_anonymous_members_to_scope(struct_union_symbol);
1465 
1467 
1468  struct_union_symbol.type.set(ID_C_unnamed_object, base_name);
1469 }
1470 
1472  const source_locationt &source_location,
1473  const exprt &object,
1474  const irep_idt &component_name,
1475  exprt &member)
1476 {
1477  const typet &followed_type=follow(object.type());
1478 
1479  assert(followed_type.id()==ID_struct ||
1480  followed_type.id()==ID_union);
1481 
1482  struct_union_typet final_type=
1483  to_struct_union_type(followed_type);
1484 
1485  const struct_union_typet::componentst &components=
1486  final_type.components();
1487 
1488  for(const auto &component : components)
1489  {
1490  member_exprt tmp(object, component.get_name(), component.type());
1491  tmp.add_source_location()=source_location;
1492 
1493  if(component.get_name()==component_name)
1494  {
1495  member.swap(tmp);
1496 
1497  bool not_ok=check_component_access(component, final_type);
1498  if(not_ok)
1499  {
1501  {
1502  member.set(ID_C_not_accessible, true);
1503  member.set(ID_C_access, component.get(ID_access));
1504  }
1505  else
1506  {
1507  error().source_location=source_location;
1508  error() << "error: member '" << component_name
1509  << "' is not accessible (" << component.get(ID_access) << ")"
1510  << eom;
1511  throw 0;
1512  }
1513  }
1514 
1515  if(object.get_bool(ID_C_lvalue))
1516  member.set(ID_C_lvalue, true);
1517 
1518  if(
1519  object.type().get_bool(ID_C_constant) &&
1520  !component.get_bool(ID_is_mutable))
1521  {
1522  member.type().set(ID_C_constant, true);
1523  }
1524 
1525  member.add_source_location()=source_location;
1526 
1527  return true; // component found
1528  }
1529  else if(follow(component.type()).find(ID_C_unnamed_object).is_not_nil())
1530  {
1531  // could be anonymous union or struct
1532 
1533  const typet &component_type=follow(component.type());
1534 
1535  if(component_type.id()==ID_union ||
1536  component_type.id()==ID_struct)
1537  {
1538  // recursive call!
1539  if(get_component(source_location, tmp, component_name, member))
1540  {
1541  if(check_component_access(component, final_type))
1542  {
1543  error().source_location=source_location;
1544  error() << "error: member '" << component_name
1545  << "' is not accessible" << eom;
1546  throw 0;
1547  }
1548 
1549  if(object.get_bool(ID_C_lvalue))
1550  member.set(ID_C_lvalue, true);
1551 
1552  if(
1553  object.get_bool(ID_C_constant) &&
1554  !component.get_bool(ID_is_mutable))
1555  {
1556  member.type().set(ID_C_constant, true);
1557  }
1558 
1559  member.add_source_location()=source_location;
1560  return true; // component found
1561  }
1562  }
1563  }
1564  }
1565 
1566  return false; // component not found
1567 }
1568 
1571  const struct_union_typet &struct_union_type)
1572 {
1573  const irep_idt &access=component.get(ID_access);
1574 
1575  if(access == ID_noaccess)
1576  return true; // not ok
1577 
1578  if(access==ID_public)
1579  return false; // ok
1580 
1581  assert(access==ID_private ||
1582  access==ID_protected);
1583 
1584  const irep_idt &struct_identifier=
1585  struct_union_type.get(ID_name);
1586 
1587  for(cpp_scopet *pscope = &(cpp_scopes.current_scope());
1588  !(pscope->is_root_scope());
1589  pscope = &(pscope->get_parent()))
1590  {
1591  if(pscope->is_class())
1592  {
1593  if(pscope->identifier==struct_identifier)
1594  return false; // ok
1595 
1596  const struct_typet &scope_struct=
1597  to_struct_type(lookup(pscope->identifier).type);
1598 
1599  if(subtype_typecast(
1600  to_struct_type(struct_union_type), scope_struct))
1601  return false; // ok
1602 
1603  else break;
1604  }
1605  }
1606 
1607  // check friendship
1608  const irept::subt &friends = struct_union_type.find(ID_C_friends).get_sub();
1609 
1610  forall_irep(f_it, friends)
1611  {
1612  const irept &friend_symb=*f_it;
1613 
1614  const cpp_scopet &friend_scope =
1615  cpp_scopes.get_scope(friend_symb.get(ID_identifier));
1616 
1617  for(cpp_scopet *pscope = &(cpp_scopes.current_scope());
1618  !(pscope->is_root_scope());
1619  pscope = &(pscope->get_parent()))
1620  {
1621  if(friend_scope.identifier==pscope->identifier)
1622  return false; // ok
1623 
1624  if(pscope->is_class())
1625  break;
1626  }
1627  }
1628 
1629  return true; // not ok
1630 }
1631 
1633  const struct_typet &type,
1634  std::set<irep_idt> &set_bases) const
1635 {
1636  for(const auto &b : type.bases())
1637  {
1638  DATA_INVARIANT(b.id() == ID_base, "base class expression expected");
1639 
1640  const struct_typet &base = to_struct_type(lookup(b.type()).type);
1641 
1642  set_bases.insert(base.get(ID_name));
1643  get_bases(base, set_bases);
1644  }
1645 }
1646 
1648  const struct_typet &type,
1649  std::list<irep_idt> &vbases) const
1650 {
1651  if(std::find(vbases.begin(), vbases.end(), type.get(ID_name))!=vbases.end())
1652  return;
1653 
1654  for(const auto &b : type.bases())
1655  {
1656  DATA_INVARIANT(b.id() == ID_base, "base class expression expected");
1657 
1658  const struct_typet &base = to_struct_type(lookup(b.type()).type);
1659 
1660  if(b.get_bool(ID_virtual))
1661  vbases.push_back(base.get(ID_name));
1662 
1663  get_virtual_bases(base, vbases);
1664  }
1665 }
1666 
1668  const struct_typet &from,
1669  const struct_typet &to) const
1670 {
1671  if(from.get(ID_name)==to.get(ID_name))
1672  return true;
1673 
1674  std::set<irep_idt> bases;
1675 
1676  get_bases(from, bases);
1677 
1678  return bases.find(to.get(ID_name))!=bases.end();
1679 }
1680 
1682  exprt &expr,
1683  const typet &dest_type)
1684 {
1685  typet src_type=expr.type();
1686 
1687  assert(src_type.id()== ID_pointer);
1688  assert(dest_type.id()== ID_pointer);
1689 
1690  const struct_typet &src_struct =
1691  to_struct_type(static_cast<const typet &>(follow(src_type.subtype())));
1692 
1693  const struct_typet &dest_struct =
1694  to_struct_type(static_cast<const typet &>(follow(dest_type.subtype())));
1695 
1696  PRECONDITION(
1697  subtype_typecast(src_struct, dest_struct) ||
1698  subtype_typecast(dest_struct, src_struct));
1699 
1700  expr = typecast_exprt(expr, dest_type);
1701 }
c_typecheck_baset::do_initializer
virtual void do_initializer(exprt &initializer, const typet &type, bool force_constant)
Definition: c_typecheck_initializer.cpp:25
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:148
cpp_typecheckt::do_virtual_table
void do_virtual_table(const symbolt &symbol)
Definition: cpp_typecheck_virtual_table.cpp:17
struct_union_typet::components
const componentst & components() const
Definition: std_types.h:142
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:37
cpp_idt::class_identifier
irep_idt class_identifier
Definition: cpp_id.h:81
dstringt::c_str
const char * c_str() const
Definition: dstring.h:99
cpp_declarationt::storage_spec
const cpp_storage_spect & storage_spec() const
Definition: cpp_declaration.h:74
cpp_scopet::get_parent
cpp_scopet & get_parent() const
Definition: cpp_scope.h:88
typet::subtype
const typet & subtype() const
Definition: type.h:47
cpp_typecheckt::convert_anon_struct_union_member
void convert_anon_struct_union_member(const cpp_declarationt &declaration, const irep_idt &access, struct_typet::componentst &components)
Definition: cpp_typecheck_compound_type.cpp:1418
cpp_declarationt::is_typedef
bool is_typedef() const
Definition: cpp_declaration.h:135
cpp_typecheckt::tag_scope
cpp_scopet & tag_scope(const irep_idt &_base_name, bool has_body, bool tag_only_declaration)
Definition: cpp_typecheck_compound_type.cpp:82
cpp_scopet
Definition: cpp_scope.h:21
cpp_typecheckt::elaborate_class_template
void elaborate_class_template(const typet &type)
elaborate class template instances
Definition: cpp_instantiate_template.cpp:224
cpp_typecheckt::anon_counter
unsigned anon_counter
Definition: cpp_typecheck.h:226
Forall_operands
#define Forall_operands(it, expr)
Definition: expr.h:24
arith_tools.h
symbolt::is_macro
bool is_macro
Definition: symbol.h:61
cpp_idt::id_classt::CLASS
@ CLASS
cpp_member_spect::set_inline
void set_inline(bool value)
Definition: cpp_member_spec.h:29
to_struct_type
const struct_typet & to_struct_type(const typet &type)
Cast a typet to a struct_typet.
Definition: std_types.h:303
cpp_typecheckt::check_component_access
bool check_component_access(const struct_union_typet::componentt &component, const struct_union_typet &struct_union_type)
Definition: cpp_typecheck_compound_type.cpp:1569
cpp_save_scopet
Definition: cpp_scopes.h:129
irept::move_to_sub
void move_to_sub(irept &irep)
Definition: irep.cpp:42
cpp_scopest::id_map
id_mapt id_map
Definition: cpp_scopes.h:69
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:209
cpp_typecheckt::cpp_scopes
cpp_scopest cpp_scopes
Definition: cpp_typecheck.h:109
cpp_scopet::lookup
id_sett lookup(const irep_idt &base_name_to_lookup, lookup_kindt kind)
Definition: cpp_scope.h:32
irept::make_nil
void make_nil()
Definition: irep.h:475
CHECK_RETURN
#define CHECK_RETURN(CONDITION)
Definition: invariant.h:496
typet
The type of an expression, extends irept.
Definition: type.h:29
code_typet::parameterst
std::vector< parametert > parameterst
Definition: std_types.h:738
cpp_namet::namet
Definition: cpp_name.h:27
irept::pretty
std::string pretty(unsigned indent=0, unsigned max_indent=0) const
Definition: irep.cpp:488
to_cpp_declaration
cpp_declarationt & to_cpp_declaration(irept &irep)
Definition: cpp_declaration.h:148
cpp_typecheckt::check_fixed_size_array
void check_fixed_size_array(typet &type)
check that an array has fixed size
Definition: cpp_typecheck_compound_type.cpp:759
struct_union_typet
Base type for structs and unions.
Definition: std_types.h:57
cpp_typecheckt::typecheck_compound_body
void typecheck_compound_body(symbolt &symbol)
Definition: cpp_typecheck_compound_type.cpp:928
symbolt::type
typet type
Type of symbol.
Definition: symbol.h:31
cpp_typecheckt::convert_parameter
void convert_parameter(const irep_idt &current_mode, code_typet::parametert &parameter)
Definition: cpp_typecheck_function.cpp:22
side_effect_expr_function_callt
A side_effect_exprt representation of a function call side effect.
Definition: std_code.h:2127
mp_integer
BigInt mp_integer
Definition: mp_arith.h:19
code_typet::parametert::set_identifier
void set_identifier(const irep_idt &identifier)
Definition: std_types.h:782
irept::add
irept & add(const irep_namet &name)
Definition: irep.cpp:113
symbol_exprt::typeless
static symbol_exprt typeless(const irep_idt &id)
Generate a symbol_exprt without a proper type.
Definition: std_expr.h:101
cpp_idt::identifier
irep_idt identifier
Definition: cpp_id.h:78
cpp_type2name.h
cpp_declaratort::name
cpp_namet & name()
Definition: cpp_declarator.h:36
cpp_typecheckt::typecheck_member_function
void typecheck_member_function(const symbolt &compound_symbol, struct_typet::componentt &component, irept &initializers, const typet &method_qualifier, exprt &value)
Definition: cpp_typecheck_compound_type.cpp:1255
irept::find
const irept & find(const irep_namet &name) const
Definition: irep.cpp:103
cpp_typecheckt::typecheck_compound_bases
void typecheck_compound_bases(struct_typet &type)
Definition: cpp_typecheck_bases.cpp:16
cpp_typecheck_resolvet
Definition: cpp_typecheck_resolve.h:21
namespacet::lookup
const symbolt & lookup(const irep_idt &name) const
Lookup a symbol in the namespace.
Definition: namespace.h:44
cpp_declarator_convertert::convert
symbolt & convert(const typet &type, const cpp_storage_spect &storage_spec, const cpp_member_spect &member_spec, cpp_declaratort &declarator)
Definition: cpp_declarator_converter.cpp:34
cpp_scopest::get_scope
cpp_scopet & get_scope(const irep_idt &identifier)
Definition: cpp_scopes.h:81
exprt
Base class for all expressions.
Definition: expr.h:53
struct_union_typet::componentst
std::vector< componentt > componentst
Definition: std_types.h:135
cpp_typecheckt::cpp_constructor
optionalt< codet > cpp_constructor(const source_locationt &source_location, const exprt &object, const exprt::operandst &operands)
Definition: cpp_constructor.cpp:25
cpp_storage_spect::is_extern
bool is_extern() const
Definition: cpp_storage_spec.h:38
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:490
cpp_typecheckt::dtor
codet dtor(const symbolt &symb, const symbol_exprt &this_expr)
produces destructor code for a class object
Definition: cpp_typecheck_destructor.cpp:50
component
auto component(T &struct_expr, const irep_idt &name, const namespacet &ns) -> decltype(struct_expr.op0())
Definition: std_expr.cpp:192
irep_idt
dstringt irep_idt
Definition: irep.h:32
to_integer
bool to_integer(const constant_exprt &expr, mp_integer &int_value)
Convert a constant expression expr to an arbitrary-precision integer.
Definition: arith_tools.cpp:19
cpp_declarationt::is_destructor
bool is_destructor() const
Definition: cpp_declaration.h:47
cpp_scopet::SCOPE_ONLY
@ SCOPE_ONLY
Definition: cpp_scope.h:30
struct_union_typet::make_incomplete
void make_incomplete()
A struct/union may be incomplete.
Definition: std_types.h:186
to_string
std::string to_string(const string_not_contains_constraintt &expr)
Used for debug printing.
Definition: string_constraint.cpp:55
struct_union_typet::default_access
irep_idt default_access() const
Return the access specification for members where access has not been modified.
Definition: std_types.h:174
messaget::eom
static eomt eom
Definition: message.h:283
cpp_idt::suffix
std::string suffix
Definition: cpp_id.h:85
c_qualifiers.h
cpp_declarationt::name_anon_struct_union
void name_anon_struct_union()
Definition: cpp_declaration.h:144
symbol_exprt
Expression to hold a symbol (variable)
Definition: std_expr.h:82
cpp_scopest::put_into_scope
cpp_idt & put_into_scope(const symbolt &symbol, cpp_scopet &scope, bool is_friend=false)
Definition: cpp_scopes.cpp:22
struct_union_typet::componentt::set_name
void set_name(const irep_idt &name)
Definition: std_types.h:79
cpp_idt::id_classt::BLOCK_SCOPE
@ BLOCK_SCOPE
cpp_scopet::contains
bool contains(const irep_idt &base_name_to_lookup)
Definition: cpp_scope.cpp:203
cpp_storage_spect::is_static
bool is_static() const
Definition: cpp_storage_spec.h:37
cpp_idt
Definition: cpp_id.h:29
union_tag_typet
A union tag type, i.e., union_typet with an identifier.
Definition: std_types.h:530
cpp_declarationt::declarators
const declaratorst & declarators() const
Definition: cpp_declaration.h:64
cpp_declarationt::member_spec
const cpp_member_spect & member_spec() const
Definition: cpp_declaration.h:86
cpp_typecheckt::typecheck_friend_declaration
void typecheck_friend_declaration(symbolt &symbol, cpp_declarationt &cpp_declaration)
Definition: cpp_typecheck_compound_type.cpp:856
symbolt::pretty_name
irep_idt pretty_name
Language-specific display name.
Definition: symbol.h:52
to_code
const codet & to_code(const exprt &expr)
Definition: std_code.h:158
cpp_typecheckt::default_dtor
void default_dtor(const symbolt &symb, cpp_declarationt &dtor)
Note:
Definition: cpp_typecheck_destructor.cpp:28
cpp_scopest::get_global_scope
cpp_scopet & get_global_scope()
Definition: cpp_scopes.h:116
cpp_idt::is_scope
bool is_scope
Definition: cpp_id.h:49
array_typet::size
const exprt & size() const
Definition: std_types.h:973
cpp_typecheckt::cpp_is_pod
bool cpp_is_pod(const typet &type) const
Definition: cpp_is_pod.cpp:14
cpp_member_spect::is_inline
bool is_inline() const
Definition: cpp_member_spec.h:24
cpp_idt::is_method
bool is_method
Definition: cpp_id.h:48
exprt::type
typet & type()
Return the type of the expression.
Definition: expr.h:81
cpp_typecheckt::typecheck_type
void typecheck_type(typet &) override
Definition: cpp_typecheck_type.cpp:23
irept::get_bool
bool get_bool(const irep_namet &name) const
Definition: irep.cpp:64
irept::is_not_nil
bool is_not_nil() const
Definition: irep.h:402
c_typecheck_baset::module
const irep_idt module
Definition: c_typecheck_base.h:68
cpp_typecheckt::has_const
static bool has_const(const typet &type)
Definition: cpp_typecheck_compound_type.cpp:32
cpp_member_spect::is_virtual
bool is_virtual() const
Definition: cpp_member_spec.h:23
to_code_type
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
Definition: std_types.h:946
cpp_typecheckt::default_ctor
void default_ctor(const source_locationt &source_location, const irep_idt &base_name, cpp_declarationt &ctor) const
Generate code for implicit default constructors.
Definition: cpp_typecheck_constructor.cpp:119
cpp_scopest::go_to_global_scope
void go_to_global_scope()
Definition: cpp_scopes.h:111
symbolt::mode
irep_idt mode
Language mode.
Definition: symbol.h:49
cpp_member_spect::is_explicit
bool is_explicit() const
Definition: cpp_member_spec.h:26
messaget::error
mstreamt & error() const
Definition: message.h:385
cpp_idt::id_classt::SYMBOL
@ SYMBOL
cpp_typecheckt::get_virtual_bases
void get_virtual_bases(const struct_typet &type, std::list< irep_idt > &vbases) const
Definition: cpp_typecheck_compound_type.cpp:1647
cpp_typecheckt::add_method_body
void add_method_body(symbolt *_method_symbol)
Definition: cpp_typecheck_method_bodies.cpp:51
cpp_typecheckt::typecheck_compound_declarator
void typecheck_compound_declarator(const symbolt &symbol, const cpp_declarationt &declaration, cpp_declaratort &declarator, struct_typet::componentst &components, const irep_idt &access, bool is_static, bool is_typedef, bool is_mutable)
Definition: cpp_typecheck_compound_type.cpp:287
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:511
exprt::has_operands
bool has_operands() const
Return true if there is at least one operand.
Definition: expr.h:92
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:44
cpp_scopest::current_scope
cpp_scopet & current_scope()
Definition: cpp_scopes.h:33
struct_union_typet::componentt::get_name
const irep_idt & get_name() const
Definition: std_types.h:74
failed
static bool failed(bool error_indicator)
Definition: symtab2gb_parse_options.cpp:34
messaget::mstreamt::source_location
source_locationt source_location
Definition: message.h:244
cpp_declarator_convertert
Definition: cpp_declarator_converter.h:26
codet::make_block
class code_blockt & make_block()
If this codet is a code_blockt (i.e. it represents a block of statements), return the unmodified inpu...
Definition: std_code.cpp:23
PRECONDITION
#define PRECONDITION(CONDITION)
Definition: invariant.h:464
typet::source_location
const source_locationt & source_location() const
Definition: type.h:71
cpp_declarator_convertert::is_friend
bool is_friend
Definition: cpp_declarator_converter.h:34
symbol_exprt::get_identifier
const irep_idt & get_identifier() const
Definition: std_expr.h:111
cpp_symbol_expr
symbol_exprt cpp_symbol_expr(const symbolt &symbol)
Definition: cpp_util.cpp:14
struct_union_typet::componentt::set_pretty_name
void set_pretty_name(const irep_idt &name)
Definition: std_types.h:109
struct_union_typet::componentt::set_base_name
void set_base_name(const irep_idt &base_name)
Definition: std_types.h:89
cpp_namet::is_simple_name
bool is_simple_name() const
Definition: cpp_name.h:89
std_types.h
cpp_typecheckt::check_member_initializers
void check_member_initializers(const struct_typet::basest &bases, const struct_typet::componentst &components, const irept &initializers)
Check a constructor initialization-list.
Definition: cpp_typecheck_constructor.cpp:418
cpp_storage_spect::is_mutable
bool is_mutable() const
Definition: cpp_storage_spec.h:41
c_qualifierst::write
virtual void write(typet &src) const override
Definition: c_qualifiers.cpp:89
symbolt::symbol_expr
class symbol_exprt symbol_expr() const
Produces a symbol_exprt for a symbol.
Definition: symbol.cpp:122
code_typet::set_inlined
void set_inlined(bool value)
Definition: std_types.h:872
cpp_typecheckt::make_ptr_typecast
void make_ptr_typecast(exprt &expr, const typet &dest_type)
Definition: cpp_typecheck_compound_type.cpp:1681
symbol_tablet::insert
virtual std::pair< symbolt &, bool > insert(symbolt symbol) override
Author: Diffblue Ltd.
Definition: symbol_table.cpp:19
struct_typet::bases
const basest & bases() const
Get the collection of base classes/structs.
Definition: std_types.h:257
c_qualifierst
Definition: c_qualifiers.h:61
c_typecheck_baset::symbol_table
symbol_tablet & symbol_table
Definition: c_typecheck_base.h:67
pointer_type
pointer_typet pointer_type(const typet &subtype)
Definition: c_types.cpp:243
cpp_typecheckt::put_compound_into_scope
void put_compound_into_scope(const struct_union_typet::componentt &component)
Definition: cpp_typecheck_compound_type.cpp:784
cpp_typecheckt::deferred_typechecking
std::unordered_set< irep_idt > deferred_typechecking
Definition: cpp_typecheck.h:595
irept::swap
void swap(irept &irep)
Definition: irep.h:463
to_symbol_expr
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
Definition: std_expr.h:177
cpp_typecheckt::subtype_typecast
bool subtype_typecast(const struct_typet &from, const struct_typet &to) const
Definition: cpp_typecheck_compound_type.cpp:1667
code_typet
Base type of functions.
Definition: std_types.h:736
cpp_convert_type.h
cpp_declarationt
Definition: cpp_declaration.h:24
c_typecheck_baset::make_constant_index
virtual void make_constant_index(exprt &expr)
Definition: c_typecheck_expr.cpp:3469
irept::is_nil
bool is_nil() const
Definition: irep.h:398
irept::id
const irep_idt & id() const
Definition: irep.h:418
irept::remove
void remove(const irep_namet &name)
Definition: irep.cpp:93
cpp_storage_spect::is_auto
bool is_auto() const
Definition: cpp_storage_spec.h:39
exprt::operandst
std::vector< exprt > operandst
Definition: expr.h:55
dstringt::empty
bool empty() const
Definition: dstring.h:88
cpp_typecheckt::get_component
bool get_component(const source_locationt &source_location, const exprt &object, const irep_idt &component_name, exprt &member)
Definition: cpp_typecheck_compound_type.cpp:1471
cpp_typecheckt::function_identifier
irep_idt function_identifier(const typet &type)
for function overloading
Definition: cpp_typecheck_function.cpp:158
code_typet::parameters
const parameterst & parameters() const
Definition: std_types.h:857
cpp_declarationt::is_template
bool is_template() const
Definition: cpp_declaration.h:52
typet::add_source_location
source_locationt & add_source_location()
Definition: type.h:76
cpp_typecheckt::convert_template_declaration
void convert_template_declaration(cpp_declarationt &declaration)
Definition: cpp_typecheck_template.cpp:967
cpp_declaratort::member_initializers
irept & member_initializers()
Definition: cpp_declarator.h:71
cpp_typecheckt::typecheck_compound_type
void typecheck_compound_type(struct_union_typet &) override
Definition: cpp_typecheck_compound_type.cpp:121
forall_subtypes
#define forall_subtypes(it, type)
Definition: type.h:216
cpp_typecheck.h
cpp_storage_spect::location
source_locationt & location()
Definition: cpp_storage_spec.h:27
cpp_scopet::RECURSIVE
@ RECURSIVE
Definition: cpp_scope.h:30
cpp_typecheckt::get_bases
void get_bases(const struct_typet &type, std::set< irep_idt > &set_bases) const
Definition: cpp_typecheck_compound_type.cpp:1632
sharing_treet< irept, std::map< irep_namet, irept > >::subt
typename dt::subt subt
Definition: irep.h:182
cpp_template_args_non_tct
Definition: cpp_template_args.h:45
code_typet::parametert::set_base_name
void set_base_name(const irep_idt &name)
Definition: std_types.h:787
symbol_tablet::move
virtual bool move(symbolt &symbol, symbolt *&new_symbol) override
Move a symbol into the symbol table.
Definition: symbol_table.cpp:69
code_typet::parametert::set_this
void set_this()
Definition: std_types.h:807
cpp_storage_spect::is_register
bool is_register() const
Definition: cpp_storage_spec.h:40
source_locationt
Definition: source_location.h:20
cpp_typecheckt::full_member_initialization
void full_member_initialization(const struct_union_typet &struct_union_type, irept &initializers)
Build the full initialization list of the constructor.
Definition: cpp_typecheck_constructor.cpp:545
simplify_expr.h
member_exprt
Extract member of struct or union.
Definition: std_expr.h:3434
struct_union_typet::componentt
Definition: std_types.h:64
irept::get_string
const std::string & get_string(const irep_namet &name) const
Definition: irep.h:431
symbolt::value
exprt value
Initial value of symbol.
Definition: symbol.h:34
forall_irep
#define forall_irep(it, irep)
Definition: irep.h:62
cpp_namet::is_operator
bool is_operator() const
Definition: cpp_name.h:97
cpp_typecheckt::add_anonymous_members_to_scope
void add_anonymous_members_to_scope(const symbolt &struct_union_symbol)
Definition: cpp_typecheck_compound_type.cpp:1368
cpp_typecheckt::add_this_to_method_type
void add_this_to_method_type(const symbolt &compound_symbol, code_typet &method_type, const typet &method_qualifier)
Definition: cpp_typecheck_compound_type.cpp:1339
struct_typet
Structure type, corresponds to C style structs.
Definition: std_types.h:226
cpp_namet::source_location
const source_locationt & source_location() const
Definition: cpp_name.h:73
cpp_idt::id_classt::TYPEDEF
@ TYPEDEF
array_typet
Arrays with given size.
Definition: std_types.h:965
cpp_idt::is_static_member
bool is_static_member
Definition: cpp_id.h:48
code_returnt
codet representation of a "return from a function" statement.
Definition: std_code.h:1313
symbolt::is_extern
bool is_extern
Definition: symbol.h:66
cpp_declarationt::is_constructor
bool is_constructor() const
Definition: cpp_declaration.h:37
cpp_typecheck_resolvet::resolve_scope
cpp_scopet & resolve_scope(const cpp_namet &cpp_name, irep_idt &base_name, cpp_template_args_non_tct &template_args)
Definition: cpp_typecheck_resolve.cpp:854
namespace_baset::follow
const typet & follow(const typet &) const
Resolve type symbol to the type it points to.
Definition: namespace.cpp:51
cpp_type2name
std::string cpp_type2name(const typet &type)
Definition: cpp_type2name.cpp:97
irept::get
const irep_idt & get(const irep_namet &name) const
Definition: irep.cpp:51
symbolt::location
source_locationt location
Source code location of definition of symbol.
Definition: symbol.h:37
symbolt
Symbol table entry.
Definition: symbol.h:28
irept::set
void set(const irep_namet &name, const irep_idt &value)
Definition: irep.h:442
side_effect_expr_function_callt::arguments
exprt::operandst & arguments()
Definition: std_code.h:2171
symbolt::is_type
bool is_type
Definition: symbol.h:61
cpp_typecheckt::has_auto
static bool has_auto(const typet &type)
Definition: cpp_typecheck_compound_type.cpp:64
cpp_idt::id_class
id_classt id_class
Definition: cpp_id.h:51
irept::get_sub
subt & get_sub()
Definition: irep.h:477
to_array_type
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
Definition: std_types.h:1011
cpp_typecheckt::has_volatile
static bool has_volatile(const typet &type)
Definition: cpp_typecheck_compound_type.cpp:48
code_typet::parametert
Definition: std_types.h:753
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:155
symbolt::is_static_lifetime
bool is_static_lifetime
Definition: symbol.h:65
already_typechecked_exprt
Definition: c_typecheck_base.h:277
cpp_declaratort::value
exprt & value()
Definition: cpp_declarator.h:42
cpp_idt::prefix
std::string prefix
Definition: cpp_id.h:85
symbol_table_baset::lookup
const symbolt * lookup(const irep_idt &name) const
Find a symbol in the symbol table for read-only access.
Definition: symbol_table_base.h:95
code_typet::return_type
const typet & return_type() const
Definition: std_types.h:847
irept
There are a large number of kinds of tree structured or tree-like data in CPROVER.
Definition: irep.h:394
cpp_typecheckt::find_assignop
bool find_assignop(const symbolt &symbol) const
Definition: cpp_typecheck_constructor.cpp:815
exprt::operands
operandst & operands()
Definition: expr.h:95
symbolt::is_lvalue
bool is_lvalue
Definition: symbol.h:66
exprt::add_source_location
source_locationt & add_source_location()
Definition: expr.h:257
struct_union_typet::componentt::get_base_name
const irep_idt & get_base_name() const
Definition: std_types.h:84
typecast_exprt
Semantic type conversion.
Definition: std_expr.h:2042
is_constructor
static bool is_constructor(const irep_idt &method_name)
Definition: java_bytecode_convert_method.cpp:128
uninitialized_typet
Definition: cpp_parse_tree.h:32
codet::get_statement
const irep_idt & get_statement() const
Definition: std_code.h:71
symbolt::module
irep_idt module
Name of module the symbol belongs to.
Definition: symbol.h:43
cpp_namet::get_base_name
irep_idt get_base_name() const
Definition: cpp_name.cpp:17
cpp_typecheckt::find_cpctor
bool find_cpctor(const symbolt &symbol) const
Definition: cpp_typecheck_constructor.cpp:766
cpp_typecheckt::default_assignop
void default_assignop(const symbolt &symbol, cpp_declarationt &cpctor)
Generate declaration of the implicit default assignment operator.
Definition: cpp_typecheck_constructor.cpp:278
cpp_idt::is_template_scope
bool is_template_scope() const
Definition: cpp_id.h:73
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:872
cpp_typecheckt::default_cpctor
void default_cpctor(const symbolt &, cpp_declarationt &cpctor) const
Generate code for implicit default copy constructor.
Definition: cpp_typecheck_constructor.cpp:141
cpp_namet
Definition: cpp_name.h:17
exprt::source_location
const source_locationt & source_location() const
Definition: expr.h:252
struct_union_typet::is_incomplete
bool is_incomplete() const
A struct/union may be incomplete.
Definition: std_types.h:180
c_types.h
cpp_typecheckt::dynamic_initializations
dynamic_initializationst dynamic_initializations
Definition: cpp_typecheck.h:593
cpp_typecheckt::disable_access_control
bool disable_access_control
Definition: cpp_typecheck.h:594
symbolt::is_weak
bool is_weak
Definition: symbol.h:67
symbolt::name
irep_idt name
The unique identifier.
Definition: symbol.h:40
cpp_scopest::set_scope
cpp_scopet & set_scope(const irep_idt &identifier)
Definition: cpp_scopes.h:88
cpp_member_spect::is_friend
bool is_friend() const
Definition: cpp_member_spec.h:25
cpp_declaratort
Definition: cpp_declarator.h:20
cpp_typecheckt::move_member_initializers
void move_member_initializers(irept &initializers, const code_typet &type, exprt &value)
Definition: cpp_typecheck_compound_type.cpp:1216
to_cpp_name
cpp_namet & to_cpp_name(irept &cpp_name)
Definition: cpp_name.h:144
validation_modet::INVARIANT
@ INVARIANT
code_expressiont
codet representation of an expression statement.
Definition: std_code.h:1820
cpp_scopet::insert
cpp_idt & insert(const irep_idt &_base_name)
Definition: cpp_scope.h:52
cpp_declarator_converter.h
cpp_declaratort::merge_type
typet merge_type(const typet &declaration_type) const
Definition: cpp_declarator.cpp:28
to_constant_expr
const constant_exprt & to_constant_expr(const exprt &expr)
Cast an exprt to a constant_exprt.
Definition: std_expr.h:3968
cpp_name.h