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