CBMC
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
cpp_typecheck_constructor.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: C++ Language Type Checking
4
5Author: Daniel Kroening, kroening@cs.cmu.edu
6
7\*******************************************************************/
8
11
12#include "cpp_typecheck.h"
13
15
16#include <util/arith_tools.h>
17#include <util/c_types.h>
18#include <util/pointer_expr.h>
19#include <util/std_code.h>
20
26static void copy_parent(
27 const source_locationt &source_location,
29 const irep_idt &arg_name,
30 exprt &block)
31{
32 exprt op0(
33 "explicit-typecast",
34 pointer_type(cpp_namet(parent_base_name, source_location).as_type()));
35 op0.copy_to_operands(exprt("cpp-this"));
36 op0.add_source_location()=source_location;
37
38 exprt op1(
39 "explicit-typecast",
40 pointer_type(cpp_namet(parent_base_name, source_location).as_type()));
41 op1.type().set(ID_C_reference, true);
42 to_pointer_type(op1.type()).base_type().set(ID_C_constant, true);
43 op1.get_sub().push_back(cpp_namet(arg_name, source_location));
44 op1.add_source_location()=source_location;
45
47 code.add_source_location() = source_location;
48
49 block.operands().push_back(code);
50}
51
57static void copy_member(
58 const source_locationt &source_location,
60 const irep_idt &arg_name,
61 exprt &block)
62{
63 cpp_namet op0(member_base_name, source_location);
64
65 exprt op1(ID_member);
67 op1.copy_to_operands(cpp_namet(arg_name, source_location).as_expr());
68 op1.add_source_location()=source_location;
69
70 side_effect_expr_assignt assign(op0.as_expr(), op1, typet(), source_location);
71 assign.lhs().add_source_location() = source_location;
72
73 code_expressiont code(assign);
74 code.add_source_location() = source_location;
75
76 block.operands().push_back(code);
77}
78
85static void copy_array(
86 const source_locationt &source_location,
88 mp_integer i,
89 const irep_idt &arg_name,
90 exprt &block)
91{
92 // Build the index expression
93 const exprt constant = from_integer(i, c_index_type());
94
95 const cpp_namet array(member_base_name, source_location);
96
97 exprt member(ID_member);
98 member.add(
100 member.copy_to_operands(cpp_namet(arg_name, source_location).as_expr());
101
103 index_exprt(array.as_expr(), constant),
104 index_exprt(member, constant),
105 typet(),
106 source_location);
107
108 assign.lhs().add_source_location() = source_location;
109 assign.rhs().add_source_location() = source_location;
110
111 code_expressiont code(assign);
112 code.add_source_location() = source_location;
113
114 block.operands().push_back(code);
115}
116
119 const source_locationt &source_location,
120 const irep_idt &base_name,
121 cpp_declarationt &ctor) const
122{
123 cpp_declaratort decl;
124 decl.name() = cpp_namet(base_name, source_location);
126 decl.type().add_subtype().make_nil();
127 decl.add_source_location()=source_location;
128
129 decl.value() = code_blockt();
130 decl.add(ID_cv).make_nil();
131 decl.add(ID_throw_decl).make_nil();
132
133 ctor.type().id(ID_constructor);
135 ctor.add_to_operands(std::move(decl));
136 ctor.add_source_location()=source_location;
137}
138
141 const symbolt &symbol,
143{
144 source_locationt source_location=symbol.type.source_location();
145
146 source_location.set_function(
147 id2string(symbol.base_name)+
148 "::"+id2string(symbol.base_name)+
149 "(const "+id2string(symbol.base_name)+" &)");
150
151 // Produce default constructor first
152 default_ctor(source_location, symbol.base_name, cpctor);
153 cpp_declaratort &decl0=cpctor.declarators()[0];
154
155 std::string param_identifier("ref");
156
157 // Compound name
158 const cpp_namet cppcomp(symbol.base_name, source_location);
159
160 // Parameter name
161 const cpp_namet cpp_parameter(param_identifier, source_location);
162
163 // Parameter declarator
165 parameter_tor.add(ID_value).make_nil();
168 parameter_tor.add_source_location()=source_location;
169
170 // Parameter declaration
173 auto &sub = to_type_with_subtypes(parameter_decl.type()).subtypes();
174 sub.push_back(cppcomp.as_type());
176 sub.push_back(static_cast<const typet &>(constnd));
177 parameter_decl.add_to_operands(std::move(parameter_tor));
178 parameter_decl.add_source_location()=source_location;
179
180 // Add parameter to function type
181 decl0.add(ID_type).add(ID_parameters).get_sub().push_back(parameter_decl);
182 decl0.add_source_location()=source_location;
183
186
187 cpp_declaratort &declarator =
188 static_cast<cpp_declaratort &>(to_multi_ary_expr(cpctor).op0());
189 exprt &block=declarator.value();
190
191 // First, we need to call the parent copy constructors
192 for(const auto &b : to_struct_type(symbol.type).bases())
193 {
194 DATA_INVARIANT(b.id() == ID_base, "base class expression expected");
195
196 const symbolt &parsymb = lookup(b.type());
197
198 if(cpp_is_pod(parsymb.type))
199 copy_parent(source_location, parsymb.base_name, param_identifier, block);
200 else
201 {
202 irep_idt ctor_name=parsymb.base_name;
203
204 // Call the parent default copy constructor
205 const cpp_namet cppname(ctor_name, source_location);
206
208 mem_init.add_source_location()=source_location;
210 mem_init.copy_to_operands(cpp_parameter.as_expr());
211 initializers.move_to_sub(mem_init);
212 }
213 }
214
215 // Then, we add the member initializers
216 const struct_typet::componentst &components=
217 to_struct_type(symbol.type).components();
218
219 for(const auto &mem_c : components)
220 {
221 // Take care of virtual tables
222 if(mem_c.get_bool(ID_is_vtptr))
223 {
224 const cpp_namet cppname(mem_c.get_base_name(), source_location);
225
227 lookup(to_pointer_type(mem_c.type()).base_type().get(ID_identifier));
228
231 id2string(symbol.name));
232
233 exprt var=virtual_table_symbol_var.symbol_expr();
234 address_of_exprt address(var);
235 CHECK_RETURN(address.type() == mem_c.type());
236
238
240 ptrmember.set(ID_component_name, mem_c.get_name());
241 ptrmember.operands().push_back(exprt("cpp-this"));
242
243 code_frontend_assignt assign(ptrmember, address);
244 initializers.move_to_sub(assign);
245 continue;
246 }
247
248 if(
249 mem_c.get_bool(ID_from_base) || mem_c.get_bool(ID_is_type) ||
250 mem_c.get_bool(ID_is_static) || mem_c.type().id() == ID_code)
251 {
252 continue;
253 }
254
255 const irep_idt &mem_name = mem_c.get_base_name();
256
257 const cpp_namet cppname(mem_name, source_location);
258
261 mem_init.add_source_location()=source_location;
262
265 memberexpr.copy_to_operands(cpp_parameter.as_expr());
266 memberexpr.add_source_location()=source_location;
267
268 if(mem_c.type().id() == ID_array)
269 memberexpr.set(ID_C_array_ini, true);
270
271 mem_init.add_to_operands(std::move(memberexpr));
272 initializers.move_to_sub(mem_init);
273 }
274}
275
278 const symbolt &symbol,
280{
281 source_locationt source_location=symbol.type.source_location();
282
283 source_location.set_function(
284 id2string(symbol.base_name)
285 + "& "+
286 id2string(symbol.base_name)+
287 "::operator=( const "+id2string(symbol.base_name)+"&)");
288
289 std::string arg_name("ref");
290
292 cpctor.type().id(ID_struct_tag);
293 cpctor.type().add(ID_identifier).id(symbol.name);
294 cpctor.operands().push_back(exprt(ID_cpp_declarator));
295 cpctor.add_source_location()=source_location;
296
297 cpp_declaratort &declarator =
298 static_cast<cpp_declaratort &>(to_multi_ary_expr(cpctor).op0());
299 declarator.add_source_location()=source_location;
300
301 cpp_namet &declarator_name=declarator.name();
302 typet &declarator_type=declarator.type();
303
304 declarator_type.add_source_location()=source_location;
305
307 declarator_name.get_sub().push_back(irept(ID_operator));
308 declarator_name.get_sub().push_back(irept("="));
309
313 .subtype()
314 .add(ID_C_qualifier)
315 .make_nil();
316
317 exprt &args=static_cast<exprt&>(declarator.type().add(ID_parameters));
318 args.add_source_location()=source_location;
319
320 args.get_sub().push_back(irept(ID_cpp_declaration));
321
323 static_cast<cpp_declarationt&>(args.get_sub().back());
324
325 auto &args_decl_type_sub = to_type_with_subtypes(args_decl.type()).subtypes();
326
327 args_decl.type().id(ID_merged_type);
328 args_decl_type_sub.push_back(
329 cpp_namet(symbol.base_name, source_location).as_type());
330
332 args_decl.operands().push_back(exprt(ID_cpp_declarator));
333 args_decl.add_source_location()=source_location;
334
336 static_cast<cpp_declaratort&>(args_decl.operands().back());
337
338 args_decl_declor.name() = cpp_namet(arg_name, source_location);
339 args_decl_declor.add_source_location()=source_location;
340
342 args_decl_declor.type().set(ID_C_reference, true);
343 args_decl_declor.value().make_nil();
344}
345
348 const symbolt &symbol,
349 cpp_declaratort &declarator)
350{
351 // save source location
352 source_locationt source_location=declarator.source_location();
353 declarator.make_nil();
354
355 code_blockt block;
356
357 std::string arg_name("ref");
358
359 // First, we copy the parents
360 for(const auto &b : to_struct_type(symbol.type).bases())
361 {
362 DATA_INVARIANT(b.id() == ID_base, "base class expression expected");
363
364 const symbolt &symb = lookup(b.type());
365
366 copy_parent(source_location, symb.base_name, arg_name, block);
367 }
368
369 // Then, we copy the members
370 for(const auto &c : to_struct_type(symbol.type).components())
371 {
372 if(
373 c.get_bool(ID_from_base) || c.get_bool(ID_is_type) ||
374 c.get_bool(ID_is_static) || c.get_bool(ID_is_vtptr) ||
375 c.type().id() == ID_code)
376 {
377 continue;
378 }
379
380 const irep_idt &mem_name = c.get_base_name();
381
382 if(c.type().id() == ID_array)
383 {
384 const exprt &size_expr = to_array_type(c.type()).size();
385
386 if(size_expr.id()==ID_infinity)
387 {
388 // error().source_location=object);
389 // err << "cannot copy array of infinite size\n";
390 // throw 0;
391 continue;
392 }
393
394 const auto size = numeric_cast<mp_integer>(size_expr);
395 CHECK_RETURN(!size.has_value());
396 CHECK_RETURN(*size >= 0);
397
398 for(mp_integer i = 0; i < *size; ++i)
399 copy_array(source_location, mem_name, i, arg_name, block);
400 }
401 else
402 copy_member(source_location, mem_name, arg_name, block);
403 }
404
405 // Finally we add the return statement
406 block.add(
408
409 declarator.value() = std::move(block);
410 declarator.value().add_source_location() = source_location;
411}
412
421 const struct_typet::basest &bases,
422 const struct_typet::componentst &components,
423 const irept &initializers)
424{
426
427 for(const auto &initializer : initializers.get_sub())
428 {
429 PRECONDITION(initializer.is_not_nil());
430
431 const cpp_namet &member_name=
432 to_cpp_name(initializer.find(ID_member));
433
434 bool has_template_args=member_name.has_template_args();
435
436 if(has_template_args)
437 {
438 // it has to be a parent constructor
439 typet member_type=(typet&) initializer.find(ID_member);
441
442 // check for a direct parent
443 bool ok=false;
444 for(const auto &b : bases)
445 {
446 if(
447 to_struct_tag_type(member_type).get_identifier() ==
448 to_struct_tag_type(b.type()).get_identifier())
449 {
450 ok=true;
451 break;
452 }
453 }
454
455 if(!ok)
456 {
457 error().source_location=member_name.source_location();
458 error() << "invalid initializer '" << member_name.to_string() << "'"
459 << eom;
460 throw 0;
461 }
462 return;
463 }
464
465 irep_idt base_name=member_name.get_base_name();
466 bool ok=false;
467
468 for(const auto &c : components)
469 {
470 if(c.get_base_name() != base_name)
471 continue;
472
473 // Data member
474 if(
475 !c.get_bool(ID_from_base) && !c.get_bool(ID_is_static) &&
476 c.type().id() != ID_code)
477 {
478 ok=true;
479 break;
480 }
481
482 // Maybe it is a parent constructor?
483 if(c.get_bool(ID_is_type))
484 {
485 if(c.type().id() != ID_struct_tag)
486 continue;
487
488 const symbolt &symb =
489 lookup(to_struct_tag_type(c.type()).get_identifier());
490 if(symb.type.id()!=ID_struct)
491 break;
492
493 // check for a direct parent
494 for(const auto &b : bases)
495 {
496 if(symb.name == to_struct_tag_type(b.type()).get_identifier())
497 {
498 ok=true;
499 break;
500 }
501 }
502 continue;
503 }
504
505 // Parent constructor
506 if(
507 c.get_bool(ID_from_base) && !c.get_bool(ID_is_type) &&
508 !c.get_bool(ID_is_static) && c.type().id() == ID_code &&
509 to_code_type(c.type()).return_type().id() == ID_constructor)
510 {
511 typet member_type=(typet&) initializer.find(ID_member);
513
514 // check for a direct parent
515 for(const auto &b : bases)
516 {
517 if(
519 to_struct_tag_type(b.type()).get_identifier())
520 {
521 ok=true;
522 break;
523 }
524 }
525 break;
526 }
527 }
528
529 if(!ok)
530 {
531 error().source_location=member_name.source_location();
532 error() << "invalid initializer '" << base_name << "'" << eom;
533 throw 0;
534 }
535 }
536}
537
548{
549 const struct_union_typet::componentst &components=
550 struct_union_type.components();
551
553
555
557 {
558 // First, if we are the most-derived object, then
559 // we need to construct the virtual bases
560 std::list<irep_idt> vbases;
562
563 if(!vbases.empty())
564 {
565 code_blockt block;
566
567 while(!vbases.empty())
568 {
569 const symbolt &symb=lookup(vbases.front());
570 if(!cpp_is_pod(symb.type))
571 {
572 // default initializer
573 const cpp_namet cppname(symb.base_name);
574
577 block.move_to_sub(mem_init);
578 }
579 vbases.pop_front();
580 }
581
582 code_ifthenelset cond(
583 cpp_namet("@most_derived").as_expr(), std::move(block));
584 final_initializers.move_to_sub(cond);
585 }
586
587 // Subsequently, we need to call the non-POD parent constructors
588 for(const auto &b : to_struct_type(struct_union_type).bases())
589 {
590 DATA_INVARIANT(b.id() == ID_base, "base class expression expected");
591
592 const symbolt &ctorsymb = lookup(b.type());
593
594 if(cpp_is_pod(ctorsymb.type))
595 continue;
596
597 irep_idt ctor_name=ctorsymb.base_name;
598
599 // Check if the initialization list of the constructor
600 // explicitly calls the parent constructor.
601 bool found=false;
602
603 for(irept initializer : initializers.get_sub())
604 {
605 const cpp_namet &member_name=
606 to_cpp_name(initializer.find(ID_member));
607
608 bool has_template_args=member_name.has_template_args();
609
610 if(!has_template_args)
611 {
612 irep_idt base_name=member_name.get_base_name();
613
614 // check if the initializer is a data
615 bool is_data=false;
616
617 for(const auto &c : components)
618 {
619 if(
620 c.get_base_name() == base_name && c.type().id() != ID_code &&
621 !c.get_bool(ID_is_type))
622 {
623 is_data=true;
624 break;
625 }
626 }
627
628 if(is_data)
629 continue;
630 }
631
633 static_cast<const typet&>(initializer.find(ID_member));
634
636
637 if(member_type.id() != ID_struct_tag)
638 break;
639
640 if(
641 to_struct_tag_type(b.type()).get_identifier() ==
642 to_struct_tag_type(member_type).get_identifier())
643 {
644 final_initializers.move_to_sub(initializer);
645 found=true;
646 break;
647 }
648 }
649
650 // Call the parent default constructor
651 if(!found)
652 {
654
657 final_initializers.move_to_sub(mem_init);
658 }
659
660 if(b.get_bool(ID_virtual))
661 {
663 tmp.swap(final_initializers.get_sub().back());
664
665 code_ifthenelset cond(
666 cpp_namet("@most_derived").as_expr(), std::move(tmp));
667
668 final_initializers.get_sub().back().swap(cond);
669 }
670 }
671 }
672
673 // Then, we add the member initializers
674 for(const auto &c : components)
675 {
676 // Take care of virtual tables
677 if(c.get_bool(ID_is_vtptr))
678 {
679 const cpp_namet cppname(c.get_base_name(), c.source_location());
680
682 lookup(to_pointer_type(c.type()).base_type().get(ID_identifier));
683
687
688 exprt var=virtual_table_symbol_var.symbol_expr();
689 address_of_exprt address(var);
690 CHECK_RETURN(address.type() == c.type());
691
693
695 ptrmember.set(ID_component_name, c.get_name());
696 ptrmember.operands().push_back(exprt("cpp-this"));
697
698 code_frontend_assignt assign(ptrmember, address);
699 final_initializers.move_to_sub(assign);
700 continue;
701 }
702
703 if(
704 c.get_bool(ID_from_base) || c.type().id() == ID_code ||
705 c.get_bool(ID_is_type) || c.get_bool(ID_is_static))
706 {
707 continue;
708 }
709
710 const irep_idt &mem_name = c.get_base_name();
711
712 // Check if the initialization list of the constructor
713 // explicitly initializes the data member
714 bool found=false;
715 for(auto &initializer : initializers.get_sub())
716 {
717 if(initializer.get(ID_member)!=ID_cpp_name)
718 continue;
719 cpp_namet &member_name=(cpp_namet&) initializer.add(ID_member);
720
721 if(member_name.has_template_args())
722 continue; // base-type initializer
723
724 irep_idt base_name=member_name.get_base_name();
725
726 if(mem_name==base_name)
727 {
728 final_initializers.move_to_sub(initializer);
729 found=true;
730 break;
731 }
732 }
733
734 // If the data member is a reference, it must be explicitly
735 // initialized
736 if(
737 !found && c.type().id() == ID_pointer &&
738 c.type().get_bool(ID_C_reference))
739 {
740 error().source_location = c.source_location();
741 error() << "reference must be explicitly initialized" << eom;
742 throw 0;
743 }
744
745 // If the data member is not POD and is not explicitly initialized,
746 // then its default constructor is called.
747 if(!found && !cpp_is_pod(c.type()))
748 {
750
753 final_initializers.move_to_sub(mem_init);
754 }
755 }
756
758}
759
762bool cpp_typecheckt::find_cpctor(const symbolt &symbol) const
763{
764 for(const auto &component : to_struct_type(symbol.type).components())
765 {
766 // Skip non-ctor
767 if(component.type().id()!=ID_code ||
768 to_code_type(component.type()).return_type().id() !=ID_constructor)
769 continue;
770
771 // Skip inherited constructor
772 if(component.get_bool(ID_from_base))
773 continue;
774
776
777 const code_typet::parameterst &parameters=code_type.parameters();
778
779 // First parameter is the 'this' pointer. Therefore, copy
780 // constructors have at least two parameters
781 if(parameters.size() < 2)
782 continue;
783
784 const code_typet::parametert &parameter1=parameters[1];
785
786 const typet &parameter1_type=parameter1.type();
787
789 continue;
790
791 if(
793 symbol.name)
794 {
795 continue;
796 }
797
798 bool defargs=true;
799 for(std::size_t i=2; i<parameters.size(); i++)
800 {
801 if(parameters[i].default_value().is_nil())
802 {
803 defargs=false;
804 break;
805 }
806 }
807
808 if(defargs)
809 return true;
810 }
811
812 return false;
813}
814
815bool cpp_typecheckt::find_assignop(const symbolt &symbol) const
816{
818 const struct_typet::componentst &components=struct_type.components();
819
820 for(const auto &component : components)
821 {
822 if(component.get_base_name() != "operator=")
823 continue;
824
825 if(component.get_bool(ID_is_static))
826 continue;
827
828 if(component.get_bool(ID_from_base))
829 continue;
830
832
833 const code_typet::parameterst &args=code_type.parameters();
834
835 if(args.size()!=2)
836 continue;
837
838 const code_typet::parametert &arg1=args[1];
839
840 const typet &arg1_type=arg1.type();
841
843 continue;
844
845 if(
846 to_reference_type(arg1_type).base_type().get(ID_identifier) !=
847 symbol.name)
848 continue;
849
850 return true;
851 }
852
853 return false;
854}
constant_exprt from_integer(const mp_integer &int_value, const typet &type)
reference_typet reference_type(const typet &subtype)
Definition c_types.cpp:240
pointer_typet pointer_type(const typet &subtype)
Definition c_types.cpp:235
bitvector_typet c_index_type()
Definition c_types.cpp:16
Operator to return the address of an object.
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
static void make_already_typechecked(exprt &expr)
A codet representing sequential composition of program statements.
Definition std_code.h:130
void add(const codet &code)
Definition std_code.h:168
codet representation of an expression statement.
Definition std_code.h:1394
A codet representing an assignment in the program.
Definition std_code.h:24
codet representation of an if-then-else statement.
Definition std_code.h:460
goto_instruction_codet representation of a "return from a function" statement.
Base type of functions.
Definition std_types.h:583
std::vector< parametert > parameterst
Definition std_types.h:586
Data structure for representing an arbitrary statement in a program.
cpp_namet & name()
const exprt & as_expr() const
Definition cpp_name.h:137
const typet & as_type() const
Definition cpp_name.h:142
void default_assignop(const symbolt &symbol, cpp_declarationt &cpctor)
Generate declaration of the implicit default assignment operator.
void typecheck_type(typet &) override
void full_member_initialization(const struct_union_typet &struct_union_type, irept &initializers)
Build the full initialization list of the constructor.
bool cpp_is_pod(const typet &type) const
void default_cpctor(const symbolt &, cpp_declarationt &cpctor) const
Generate code for implicit default copy constructor.
bool find_assignop(const symbolt &symbol) const
void get_virtual_bases(const struct_typet &type, std::list< irep_idt > &vbases) const
void check_member_initializers(const struct_typet::basest &bases, const struct_typet::componentst &components, const irept &initializers)
Check a constructor initialization-list.
void default_assignop_value(const symbolt &symbol, cpp_declaratort &declarator)
Generate code for the implicit default assignment operator.
bool find_cpctor(const symbolt &symbol) const
void default_ctor(const source_locationt &source_location, const irep_idt &base_name, cpp_declarationt &ctor) const
Generate code for implicit default constructors.
Operator to dereference a pointer.
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition dstring.h:38
Base class for all expressions.
Definition expr.h:56
void copy_to_operands(const exprt &expr)
Copy the given argument to the end of exprt's operands.
Definition expr.h:163
typet & type()
Return the type of the expression.
Definition expr.h:84
operandst & operands()
Definition expr.h:94
const source_locationt & source_location() const
Definition expr.h:231
source_locationt & add_source_location()
Definition expr.h:236
Array index operator.
Definition std_expr.h:1470
There are a large number of kinds of tree structured or tree-like data in CPROVER.
Definition irep.h:364
void set(const irep_idt &name, const irep_idt &value)
Definition irep.h:412
subt & get_sub()
Definition irep.h:448
void make_nil()
Definition irep.h:446
void move_to_sub(irept &irep)
Definition irep.cpp:35
irept & add(const irep_idt &name)
Definition irep.cpp:103
source_locationt source_location
Definition message.h:239
mstreamt & error() const
Definition message.h:391
static eomt eom
Definition message.h:289
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
A side_effect_exprt that performs an assignment.
Definition std_code.h:1565
void set_function(const irep_idt &function)
Structure type, corresponds to C style structs.
Definition std_types.h:231
std::vector< baset > basest
Definition std_types.h:259
Base type for structs and unions.
Definition std_types.h:62
std::vector< componentt > componentst
Definition std_types.h:140
Symbol table entry.
Definition symbol.h:28
typet type
Type of symbol.
Definition symbol.h:31
irep_idt name
The unique identifier.
Definition symbol.h:40
irep_idt irep_idt base_name
Name of module the symbol belongs to.
Definition symbol.h:46
The type of an expression, extends irept.
Definition type.h:29
const source_locationt & source_location() const
Definition type.h:72
typet & add_subtype()
Definition type.h:53
cpp_namet & to_cpp_name(irept &cpp_name)
Definition cpp_name.h:148
C++ Language Type Checking.
static void copy_array(const source_locationt &source_location, const irep_idt &member_base_name, mp_integer i, const irep_idt &arg_name, exprt &block)
Generate code to copy the member.
static void copy_member(const source_locationt &source_location, const irep_idt &member_base_name, const irep_idt &arg_name, exprt &block)
Generate code to copy the member.
static void copy_parent(const source_locationt &source_location, const irep_idt &parent_base_name, const irep_idt &arg_name, exprt &block)
Generate code to copy the parent.
const std::string & id2string(const irep_idt &d)
Definition irep.h:44
API to expression classes for Pointers.
bool is_reference(const typet &type)
Returns true if the type is a reference.
const reference_typet & to_reference_type(const typet &type)
Cast a typet to a reference_typet.
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
BigInt mp_integer
Definition smt_terms.h:17
#define CHECK_RETURN(CONDITION)
Definition invariant.h:495
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
Definition invariant.h:534
#define PRECONDITION(CONDITION)
Definition invariant.h:463
auto component(T &struct_expr, const irep_idt &name, const namespacet &ns) -> decltype(struct_expr.op0())
Definition std_expr.cpp:97
const multi_ary_exprt & to_multi_ary_expr(const exprt &expr)
Cast an exprt to a multi_ary_exprt.
Definition std_expr.h:987
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
Definition std_types.h:788
const struct_typet & to_struct_type(const typet &type)
Cast a typet to a struct_typet.
Definition std_types.h:308
const struct_tag_typet & to_struct_tag_type(const typet &type)
Cast a typet to a struct_tag_typet.
Definition std_types.h:518
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
Definition std_types.h:888
const type_with_subtypest & to_type_with_subtypes(const typet &type)
Definition type.h:252
const type_with_subtypet & to_type_with_subtype(const typet &type)
Definition type.h:208